1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 3.1 Module
3*35238bceSAndroid Build Coastguard Worker * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2015 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Primitive bounding box tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fPrimitiveBoundingBoxTests.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "glsStateQueryUtil.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker #include <vector>
47*35238bceSAndroid Build Coastguard Worker #include <sstream>
48*35238bceSAndroid Build Coastguard Worker #include <algorithm>
49*35238bceSAndroid Build Coastguard Worker
50*35238bceSAndroid Build Coastguard Worker namespace deqp
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker namespace gles31
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace Functional
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker namespace
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker
59*35238bceSAndroid Build Coastguard Worker namespace StateQueryUtil = ::deqp::gls::StateQueryUtil;
60*35238bceSAndroid Build Coastguard Worker
61*35238bceSAndroid Build Coastguard Worker struct BoundingBox
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker tcu::Vec4 min;
64*35238bceSAndroid Build Coastguard Worker tcu::Vec4 max;
65*35238bceSAndroid Build Coastguard Worker
66*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
67*35238bceSAndroid Build Coastguard Worker * Get component by index of a 8-component vector constructed by
68*35238bceSAndroid Build Coastguard Worker * concatenating 4-component min and max vectors.
69*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
70*35238bceSAndroid Build Coastguard Worker float &getComponentAccess(int ndx);
71*35238bceSAndroid Build Coastguard Worker const float &getComponentAccess(int ndx) const;
72*35238bceSAndroid Build Coastguard Worker };
73*35238bceSAndroid Build Coastguard Worker
getComponentAccess(int ndx)74*35238bceSAndroid Build Coastguard Worker float &BoundingBox::getComponentAccess(int ndx)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker DE_ASSERT(ndx >= 0 && ndx < 8);
77*35238bceSAndroid Build Coastguard Worker if (ndx < 4)
78*35238bceSAndroid Build Coastguard Worker return min[ndx];
79*35238bceSAndroid Build Coastguard Worker else
80*35238bceSAndroid Build Coastguard Worker return max[ndx - 4];
81*35238bceSAndroid Build Coastguard Worker }
82*35238bceSAndroid Build Coastguard Worker
getComponentAccess(int ndx) const83*35238bceSAndroid Build Coastguard Worker const float &BoundingBox::getComponentAccess(int ndx) const
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker return const_cast<BoundingBox *>(this)->getComponentAccess(ndx);
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker struct ProjectedBBox
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker tcu::Vec3 min;
91*35238bceSAndroid Build Coastguard Worker tcu::Vec3 max;
92*35238bceSAndroid Build Coastguard Worker };
93*35238bceSAndroid Build Coastguard Worker
projectBoundingBox(const BoundingBox & bbox)94*35238bceSAndroid Build Coastguard Worker static ProjectedBBox projectBoundingBox(const BoundingBox &bbox)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker const float wMin = de::max(0.0f, bbox.min.w()); // clamp to w=0 as extension requires
97*35238bceSAndroid Build Coastguard Worker const float wMax = de::max(0.0f, bbox.max.w());
98*35238bceSAndroid Build Coastguard Worker ProjectedBBox retVal;
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker retVal.min = tcu::min(bbox.min.swizzle(0, 1, 2) / wMin, bbox.min.swizzle(0, 1, 2) / wMax);
101*35238bceSAndroid Build Coastguard Worker retVal.max = tcu::max(bbox.max.swizzle(0, 1, 2) / wMin, bbox.max.swizzle(0, 1, 2) / wMax);
102*35238bceSAndroid Build Coastguard Worker return retVal;
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker
getViewportBoundingBoxArea(const ProjectedBBox & bbox,const tcu::IVec2 & viewportSize,float size=0.0f)105*35238bceSAndroid Build Coastguard Worker static tcu::IVec4 getViewportBoundingBoxArea(const ProjectedBBox &bbox, const tcu::IVec2 &viewportSize,
106*35238bceSAndroid Build Coastguard Worker float size = 0.0f)
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker tcu::Vec4 vertexBox;
109*35238bceSAndroid Build Coastguard Worker tcu::IVec4 pixelBox;
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker vertexBox.x() = (bbox.min.x() * 0.5f + 0.5f) * (float)viewportSize.x();
112*35238bceSAndroid Build Coastguard Worker vertexBox.y() = (bbox.min.y() * 0.5f + 0.5f) * (float)viewportSize.y();
113*35238bceSAndroid Build Coastguard Worker vertexBox.z() = (bbox.max.x() * 0.5f + 0.5f) * (float)viewportSize.x();
114*35238bceSAndroid Build Coastguard Worker vertexBox.w() = (bbox.max.y() * 0.5f + 0.5f) * (float)viewportSize.y();
115*35238bceSAndroid Build Coastguard Worker
116*35238bceSAndroid Build Coastguard Worker pixelBox.x() = deFloorFloatToInt32(vertexBox.x() - size / 2.0f);
117*35238bceSAndroid Build Coastguard Worker pixelBox.y() = deFloorFloatToInt32(vertexBox.y() - size / 2.0f);
118*35238bceSAndroid Build Coastguard Worker pixelBox.z() = deCeilFloatToInt32(vertexBox.z() + size / 2.0f);
119*35238bceSAndroid Build Coastguard Worker pixelBox.w() = deCeilFloatToInt32(vertexBox.w() + size / 2.0f);
120*35238bceSAndroid Build Coastguard Worker return pixelBox;
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker
specializeShader(Context & context,const char * code)123*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(Context &context, const char *code)
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
126*35238bceSAndroid Build Coastguard Worker std::map<std::string, std::string> specializationMap;
127*35238bceSAndroid Build Coastguard Worker
128*35238bceSAndroid Build Coastguard Worker specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
129*35238bceSAndroid Build Coastguard Worker
130*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
131*35238bceSAndroid Build Coastguard Worker {
132*35238bceSAndroid Build Coastguard Worker specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "";
133*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_SHADER_REQUIRE"] = "";
134*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_POINT_SIZE"] = "#extension GL_EXT_geometry_point_size : require";
135*35238bceSAndroid Build Coastguard Worker specializationMap["GPU_SHADER5_REQUIRE"] = "";
136*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_SHADER_REQUIRE"] = "";
137*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "#extension GL_EXT_tessellation_point_size : require";
138*35238bceSAndroid Build Coastguard Worker specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "";
139*35238bceSAndroid Build Coastguard Worker specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBox";
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker else if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
142*35238bceSAndroid Build Coastguard Worker {
143*35238bceSAndroid Build Coastguard Worker specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "#extension GL_ARB_ES3_2_compatibility : require";
144*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_SHADER_REQUIRE"] = "";
145*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_POINT_SIZE"] = "";
146*35238bceSAndroid Build Coastguard Worker specializationMap["GPU_SHADER5_REQUIRE"] = "";
147*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_SHADER_REQUIRE"] = "";
148*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "";
149*35238bceSAndroid Build Coastguard Worker specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "";
150*35238bceSAndroid Build Coastguard Worker specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBox";
151*35238bceSAndroid Build Coastguard Worker }
152*35238bceSAndroid Build Coastguard Worker else
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker specializationMap["ARB_ES32_COMPATIBILITY_REQUIRE"] = "";
155*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_SHADER_REQUIRE"] = "#extension GL_EXT_geometry_shader : require";
156*35238bceSAndroid Build Coastguard Worker specializationMap["GEOMETRY_POINT_SIZE"] = "#extension GL_EXT_geometry_point_size : require";
157*35238bceSAndroid Build Coastguard Worker specializationMap["GPU_SHADER5_REQUIRE"] = "#extension GL_EXT_gpu_shader5 : require";
158*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_SHADER_REQUIRE"] = "#extension GL_EXT_tessellation_shader : require";
159*35238bceSAndroid Build Coastguard Worker specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] = "#extension GL_EXT_tessellation_point_size : require";
160*35238bceSAndroid Build Coastguard Worker specializationMap["PRIMITIVE_BOUNDING_BOX_REQUIRE"] = "#extension GL_EXT_primitive_bounding_box : require";
161*35238bceSAndroid Build Coastguard Worker specializationMap["PRIM_GL_BOUNDING_BOX"] = "gl_BoundingBoxEXT";
162*35238bceSAndroid Build Coastguard Worker }
163*35238bceSAndroid Build Coastguard Worker
164*35238bceSAndroid Build Coastguard Worker return tcu::StringTemplate(code).specialize(specializationMap);
165*35238bceSAndroid Build Coastguard Worker }
166*35238bceSAndroid Build Coastguard Worker
getBoundingBoxFunction(Context & context)167*35238bceSAndroid Build Coastguard Worker static decltype(glw::Functions::primitiveBoundingBox) getBoundingBoxFunction(Context &context)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker decltype(glw::Functions::primitiveBoundingBox) boundingBoxFunc;
170*35238bceSAndroid Build Coastguard Worker const glw::Functions &funcs = context.getRenderContext().getFunctions();
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker /* OpenGL ES is assumed to have it (extensions checks passed). */
173*35238bceSAndroid Build Coastguard Worker if (glu::isContextTypeES(context.getRenderContext().getType()))
174*35238bceSAndroid Build Coastguard Worker return funcs.primitiveBoundingBox;
175*35238bceSAndroid Build Coastguard Worker
176*35238bceSAndroid Build Coastguard Worker boundingBoxFunc = (decltype(boundingBoxFunc))context.getRenderContext().getProcAddress("glPrimitiveBoundingBoxARB");
177*35238bceSAndroid Build Coastguard Worker
178*35238bceSAndroid Build Coastguard Worker DE_ASSERT(boundingBoxFunc);
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Worker return boundingBoxFunc;
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker
supportsES32OrGL45(Context & context)183*35238bceSAndroid Build Coastguard Worker static bool supportsES32OrGL45(Context &context)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker return glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
186*35238bceSAndroid Build Coastguard Worker glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5));
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker
boundingBoxSupported(Context & context)189*35238bceSAndroid Build Coastguard Worker static bool boundingBoxSupported(Context &context)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker /* Require one of:
192*35238bceSAndroid Build Coastguard Worker * - OpenGL ES 3.2
193*35238bceSAndroid Build Coastguard Worker * - OpenGL 4.5 + GL_ARB_ES3_2_compatibility
194*35238bceSAndroid Build Coastguard Worker * - OpenGL ES 3.1 + GL_EXT_primitive_bounding_box
195*35238bceSAndroid Build Coastguard Worker */
196*35238bceSAndroid Build Coastguard Worker return glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
197*35238bceSAndroid Build Coastguard Worker ((glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)) &&
198*35238bceSAndroid Build Coastguard Worker context.getContextInfo().isExtensionSupported("GL_ARB_ES3_2_compatibility")) ||
199*35238bceSAndroid Build Coastguard Worker context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"));
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker
202*35238bceSAndroid Build Coastguard Worker class InitialValueCase : public TestCase
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker public:
205*35238bceSAndroid Build Coastguard Worker InitialValueCase(Context &context, const char *name, const char *desc);
206*35238bceSAndroid Build Coastguard Worker
207*35238bceSAndroid Build Coastguard Worker void init(void);
208*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
209*35238bceSAndroid Build Coastguard Worker };
210*35238bceSAndroid Build Coastguard Worker
InitialValueCase(Context & context,const char * name,const char * desc)211*35238bceSAndroid Build Coastguard Worker InitialValueCase::InitialValueCase(Context &context, const char *name, const char *desc) : TestCase(context, name, desc)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker }
214*35238bceSAndroid Build Coastguard Worker
init(void)215*35238bceSAndroid Build Coastguard Worker void InitialValueCase::init(void)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
218*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker
iterate(void)221*35238bceSAndroid Build Coastguard Worker InitialValueCase::IterateResult InitialValueCase::iterate(void)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]> state;
224*35238bceSAndroid Build Coastguard Worker glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker gl.enableLogging(true);
227*35238bceSAndroid Build Coastguard Worker
228*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
229*35238bceSAndroid Build Coastguard Worker << "Querying GL_PRIMITIVE_BOUNDING_BOX_EXT, expecting (-1, -1, -1, 1) (1, 1, 1, 1)"
230*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
231*35238bceSAndroid Build Coastguard Worker
232*35238bceSAndroid Build Coastguard Worker gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
233*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
234*35238bceSAndroid Build Coastguard Worker
235*35238bceSAndroid Build Coastguard Worker if (!state.verifyValidity(m_testCtx))
236*35238bceSAndroid Build Coastguard Worker return STOP;
237*35238bceSAndroid Build Coastguard Worker
238*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Got " << tcu::formatArray(&state[0], &state[8])
239*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
240*35238bceSAndroid Build Coastguard Worker
241*35238bceSAndroid Build Coastguard Worker if ((state[0] != -1.0f) || (state[1] != -1.0f) || (state[2] != -1.0f) || (state[3] != 1.0f) || (state[4] != 1.0f) ||
242*35238bceSAndroid Build Coastguard Worker (state[5] != 1.0f) || (state[6] != 1.0f) || (state[7] != 1.0f))
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected value" << tcu::TestLog::EndMessage;
245*35238bceSAndroid Build Coastguard Worker
246*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid initial value");
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker else
249*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker return STOP;
252*35238bceSAndroid Build Coastguard Worker }
253*35238bceSAndroid Build Coastguard Worker
254*35238bceSAndroid Build Coastguard Worker class QueryCase : public TestCase
255*35238bceSAndroid Build Coastguard Worker {
256*35238bceSAndroid Build Coastguard Worker public:
257*35238bceSAndroid Build Coastguard Worker enum QueryMethod
258*35238bceSAndroid Build Coastguard Worker {
259*35238bceSAndroid Build Coastguard Worker QUERY_FLOAT = 0,
260*35238bceSAndroid Build Coastguard Worker QUERY_BOOLEAN,
261*35238bceSAndroid Build Coastguard Worker QUERY_INT,
262*35238bceSAndroid Build Coastguard Worker QUERY_INT64,
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker QUERY_LAST
265*35238bceSAndroid Build Coastguard Worker };
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker QueryCase(Context &context, const char *name, const char *desc, QueryMethod method);
268*35238bceSAndroid Build Coastguard Worker
269*35238bceSAndroid Build Coastguard Worker private:
270*35238bceSAndroid Build Coastguard Worker void init(void);
271*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
272*35238bceSAndroid Build Coastguard Worker
273*35238bceSAndroid Build Coastguard Worker bool verifyState(glu::CallLogWrapper &gl, const BoundingBox &bbox) const;
274*35238bceSAndroid Build Coastguard Worker
275*35238bceSAndroid Build Coastguard Worker const QueryMethod m_method;
276*35238bceSAndroid Build Coastguard Worker };
277*35238bceSAndroid Build Coastguard Worker
QueryCase(Context & context,const char * name,const char * desc,QueryMethod method)278*35238bceSAndroid Build Coastguard Worker QueryCase::QueryCase(Context &context, const char *name, const char *desc, QueryMethod method)
279*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
280*35238bceSAndroid Build Coastguard Worker , m_method(method)
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker DE_ASSERT(method < QUERY_LAST);
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker
init(void)285*35238bceSAndroid Build Coastguard Worker void QueryCase::init(void)
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
288*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
289*35238bceSAndroid Build Coastguard Worker }
290*35238bceSAndroid Build Coastguard Worker
iterate(void)291*35238bceSAndroid Build Coastguard Worker QueryCase::IterateResult QueryCase::iterate(void)
292*35238bceSAndroid Build Coastguard Worker {
293*35238bceSAndroid Build Coastguard Worker static const BoundingBox fixedCases[] = {
294*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)},
295*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(-0.0f, -0.0f, -0.0f, -0.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, -0.0f)},
296*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, -1.0f)},
297*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(2.0f, 2.0f, 2.0f, 2.0f), tcu::Vec4(1.5f, 1.5f, 1.5f, 1.0f)},
298*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f)},
299*35238bceSAndroid Build Coastguard Worker {tcu::Vec4(1.0f, 1.0f, 1.0f, 0.3f), tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.2f)},
300*35238bceSAndroid Build Coastguard Worker };
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker const int numRandomCases = 9;
303*35238bceSAndroid Build Coastguard Worker glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
304*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xDE3210);
305*35238bceSAndroid Build Coastguard Worker std::vector<BoundingBox> cases;
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker cases.insert(cases.begin(), DE_ARRAY_BEGIN(fixedCases), DE_ARRAY_END(fixedCases));
308*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numRandomCases; ++ndx)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker BoundingBox boundingBox;
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker // parameter evaluation order is not guaranteed, cannot just do "max = (rand(), rand(), ...)
313*35238bceSAndroid Build Coastguard Worker for (int coordNdx = 0; coordNdx < 8; ++coordNdx)
314*35238bceSAndroid Build Coastguard Worker boundingBox.getComponentAccess(coordNdx) = rnd.getFloat(-4.0f, 4.0f);
315*35238bceSAndroid Build Coastguard Worker
316*35238bceSAndroid Build Coastguard Worker cases.push_back(boundingBox);
317*35238bceSAndroid Build Coastguard Worker }
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker gl.enableLogging(true);
320*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
321*35238bceSAndroid Build Coastguard Worker
322*35238bceSAndroid Build Coastguard Worker auto boundingBoxFunc = getBoundingBoxFunction(m_context);
323*35238bceSAndroid Build Coastguard Worker
324*35238bceSAndroid Build Coastguard Worker for (int caseNdx = 0; caseNdx < (int)cases.size(); ++caseNdx)
325*35238bceSAndroid Build Coastguard Worker {
326*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(caseNdx + 1));
327*35238bceSAndroid Build Coastguard Worker const BoundingBox &boundingBox = cases[caseNdx];
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker /* On desktop GL, we cannot use call wrapper here but must use resolved extension function. */
330*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker boundingBoxFunc(boundingBox.min.x(), boundingBox.min.y(), boundingBox.min.z(), boundingBox.min.w(),
333*35238bceSAndroid Build Coastguard Worker boundingBox.max.x(), boundingBox.max.y(), boundingBox.max.z(), boundingBox.max.w());
334*35238bceSAndroid Build Coastguard Worker }
335*35238bceSAndroid Build Coastguard Worker else
336*35238bceSAndroid Build Coastguard Worker {
337*35238bceSAndroid Build Coastguard Worker gl.glPrimitiveBoundingBox(boundingBox.min.x(), boundingBox.min.y(), boundingBox.min.z(),
338*35238bceSAndroid Build Coastguard Worker boundingBox.min.w(), boundingBox.max.x(), boundingBox.max.y(),
339*35238bceSAndroid Build Coastguard Worker boundingBox.max.z(), boundingBox.max.w());
340*35238bceSAndroid Build Coastguard Worker }
341*35238bceSAndroid Build Coastguard Worker
342*35238bceSAndroid Build Coastguard Worker if (!verifyState(gl, boundingBox))
343*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected query result");
344*35238bceSAndroid Build Coastguard Worker }
345*35238bceSAndroid Build Coastguard Worker
346*35238bceSAndroid Build Coastguard Worker return STOP;
347*35238bceSAndroid Build Coastguard Worker }
348*35238bceSAndroid Build Coastguard Worker
verifyState(glu::CallLogWrapper & gl,const BoundingBox & bbox) const349*35238bceSAndroid Build Coastguard Worker bool QueryCase::verifyState(glu::CallLogWrapper &gl, const BoundingBox &bbox) const
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker switch (m_method)
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker case QUERY_FLOAT:
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLfloat[8]> state;
356*35238bceSAndroid Build Coastguard Worker bool error = false;
357*35238bceSAndroid Build Coastguard Worker
358*35238bceSAndroid Build Coastguard Worker gl.glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
359*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
360*35238bceSAndroid Build Coastguard Worker
361*35238bceSAndroid Build Coastguard Worker if (!state.verifyValidity(m_testCtx))
362*35238bceSAndroid Build Coastguard Worker return false;
363*35238bceSAndroid Build Coastguard Worker
364*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "glGetFloatv returned " << tcu::formatArray(&state[0], &state[8])
365*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
366*35238bceSAndroid Build Coastguard Worker
367*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
368*35238bceSAndroid Build Coastguard Worker if (state[ndx] != bbox.getComponentAccess(ndx))
369*35238bceSAndroid Build Coastguard Worker error = true;
370*35238bceSAndroid Build Coastguard Worker
371*35238bceSAndroid Build Coastguard Worker if (error)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected value\n"
374*35238bceSAndroid Build Coastguard Worker << "Expected [" << bbox.min.x() << ", " << bbox.min.y() << ", " << bbox.min.z() << ", "
375*35238bceSAndroid Build Coastguard Worker << bbox.min.w() << ", " << bbox.max.x() << ", " << bbox.max.y() << ", " << bbox.max.z()
376*35238bceSAndroid Build Coastguard Worker << ", " << bbox.max.w() << "]" << tcu::TestLog::EndMessage;
377*35238bceSAndroid Build Coastguard Worker return false;
378*35238bceSAndroid Build Coastguard Worker }
379*35238bceSAndroid Build Coastguard Worker return true;
380*35238bceSAndroid Build Coastguard Worker }
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker case QUERY_INT:
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[8]> state;
385*35238bceSAndroid Build Coastguard Worker bool error = false;
386*35238bceSAndroid Build Coastguard Worker
387*35238bceSAndroid Build Coastguard Worker gl.glGetIntegerv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
388*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
389*35238bceSAndroid Build Coastguard Worker
390*35238bceSAndroid Build Coastguard Worker if (!state.verifyValidity(m_testCtx))
391*35238bceSAndroid Build Coastguard Worker return false;
392*35238bceSAndroid Build Coastguard Worker
393*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv returned "
394*35238bceSAndroid Build Coastguard Worker << tcu::formatArray(&state[0], &state[8]) << tcu::TestLog::EndMessage;
395*35238bceSAndroid Build Coastguard Worker
396*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
397*35238bceSAndroid Build Coastguard Worker if (state[ndx] !=
398*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx)) &&
399*35238bceSAndroid Build Coastguard Worker state[ndx] !=
400*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx)))
401*35238bceSAndroid Build Coastguard Worker error = true;
402*35238bceSAndroid Build Coastguard Worker
403*35238bceSAndroid Build Coastguard Worker if (error)
404*35238bceSAndroid Build Coastguard Worker {
405*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder builder(&m_testCtx.getLog());
406*35238bceSAndroid Build Coastguard Worker
407*35238bceSAndroid Build Coastguard Worker builder << "Error, unexpected value\n"
408*35238bceSAndroid Build Coastguard Worker << "Expected [";
409*35238bceSAndroid Build Coastguard Worker
410*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
411*35238bceSAndroid Build Coastguard Worker {
412*35238bceSAndroid Build Coastguard Worker const glw::GLint roundDown =
413*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint>(bbox.getComponentAccess(ndx));
414*35238bceSAndroid Build Coastguard Worker const glw::GLint roundUp =
415*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint>(bbox.getComponentAccess(ndx));
416*35238bceSAndroid Build Coastguard Worker
417*35238bceSAndroid Build Coastguard Worker if (ndx != 0)
418*35238bceSAndroid Build Coastguard Worker builder << ", ";
419*35238bceSAndroid Build Coastguard Worker
420*35238bceSAndroid Build Coastguard Worker if (roundDown == roundUp)
421*35238bceSAndroid Build Coastguard Worker builder << roundDown;
422*35238bceSAndroid Build Coastguard Worker else
423*35238bceSAndroid Build Coastguard Worker builder << "{" << roundDown << ", " << roundUp << "}";
424*35238bceSAndroid Build Coastguard Worker }
425*35238bceSAndroid Build Coastguard Worker
426*35238bceSAndroid Build Coastguard Worker builder << "]" << tcu::TestLog::EndMessage;
427*35238bceSAndroid Build Coastguard Worker return false;
428*35238bceSAndroid Build Coastguard Worker }
429*35238bceSAndroid Build Coastguard Worker return true;
430*35238bceSAndroid Build Coastguard Worker }
431*35238bceSAndroid Build Coastguard Worker
432*35238bceSAndroid Build Coastguard Worker case QUERY_INT64:
433*35238bceSAndroid Build Coastguard Worker {
434*35238bceSAndroid Build Coastguard Worker StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint64[8]> state;
435*35238bceSAndroid Build Coastguard Worker bool error = false;
436*35238bceSAndroid Build Coastguard Worker
437*35238bceSAndroid Build Coastguard Worker gl.glGetInteger64v(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
438*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker if (!state.verifyValidity(m_testCtx))
441*35238bceSAndroid Build Coastguard Worker return false;
442*35238bceSAndroid Build Coastguard Worker
443*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "glGetInteger64v returned "
444*35238bceSAndroid Build Coastguard Worker << tcu::formatArray(&state[0], &state[8]) << tcu::TestLog::EndMessage;
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
447*35238bceSAndroid Build Coastguard Worker if (state[ndx] !=
448*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx)) &&
449*35238bceSAndroid Build Coastguard Worker state[ndx] !=
450*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx)))
451*35238bceSAndroid Build Coastguard Worker error = true;
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker if (error)
454*35238bceSAndroid Build Coastguard Worker {
455*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder builder(&m_testCtx.getLog());
456*35238bceSAndroid Build Coastguard Worker
457*35238bceSAndroid Build Coastguard Worker builder << "Error, unexpected value\n"
458*35238bceSAndroid Build Coastguard Worker << "Expected [";
459*35238bceSAndroid Build Coastguard Worker
460*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
461*35238bceSAndroid Build Coastguard Worker {
462*35238bceSAndroid Build Coastguard Worker const glw::GLint64 roundDown =
463*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(bbox.getComponentAccess(ndx));
464*35238bceSAndroid Build Coastguard Worker const glw::GLint64 roundUp =
465*35238bceSAndroid Build Coastguard Worker StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(bbox.getComponentAccess(ndx));
466*35238bceSAndroid Build Coastguard Worker
467*35238bceSAndroid Build Coastguard Worker if (ndx != 0)
468*35238bceSAndroid Build Coastguard Worker builder << ", ";
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker if (roundDown == roundUp)
471*35238bceSAndroid Build Coastguard Worker builder << roundDown;
472*35238bceSAndroid Build Coastguard Worker else
473*35238bceSAndroid Build Coastguard Worker builder << "{" << roundDown << ", " << roundUp << "}";
474*35238bceSAndroid Build Coastguard Worker }
475*35238bceSAndroid Build Coastguard Worker
476*35238bceSAndroid Build Coastguard Worker builder << "]" << tcu::TestLog::EndMessage;
477*35238bceSAndroid Build Coastguard Worker return false;
478*35238bceSAndroid Build Coastguard Worker }
479*35238bceSAndroid Build Coastguard Worker return true;
480*35238bceSAndroid Build Coastguard Worker }
481*35238bceSAndroid Build Coastguard Worker
482*35238bceSAndroid Build Coastguard Worker case QUERY_BOOLEAN:
483*35238bceSAndroid Build Coastguard Worker {
484*35238bceSAndroid Build Coastguard Worker StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean[8]> state;
485*35238bceSAndroid Build Coastguard Worker bool error = false;
486*35238bceSAndroid Build Coastguard Worker
487*35238bceSAndroid Build Coastguard Worker gl.glGetBooleanv(GL_PRIMITIVE_BOUNDING_BOX_EXT, state);
488*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "query");
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker if (!state.verifyValidity(m_testCtx))
491*35238bceSAndroid Build Coastguard Worker return false;
492*35238bceSAndroid Build Coastguard Worker
493*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "glGetBooleanv returned [" << glu::getBooleanStr(state[0])
494*35238bceSAndroid Build Coastguard Worker << ", " << glu::getBooleanStr(state[1]) << ", " << glu::getBooleanStr(state[2]) << ", "
495*35238bceSAndroid Build Coastguard Worker << glu::getBooleanStr(state[3]) << ", " << glu::getBooleanStr(state[4]) << ", "
496*35238bceSAndroid Build Coastguard Worker << glu::getBooleanStr(state[5]) << ", " << glu::getBooleanStr(state[6]) << ", "
497*35238bceSAndroid Build Coastguard Worker << glu::getBooleanStr(state[7]) << "]\n"
498*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
499*35238bceSAndroid Build Coastguard Worker
500*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
501*35238bceSAndroid Build Coastguard Worker if (state[ndx] != ((bbox.getComponentAccess(ndx) != 0.0f) ? (GL_TRUE) : (GL_FALSE)))
502*35238bceSAndroid Build Coastguard Worker error = true;
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker if (error)
505*35238bceSAndroid Build Coastguard Worker {
506*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder builder(&m_testCtx.getLog());
507*35238bceSAndroid Build Coastguard Worker
508*35238bceSAndroid Build Coastguard Worker builder << "Error, unexpected value\n"
509*35238bceSAndroid Build Coastguard Worker << "Expected [";
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 8; ++ndx)
512*35238bceSAndroid Build Coastguard Worker {
513*35238bceSAndroid Build Coastguard Worker if (ndx != 0)
514*35238bceSAndroid Build Coastguard Worker builder << ", ";
515*35238bceSAndroid Build Coastguard Worker
516*35238bceSAndroid Build Coastguard Worker builder << ((bbox.getComponentAccess(ndx) != 0.0f) ? ("GL_TRUE") : ("GL_FALSE"));
517*35238bceSAndroid Build Coastguard Worker }
518*35238bceSAndroid Build Coastguard Worker
519*35238bceSAndroid Build Coastguard Worker builder << "]" << tcu::TestLog::EndMessage;
520*35238bceSAndroid Build Coastguard Worker return false;
521*35238bceSAndroid Build Coastguard Worker }
522*35238bceSAndroid Build Coastguard Worker return true;
523*35238bceSAndroid Build Coastguard Worker }
524*35238bceSAndroid Build Coastguard Worker
525*35238bceSAndroid Build Coastguard Worker default:
526*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
527*35238bceSAndroid Build Coastguard Worker return true;
528*35238bceSAndroid Build Coastguard Worker }
529*35238bceSAndroid Build Coastguard Worker }
530*35238bceSAndroid Build Coastguard Worker
531*35238bceSAndroid Build Coastguard Worker class BBoxRenderCase : public TestCase
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker public:
534*35238bceSAndroid Build Coastguard Worker enum
535*35238bceSAndroid Build Coastguard Worker {
536*35238bceSAndroid Build Coastguard Worker FLAG_RENDERTARGET_DEFAULT = 1u << 0, //!< render to default renderbuffer
537*35238bceSAndroid Build Coastguard Worker FLAG_RENDERTARGET_FBO = 1u << 1, //!< render to framebuffer object
538*35238bceSAndroid Build Coastguard Worker
539*35238bceSAndroid Build Coastguard Worker FLAG_BBOXSIZE_EQUAL = 1u << 2, //!< set tight primitive bounding box
540*35238bceSAndroid Build Coastguard Worker FLAG_BBOXSIZE_LARGER = 1u << 3, //!< set padded primitive bounding box
541*35238bceSAndroid Build Coastguard Worker FLAG_BBOXSIZE_SMALLER = 1u << 4, //!< set too small primitive bounding box
542*35238bceSAndroid Build Coastguard Worker
543*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION = 1u << 5, //!< use tessellation shader
544*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY = 1u << 6, //!< use geometry shader
545*35238bceSAndroid Build Coastguard Worker
546*35238bceSAndroid Build Coastguard Worker FLAG_SET_BBOX_STATE = 1u << 7, //!< set primitive bounding box using global state
547*35238bceSAndroid Build Coastguard Worker FLAG_SET_BBOX_OUTPUT = 1u << 8, //!< set primitive bounding box using tessellation output
548*35238bceSAndroid Build Coastguard Worker FLAG_PER_PRIMITIVE_BBOX = 1u << 9, //!< set primitive bounding per primitive
549*35238bceSAndroid Build Coastguard Worker
550*35238bceSAndroid Build Coastguard Worker FLAGBIT_USER_BIT = 10u //!< bits N and and up are reserved for subclasses
551*35238bceSAndroid Build Coastguard Worker };
552*35238bceSAndroid Build Coastguard Worker
553*35238bceSAndroid Build Coastguard Worker BBoxRenderCase(Context &context, const char *name, const char *description, int numIterations, uint32_t flags);
554*35238bceSAndroid Build Coastguard Worker ~BBoxRenderCase(void);
555*35238bceSAndroid Build Coastguard Worker
556*35238bceSAndroid Build Coastguard Worker protected:
557*35238bceSAndroid Build Coastguard Worker enum RenderTarget
558*35238bceSAndroid Build Coastguard Worker {
559*35238bceSAndroid Build Coastguard Worker RENDERTARGET_DEFAULT,
560*35238bceSAndroid Build Coastguard Worker RENDERTARGET_FBO,
561*35238bceSAndroid Build Coastguard Worker };
562*35238bceSAndroid Build Coastguard Worker enum BBoxSize
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker BBOXSIZE_EQUAL,
565*35238bceSAndroid Build Coastguard Worker BBOXSIZE_LARGER,
566*35238bceSAndroid Build Coastguard Worker BBOXSIZE_SMALLER,
567*35238bceSAndroid Build Coastguard Worker };
568*35238bceSAndroid Build Coastguard Worker
569*35238bceSAndroid Build Coastguard Worker enum
570*35238bceSAndroid Build Coastguard Worker {
571*35238bceSAndroid Build Coastguard Worker RENDER_TARGET_MIN_SIZE = 256,
572*35238bceSAndroid Build Coastguard Worker FBO_SIZE = 512,
573*35238bceSAndroid Build Coastguard Worker MIN_VIEWPORT_SIZE = 256,
574*35238bceSAndroid Build Coastguard Worker MAX_VIEWPORT_SIZE = 512,
575*35238bceSAndroid Build Coastguard Worker };
576*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(MIN_VIEWPORT_SIZE <= RENDER_TARGET_MIN_SIZE);
577*35238bceSAndroid Build Coastguard Worker
578*35238bceSAndroid Build Coastguard Worker enum
579*35238bceSAndroid Build Coastguard Worker {
580*35238bceSAndroid Build Coastguard Worker VA_POS_VEC_NDX = 0,
581*35238bceSAndroid Build Coastguard Worker VA_COL_VEC_NDX = 1,
582*35238bceSAndroid Build Coastguard Worker VA_NUM_ATTRIB_VECS = 2,
583*35238bceSAndroid Build Coastguard Worker };
584*35238bceSAndroid Build Coastguard Worker
585*35238bceSAndroid Build Coastguard Worker enum AABBRoundDirection
586*35238bceSAndroid Build Coastguard Worker {
587*35238bceSAndroid Build Coastguard Worker ROUND_INWARDS = 0,
588*35238bceSAndroid Build Coastguard Worker ROUND_OUTWARDS
589*35238bceSAndroid Build Coastguard Worker };
590*35238bceSAndroid Build Coastguard Worker
591*35238bceSAndroid Build Coastguard Worker struct IterationConfig
592*35238bceSAndroid Build Coastguard Worker {
593*35238bceSAndroid Build Coastguard Worker tcu::IVec2 viewportPos;
594*35238bceSAndroid Build Coastguard Worker tcu::IVec2 viewportSize;
595*35238bceSAndroid Build Coastguard Worker tcu::Vec2 patternPos; //!< in NDC
596*35238bceSAndroid Build Coastguard Worker tcu::Vec2 patternSize; //!< in NDC
597*35238bceSAndroid Build Coastguard Worker BoundingBox bbox;
598*35238bceSAndroid Build Coastguard Worker };
599*35238bceSAndroid Build Coastguard Worker
600*35238bceSAndroid Build Coastguard Worker virtual void init(void);
601*35238bceSAndroid Build Coastguard Worker virtual void deinit(void);
602*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
603*35238bceSAndroid Build Coastguard Worker
604*35238bceSAndroid Build Coastguard Worker virtual std::string genVertexSource(void) const = 0;
605*35238bceSAndroid Build Coastguard Worker virtual std::string genFragmentSource(void) const = 0;
606*35238bceSAndroid Build Coastguard Worker virtual std::string genTessellationControlSource(void) const = 0;
607*35238bceSAndroid Build Coastguard Worker virtual std::string genTessellationEvaluationSource(void) const = 0;
608*35238bceSAndroid Build Coastguard Worker virtual std::string genGeometrySource(void) const = 0;
609*35238bceSAndroid Build Coastguard Worker
610*35238bceSAndroid Build Coastguard Worker virtual IterationConfig generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const = 0;
611*35238bceSAndroid Build Coastguard Worker virtual void getAttributeData(std::vector<tcu::Vec4> &data) const = 0;
612*35238bceSAndroid Build Coastguard Worker virtual void renderTestPattern(const IterationConfig &config) = 0;
613*35238bceSAndroid Build Coastguard Worker virtual void verifyRenderResult(const IterationConfig &config) = 0;
614*35238bceSAndroid Build Coastguard Worker
615*35238bceSAndroid Build Coastguard Worker IterationConfig generateRandomConfig(int seed, const tcu::IVec2 &renderTargetSize) const;
616*35238bceSAndroid Build Coastguard Worker tcu::IVec4 getViewportPatternArea(const tcu::Vec2 &patternPos, const tcu::Vec2 &patternSize,
617*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &viewportSize, AABBRoundDirection roundDir) const;
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker void setupRender(const IterationConfig &config);
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker enum ShaderFunction
622*35238bceSAndroid Build Coastguard Worker {
623*35238bceSAndroid Build Coastguard Worker SHADER_FUNC_MIRROR_X,
624*35238bceSAndroid Build Coastguard Worker SHADER_FUNC_MIRROR_Y,
625*35238bceSAndroid Build Coastguard Worker SHADER_FUNC_INSIDE_BBOX,
626*35238bceSAndroid Build Coastguard Worker };
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker const char *genShaderFunction(ShaderFunction func) const;
629*35238bceSAndroid Build Coastguard Worker
630*35238bceSAndroid Build Coastguard Worker const RenderTarget m_renderTarget;
631*35238bceSAndroid Build Coastguard Worker const BBoxSize m_bboxSize;
632*35238bceSAndroid Build Coastguard Worker const bool m_hasTessellationStage;
633*35238bceSAndroid Build Coastguard Worker const bool m_hasGeometryStage;
634*35238bceSAndroid Build Coastguard Worker const bool m_useGlobalState;
635*35238bceSAndroid Build Coastguard Worker const bool m_calcPerPrimitiveBBox;
636*35238bceSAndroid Build Coastguard Worker const int m_numIterations;
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_program;
639*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Buffer> m_vbo;
640*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Framebuffer> m_fbo;
641*35238bceSAndroid Build Coastguard Worker glw::GLuint m_vao;
642*35238bceSAndroid Build Coastguard Worker
643*35238bceSAndroid Build Coastguard Worker decltype(glw::Functions::primitiveBoundingBox) m_boundingBoxFunc;
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker private:
646*35238bceSAndroid Build Coastguard Worker std::vector<IterationConfig> m_iterationConfigs;
647*35238bceSAndroid Build Coastguard Worker int m_iteration;
648*35238bceSAndroid Build Coastguard Worker };
649*35238bceSAndroid Build Coastguard Worker
BBoxRenderCase(Context & context,const char * name,const char * description,int numIterations,uint32_t flags)650*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::BBoxRenderCase(Context &context, const char *name, const char *description, int numIterations,
651*35238bceSAndroid Build Coastguard Worker uint32_t flags)
652*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
653*35238bceSAndroid Build Coastguard Worker , m_renderTarget((flags & FLAG_RENDERTARGET_DEFAULT) ? (RENDERTARGET_DEFAULT) : (RENDERTARGET_FBO))
654*35238bceSAndroid Build Coastguard Worker , m_bboxSize((flags & FLAG_BBOXSIZE_EQUAL) ? (BBOXSIZE_EQUAL) :
655*35238bceSAndroid Build Coastguard Worker (flags & FLAG_BBOXSIZE_SMALLER) ? (BBOXSIZE_SMALLER) :
656*35238bceSAndroid Build Coastguard Worker (BBOXSIZE_LARGER))
657*35238bceSAndroid Build Coastguard Worker , m_hasTessellationStage((flags & FLAG_TESSELLATION) != 0)
658*35238bceSAndroid Build Coastguard Worker , m_hasGeometryStage((flags & FLAG_GEOMETRY) != 0)
659*35238bceSAndroid Build Coastguard Worker , m_useGlobalState((flags & FLAG_SET_BBOX_STATE) != 0)
660*35238bceSAndroid Build Coastguard Worker , m_calcPerPrimitiveBBox((flags & FLAG_PER_PRIMITIVE_BBOX) != 0)
661*35238bceSAndroid Build Coastguard Worker , m_numIterations(numIterations)
662*35238bceSAndroid Build Coastguard Worker , m_vao(0)
663*35238bceSAndroid Build Coastguard Worker , m_boundingBoxFunc(NULL)
664*35238bceSAndroid Build Coastguard Worker , m_iteration(0)
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker // validate flags
667*35238bceSAndroid Build Coastguard Worker DE_ASSERT(
668*35238bceSAndroid Build Coastguard Worker (((m_renderTarget == RENDERTARGET_DEFAULT) ? (FLAG_RENDERTARGET_DEFAULT) : (0)) |
669*35238bceSAndroid Build Coastguard Worker ((m_renderTarget == RENDERTARGET_FBO) ? (FLAG_RENDERTARGET_FBO) : (0)) |
670*35238bceSAndroid Build Coastguard Worker ((m_bboxSize == BBOXSIZE_EQUAL) ? (FLAG_BBOXSIZE_EQUAL) : (0)) |
671*35238bceSAndroid Build Coastguard Worker ((m_bboxSize == BBOXSIZE_LARGER) ? (FLAG_BBOXSIZE_LARGER) : (0)) |
672*35238bceSAndroid Build Coastguard Worker ((m_bboxSize == BBOXSIZE_SMALLER) ? (FLAG_BBOXSIZE_SMALLER) : (0)) |
673*35238bceSAndroid Build Coastguard Worker ((m_hasTessellationStage) ? (FLAG_TESSELLATION) : (0)) | ((m_hasGeometryStage) ? (FLAG_GEOMETRY) : (0)) |
674*35238bceSAndroid Build Coastguard Worker ((m_useGlobalState) ? (FLAG_SET_BBOX_STATE) : (0)) | ((!m_useGlobalState) ? (FLAG_SET_BBOX_OUTPUT) : (0)) |
675*35238bceSAndroid Build Coastguard Worker ((m_calcPerPrimitiveBBox) ? (FLAG_PER_PRIMITIVE_BBOX) : (0))) == (flags & ((1u << FLAGBIT_USER_BIT) - 1)));
676*35238bceSAndroid Build Coastguard Worker
677*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState || m_hasTessellationStage); // using non-global state requires tessellation
678*35238bceSAndroid Build Coastguard Worker
679*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
680*35238bceSAndroid Build Coastguard Worker {
681*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_useGlobalState); // per-primitive test requires per-primitive (non-global) state
682*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_bboxSize == BBOXSIZE_EQUAL); // smaller is hard to verify, larger not interesting
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker }
685*35238bceSAndroid Build Coastguard Worker
~BBoxRenderCase(void)686*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::~BBoxRenderCase(void)
687*35238bceSAndroid Build Coastguard Worker {
688*35238bceSAndroid Build Coastguard Worker deinit();
689*35238bceSAndroid Build Coastguard Worker }
690*35238bceSAndroid Build Coastguard Worker
init(void)691*35238bceSAndroid Build Coastguard Worker void BBoxRenderCase::init(void)
692*35238bceSAndroid Build Coastguard Worker {
693*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
694*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 renderTargetSize =
695*35238bceSAndroid Build Coastguard Worker (m_renderTarget == RENDERTARGET_DEFAULT) ?
696*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
697*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(FBO_SIZE, FBO_SIZE));
698*35238bceSAndroid Build Coastguard Worker const bool hasES32OrGL45 = supportsES32OrGL45(m_context);
699*35238bceSAndroid Build Coastguard Worker
700*35238bceSAndroid Build Coastguard Worker // requirements
701*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
702*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
703*35238bceSAndroid Build Coastguard Worker if (!hasES32OrGL45 && m_hasTessellationStage &&
704*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
705*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
706*35238bceSAndroid Build Coastguard Worker if (!hasES32OrGL45 && m_hasGeometryStage &&
707*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
708*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
709*35238bceSAndroid Build Coastguard Worker if (m_renderTarget == RENDERTARGET_DEFAULT &&
710*35238bceSAndroid Build Coastguard Worker (renderTargetSize.x() < RENDER_TARGET_MIN_SIZE || renderTargetSize.y() < RENDER_TARGET_MIN_SIZE))
711*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError(std::string() + "Test requires " + de::toString<int>(RENDER_TARGET_MIN_SIZE) +
712*35238bceSAndroid Build Coastguard Worker "x" + de::toString<int>(RENDER_TARGET_MIN_SIZE) + " default framebuffer");
713*35238bceSAndroid Build Coastguard Worker
714*35238bceSAndroid Build Coastguard Worker // log case specifics
715*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting primitive bounding box "
716*35238bceSAndroid Build Coastguard Worker << ((m_calcPerPrimitiveBBox) ? ("to exactly cover each generated primitive") :
717*35238bceSAndroid Build Coastguard Worker (m_bboxSize == BBOXSIZE_EQUAL) ? ("to exactly cover rendered grid") :
718*35238bceSAndroid Build Coastguard Worker (m_bboxSize == BBOXSIZE_LARGER) ? ("to cover the grid and include some padding") :
719*35238bceSAndroid Build Coastguard Worker (m_bboxSize == BBOXSIZE_SMALLER) ? ("to cover only a subset of the grid") :
720*35238bceSAndroid Build Coastguard Worker (DE_NULL))
721*35238bceSAndroid Build Coastguard Worker << ".\n"
722*35238bceSAndroid Build Coastguard Worker << "Rendering with vertex" << ((m_hasTessellationStage) ? ("-tessellation{ctrl,eval}") : (""))
723*35238bceSAndroid Build Coastguard Worker << ((m_hasGeometryStage) ? ("-geometry") : ("")) << "-fragment program.\n"
724*35238bceSAndroid Build Coastguard Worker << "Set bounding box using "
725*35238bceSAndroid Build Coastguard Worker << ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
726*35238bceSAndroid Build Coastguard Worker << "\n"
727*35238bceSAndroid Build Coastguard Worker << "Verifying rendering results are valid within the bounding box." << tcu::TestLog::EndMessage;
728*35238bceSAndroid Build Coastguard Worker
729*35238bceSAndroid Build Coastguard Worker // resources
730*35238bceSAndroid Build Coastguard Worker
731*35238bceSAndroid Build Coastguard Worker {
732*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
733*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()));
734*35238bceSAndroid Build Coastguard Worker sources << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()));
735*35238bceSAndroid Build Coastguard Worker
736*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
737*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(
738*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationControlSource().c_str()))
739*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
740*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationEvaluationSource().c_str()));
741*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
742*35238bceSAndroid Build Coastguard Worker sources << glu::GeometrySource(specializeShader(m_context, genGeometrySource().c_str()));
743*35238bceSAndroid Build Coastguard Worker
744*35238bceSAndroid Build Coastguard Worker m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
745*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "build program");
746*35238bceSAndroid Build Coastguard Worker
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
749*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
750*35238bceSAndroid Build Coastguard Worker }
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
753*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
754*35238bceSAndroid Build Coastguard Worker }
755*35238bceSAndroid Build Coastguard Worker
756*35238bceSAndroid Build Coastguard Worker if (m_renderTarget == RENDERTARGET_FBO)
757*35238bceSAndroid Build Coastguard Worker {
758*35238bceSAndroid Build Coastguard Worker glu::Texture colorAttachment(m_context.getRenderContext());
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D, *colorAttachment);
761*35238bceSAndroid Build Coastguard Worker gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, FBO_SIZE, FBO_SIZE);
762*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");
763*35238bceSAndroid Build Coastguard Worker
764*35238bceSAndroid Build Coastguard Worker m_fbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
765*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);
766*35238bceSAndroid Build Coastguard Worker gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *colorAttachment, 0);
767*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "attach");
768*35238bceSAndroid Build Coastguard Worker
769*35238bceSAndroid Build Coastguard Worker // unbind to prevent texture name deletion from removing it from current fbo attachments
770*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker
773*35238bceSAndroid Build Coastguard Worker m_boundingBoxFunc = getBoundingBoxFunction(m_context);
774*35238bceSAndroid Build Coastguard Worker
775*35238bceSAndroid Build Coastguard Worker {
776*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> data;
777*35238bceSAndroid Build Coastguard Worker
778*35238bceSAndroid Build Coastguard Worker getAttributeData(data);
779*35238bceSAndroid Build Coastguard Worker
780*35238bceSAndroid Build Coastguard Worker // Generate VAO for desktop OpenGL
781*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
782*35238bceSAndroid Build Coastguard Worker {
783*35238bceSAndroid Build Coastguard Worker gl.genVertexArrays(1, &m_vao);
784*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(m_vao);
785*35238bceSAndroid Build Coastguard Worker }
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
788*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
789*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
790*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");
791*35238bceSAndroid Build Coastguard Worker }
792*35238bceSAndroid Build Coastguard Worker
793*35238bceSAndroid Build Coastguard Worker // Iterations
794*35238bceSAndroid Build Coastguard Worker for (int iterationNdx = 0; iterationNdx < m_numIterations; ++iterationNdx)
795*35238bceSAndroid Build Coastguard Worker m_iterationConfigs.push_back(generateConfig(iterationNdx, renderTargetSize));
796*35238bceSAndroid Build Coastguard Worker }
797*35238bceSAndroid Build Coastguard Worker
deinit(void)798*35238bceSAndroid Build Coastguard Worker void BBoxRenderCase::deinit(void)
799*35238bceSAndroid Build Coastguard Worker {
800*35238bceSAndroid Build Coastguard Worker m_program.clear();
801*35238bceSAndroid Build Coastguard Worker m_vbo.clear();
802*35238bceSAndroid Build Coastguard Worker m_fbo.clear();
803*35238bceSAndroid Build Coastguard Worker
804*35238bceSAndroid Build Coastguard Worker if (m_vao)
805*35238bceSAndroid Build Coastguard Worker {
806*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
807*35238bceSAndroid Build Coastguard Worker m_vao = 0;
808*35238bceSAndroid Build Coastguard Worker }
809*35238bceSAndroid Build Coastguard Worker }
810*35238bceSAndroid Build Coastguard Worker
iterate(void)811*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::IterateResult BBoxRenderCase::iterate(void)
812*35238bceSAndroid Build Coastguard Worker {
813*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(),
814*35238bceSAndroid Build Coastguard Worker std::string() + "Iteration" + de::toString((int)m_iteration),
815*35238bceSAndroid Build Coastguard Worker std::string() + "Iteration " + de::toString((int)m_iteration + 1) + "/" +
816*35238bceSAndroid Build Coastguard Worker de::toString((int)m_iterationConfigs.size()));
817*35238bceSAndroid Build Coastguard Worker const IterationConfig &config = m_iterationConfigs[m_iteration];
818*35238bceSAndroid Build Coastguard Worker
819*35238bceSAndroid Build Coastguard Worker // default
820*35238bceSAndroid Build Coastguard Worker if (m_iteration == 0)
821*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
822*35238bceSAndroid Build Coastguard Worker
823*35238bceSAndroid Build Coastguard Worker renderTestPattern(config);
824*35238bceSAndroid Build Coastguard Worker verifyRenderResult(config);
825*35238bceSAndroid Build Coastguard Worker
826*35238bceSAndroid Build Coastguard Worker if (++m_iteration < (int)m_iterationConfigs.size())
827*35238bceSAndroid Build Coastguard Worker return CONTINUE;
828*35238bceSAndroid Build Coastguard Worker
829*35238bceSAndroid Build Coastguard Worker return STOP;
830*35238bceSAndroid Build Coastguard Worker }
831*35238bceSAndroid Build Coastguard Worker
generateRandomConfig(int seed,const tcu::IVec2 & renderTargetSize) const832*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::IterationConfig BBoxRenderCase::generateRandomConfig(int seed, const tcu::IVec2 &renderTargetSize) const
833*35238bceSAndroid Build Coastguard Worker {
834*35238bceSAndroid Build Coastguard Worker de::Random rnd(seed);
835*35238bceSAndroid Build Coastguard Worker IterationConfig config;
836*35238bceSAndroid Build Coastguard Worker
837*35238bceSAndroid Build Coastguard Worker // viewport config
838*35238bceSAndroid Build Coastguard Worker config.viewportSize.x() = rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.x(), MAX_VIEWPORT_SIZE));
839*35238bceSAndroid Build Coastguard Worker config.viewportSize.y() = rnd.getInt(MIN_VIEWPORT_SIZE, de::min<int>(renderTargetSize.y(), MAX_VIEWPORT_SIZE));
840*35238bceSAndroid Build Coastguard Worker config.viewportPos.x() = rnd.getInt(0, renderTargetSize.x() - config.viewportSize.x());
841*35238bceSAndroid Build Coastguard Worker config.viewportPos.y() = rnd.getInt(0, renderTargetSize.y() - config.viewportSize.y());
842*35238bceSAndroid Build Coastguard Worker
843*35238bceSAndroid Build Coastguard Worker // pattern location inside viewport
844*35238bceSAndroid Build Coastguard Worker config.patternSize.x() = rnd.getFloat(0.4f, 1.4f);
845*35238bceSAndroid Build Coastguard Worker config.patternSize.y() = rnd.getFloat(0.4f, 1.4f);
846*35238bceSAndroid Build Coastguard Worker config.patternPos.x() = rnd.getFloat(-1.0f, 1.0f - config.patternSize.x());
847*35238bceSAndroid Build Coastguard Worker config.patternPos.y() = rnd.getFloat(-1.0f, 1.0f - config.patternSize.y());
848*35238bceSAndroid Build Coastguard Worker
849*35238bceSAndroid Build Coastguard Worker // accurate bounding box
850*35238bceSAndroid Build Coastguard Worker config.bbox.min = tcu::Vec4(config.patternPos.x(), config.patternPos.y(), 0.0f, 1.0f);
851*35238bceSAndroid Build Coastguard Worker config.bbox.max = tcu::Vec4(config.patternPos.x() + config.patternSize.x(),
852*35238bceSAndroid Build Coastguard Worker config.patternPos.y() + config.patternSize.y(), 0.0f, 1.0f);
853*35238bceSAndroid Build Coastguard Worker
854*35238bceSAndroid Build Coastguard Worker if (m_bboxSize == BBOXSIZE_LARGER)
855*35238bceSAndroid Build Coastguard Worker {
856*35238bceSAndroid Build Coastguard Worker // increase bbox size
857*35238bceSAndroid Build Coastguard Worker config.bbox.min.x() -= rnd.getFloat() * 0.5f;
858*35238bceSAndroid Build Coastguard Worker config.bbox.min.y() -= rnd.getFloat() * 0.5f;
859*35238bceSAndroid Build Coastguard Worker config.bbox.min.z() -= rnd.getFloat() * 0.5f;
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker config.bbox.max.x() += rnd.getFloat() * 0.5f;
862*35238bceSAndroid Build Coastguard Worker config.bbox.max.y() += rnd.getFloat() * 0.5f;
863*35238bceSAndroid Build Coastguard Worker config.bbox.max.z() += rnd.getFloat() * 0.5f;
864*35238bceSAndroid Build Coastguard Worker }
865*35238bceSAndroid Build Coastguard Worker else if (m_bboxSize == BBOXSIZE_SMALLER)
866*35238bceSAndroid Build Coastguard Worker {
867*35238bceSAndroid Build Coastguard Worker // reduce bbox size
868*35238bceSAndroid Build Coastguard Worker config.bbox.min.x() += rnd.getFloat() * 0.4f * config.patternSize.x();
869*35238bceSAndroid Build Coastguard Worker config.bbox.min.y() += rnd.getFloat() * 0.4f * config.patternSize.y();
870*35238bceSAndroid Build Coastguard Worker
871*35238bceSAndroid Build Coastguard Worker config.bbox.max.x() -= rnd.getFloat() * 0.4f * config.patternSize.x();
872*35238bceSAndroid Build Coastguard Worker config.bbox.max.y() -= rnd.getFloat() * 0.4f * config.patternSize.y();
873*35238bceSAndroid Build Coastguard Worker }
874*35238bceSAndroid Build Coastguard Worker
875*35238bceSAndroid Build Coastguard Worker return config;
876*35238bceSAndroid Build Coastguard Worker }
877*35238bceSAndroid Build Coastguard Worker
getViewportPatternArea(const tcu::Vec2 & patternPos,const tcu::Vec2 & patternSize,const tcu::IVec2 & viewportSize,AABBRoundDirection roundDir) const878*35238bceSAndroid Build Coastguard Worker tcu::IVec4 BBoxRenderCase::getViewportPatternArea(const tcu::Vec2 &patternPos, const tcu::Vec2 &patternSize,
879*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &viewportSize, AABBRoundDirection roundDir) const
880*35238bceSAndroid Build Coastguard Worker {
881*35238bceSAndroid Build Coastguard Worker const float halfPixel = 0.5f;
882*35238bceSAndroid Build Coastguard Worker tcu::Vec4 vertexBox;
883*35238bceSAndroid Build Coastguard Worker tcu::IVec4 pixelBox;
884*35238bceSAndroid Build Coastguard Worker
885*35238bceSAndroid Build Coastguard Worker vertexBox.x() = (patternPos.x() * 0.5f + 0.5f) * (float)viewportSize.x();
886*35238bceSAndroid Build Coastguard Worker vertexBox.y() = (patternPos.y() * 0.5f + 0.5f) * (float)viewportSize.y();
887*35238bceSAndroid Build Coastguard Worker vertexBox.z() = ((patternPos.x() + patternSize.x()) * 0.5f + 0.5f) * (float)viewportSize.x();
888*35238bceSAndroid Build Coastguard Worker vertexBox.w() = ((patternPos.y() + patternSize.y()) * 0.5f + 0.5f) * (float)viewportSize.y();
889*35238bceSAndroid Build Coastguard Worker
890*35238bceSAndroid Build Coastguard Worker if (roundDir == ROUND_INWARDS)
891*35238bceSAndroid Build Coastguard Worker {
892*35238bceSAndroid Build Coastguard Worker pixelBox.x() = (int)deFloatCeil(vertexBox.x() + halfPixel);
893*35238bceSAndroid Build Coastguard Worker pixelBox.y() = (int)deFloatCeil(vertexBox.y() + halfPixel);
894*35238bceSAndroid Build Coastguard Worker pixelBox.z() = (int)deFloatFloor(vertexBox.z() - halfPixel);
895*35238bceSAndroid Build Coastguard Worker pixelBox.w() = (int)deFloatFloor(vertexBox.w() - halfPixel);
896*35238bceSAndroid Build Coastguard Worker }
897*35238bceSAndroid Build Coastguard Worker else
898*35238bceSAndroid Build Coastguard Worker {
899*35238bceSAndroid Build Coastguard Worker pixelBox.x() = (int)deFloatFloor(vertexBox.x() - halfPixel);
900*35238bceSAndroid Build Coastguard Worker pixelBox.y() = (int)deFloatFloor(vertexBox.y() - halfPixel);
901*35238bceSAndroid Build Coastguard Worker pixelBox.z() = (int)deFloatCeil(vertexBox.z() + halfPixel);
902*35238bceSAndroid Build Coastguard Worker pixelBox.w() = (int)deFloatCeil(vertexBox.w() + halfPixel);
903*35238bceSAndroid Build Coastguard Worker }
904*35238bceSAndroid Build Coastguard Worker
905*35238bceSAndroid Build Coastguard Worker return pixelBox;
906*35238bceSAndroid Build Coastguard Worker }
907*35238bceSAndroid Build Coastguard Worker
setupRender(const IterationConfig & config)908*35238bceSAndroid Build Coastguard Worker void BBoxRenderCase::setupRender(const IterationConfig &config)
909*35238bceSAndroid Build Coastguard Worker {
910*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
911*35238bceSAndroid Build Coastguard Worker const glw::GLint posLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
912*35238bceSAndroid Build Coastguard Worker const glw::GLint colLocation = gl.getAttribLocation(m_program->getProgram(), "a_color");
913*35238bceSAndroid Build Coastguard Worker const glw::GLint posScaleLocation = gl.getUniformLocation(m_program->getProgram(), "u_posScale");
914*35238bceSAndroid Build Coastguard Worker
915*35238bceSAndroid Build Coastguard Worker TCU_CHECK(posLocation != -1);
916*35238bceSAndroid Build Coastguard Worker TCU_CHECK(colLocation != -1);
917*35238bceSAndroid Build Coastguard Worker TCU_CHECK(posScaleLocation != -1);
918*35238bceSAndroid Build Coastguard Worker
919*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting viewport to ("
920*35238bceSAndroid Build Coastguard Worker << "x: " << config.viewportPos.x() << ", "
921*35238bceSAndroid Build Coastguard Worker << "y: " << config.viewportPos.y() << ", "
922*35238bceSAndroid Build Coastguard Worker << "w: " << config.viewportSize.x() << ", "
923*35238bceSAndroid Build Coastguard Worker << "h: " << config.viewportSize.y() << ")\n"
924*35238bceSAndroid Build Coastguard Worker << "Vertex coordinates are in range:\n"
925*35238bceSAndroid Build Coastguard Worker << "\tx: [" << config.patternPos.x() << ", " << (config.patternPos.x() + config.patternSize.x())
926*35238bceSAndroid Build Coastguard Worker << "]\n"
927*35238bceSAndroid Build Coastguard Worker << "\ty: [" << config.patternPos.y() << ", " << (config.patternPos.y() + config.patternSize.y())
928*35238bceSAndroid Build Coastguard Worker << "]\n"
929*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
930*35238bceSAndroid Build Coastguard Worker
931*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
932*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting primitive bounding box to:\n"
933*35238bceSAndroid Build Coastguard Worker << "\t" << config.bbox.min << "\n"
934*35238bceSAndroid Build Coastguard Worker << "\t" << config.bbox.max << "\n"
935*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
936*35238bceSAndroid Build Coastguard Worker
937*35238bceSAndroid Build Coastguard Worker if (m_useGlobalState)
938*35238bceSAndroid Build Coastguard Worker m_boundingBoxFunc(config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w(),
939*35238bceSAndroid Build Coastguard Worker config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
940*35238bceSAndroid Build Coastguard Worker else
941*35238bceSAndroid Build Coastguard Worker // state is overriden by the tessellation output, set bbox to invisible area to imitiate dirty state left by application
942*35238bceSAndroid Build Coastguard Worker m_boundingBoxFunc(-2.0f, -2.0f, 0.0f, 1.0f, -1.7f, -1.7f, 0.0f, 1.0f);
943*35238bceSAndroid Build Coastguard Worker
944*35238bceSAndroid Build Coastguard Worker if (m_fbo)
945*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, **m_fbo);
946*35238bceSAndroid Build Coastguard Worker
947*35238bceSAndroid Build Coastguard Worker gl.viewport(config.viewportPos.x(), config.viewportPos.y(), config.viewportSize.x(), config.viewportSize.y());
948*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
949*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
950*35238bceSAndroid Build Coastguard Worker
951*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
952*35238bceSAndroid Build Coastguard Worker
953*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])),
954*35238bceSAndroid Build Coastguard Worker glu::BufferOffsetAsPointer(4 * VA_POS_VEC_NDX * sizeof(float)));
955*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(VA_NUM_ATTRIB_VECS * sizeof(float[4])),
956*35238bceSAndroid Build Coastguard Worker glu::BufferOffsetAsPointer(4 * VA_COL_VEC_NDX * sizeof(float)));
957*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
958*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(colLocation);
959*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
960*35238bceSAndroid Build Coastguard Worker gl.uniform4f(posScaleLocation, config.patternPos.x(), config.patternPos.y(), config.patternSize.x(),
961*35238bceSAndroid Build Coastguard Worker config.patternSize.y());
962*35238bceSAndroid Build Coastguard Worker
963*35238bceSAndroid Build Coastguard Worker {
964*35238bceSAndroid Build Coastguard Worker const glw::GLint bboxMinPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMin");
965*35238bceSAndroid Build Coastguard Worker const glw::GLint bboxMaxPos = gl.getUniformLocation(m_program->getProgram(), "u_primitiveBBoxMax");
966*35238bceSAndroid Build Coastguard Worker
967*35238bceSAndroid Build Coastguard Worker gl.uniform4f(bboxMinPos, config.bbox.min.x(), config.bbox.min.y(), config.bbox.min.z(), config.bbox.min.w());
968*35238bceSAndroid Build Coastguard Worker gl.uniform4f(bboxMaxPos, config.bbox.max.x(), config.bbox.max.y(), config.bbox.max.z(), config.bbox.max.w());
969*35238bceSAndroid Build Coastguard Worker }
970*35238bceSAndroid Build Coastguard Worker
971*35238bceSAndroid Build Coastguard Worker gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportPos"), config.viewportPos.x(),
972*35238bceSAndroid Build Coastguard Worker config.viewportPos.y());
973*35238bceSAndroid Build Coastguard Worker gl.uniform2i(gl.getUniformLocation(m_program->getProgram(), "u_viewportSize"), config.viewportSize.x(),
974*35238bceSAndroid Build Coastguard Worker config.viewportSize.y());
975*35238bceSAndroid Build Coastguard Worker
976*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup");
977*35238bceSAndroid Build Coastguard Worker }
978*35238bceSAndroid Build Coastguard Worker
genShaderFunction(ShaderFunction func) const979*35238bceSAndroid Build Coastguard Worker const char *BBoxRenderCase::genShaderFunction(ShaderFunction func) const
980*35238bceSAndroid Build Coastguard Worker {
981*35238bceSAndroid Build Coastguard Worker switch (func)
982*35238bceSAndroid Build Coastguard Worker {
983*35238bceSAndroid Build Coastguard Worker case SHADER_FUNC_MIRROR_X:
984*35238bceSAndroid Build Coastguard Worker return "vec4 mirrorX(in highp vec4 p)\n"
985*35238bceSAndroid Build Coastguard Worker "{\n"
986*35238bceSAndroid Build Coastguard Worker " highp vec2 patternOffset = u_posScale.xy;\n"
987*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
988*35238bceSAndroid Build Coastguard Worker " highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
989*35238bceSAndroid Build Coastguard Worker " return vec4(2.0 * patternCenter.x - p.x, p.y, p.z, p.w);\n"
990*35238bceSAndroid Build Coastguard Worker "}\n";
991*35238bceSAndroid Build Coastguard Worker
992*35238bceSAndroid Build Coastguard Worker case SHADER_FUNC_MIRROR_Y:
993*35238bceSAndroid Build Coastguard Worker return "vec4 mirrorY(in highp vec4 p)\n"
994*35238bceSAndroid Build Coastguard Worker "{\n"
995*35238bceSAndroid Build Coastguard Worker " highp vec2 patternOffset = u_posScale.xy;\n"
996*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
997*35238bceSAndroid Build Coastguard Worker " highp vec2 patternCenter = patternOffset + patternScale * 0.5;\n"
998*35238bceSAndroid Build Coastguard Worker " return vec4(p.x, 2.0 * patternCenter.y - p.y, p.z, p.w);\n"
999*35238bceSAndroid Build Coastguard Worker "}\n";
1000*35238bceSAndroid Build Coastguard Worker
1001*35238bceSAndroid Build Coastguard Worker case SHADER_FUNC_INSIDE_BBOX:
1002*35238bceSAndroid Build Coastguard Worker return "uniform highp ivec2 u_viewportPos;\n"
1003*35238bceSAndroid Build Coastguard Worker "uniform highp ivec2 u_viewportSize;\n"
1004*35238bceSAndroid Build Coastguard Worker "flat in highp float v_bbox_expansionSize;\n"
1005*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_bbox_clipMin;\n"
1006*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_bbox_clipMax;\n"
1007*35238bceSAndroid Build Coastguard Worker "\n"
1008*35238bceSAndroid Build Coastguard Worker "bool fragmentInsideTheBBox(in highp float depth)\n"
1009*35238bceSAndroid Build Coastguard Worker "{\n"
1010*35238bceSAndroid Build Coastguard Worker " highp vec4 wc = vec4(floor((v_bbox_clipMin.x * 0.5 + 0.5) * float(u_viewportSize.x) - "
1011*35238bceSAndroid Build Coastguard Worker "v_bbox_expansionSize/2.0),\n"
1012*35238bceSAndroid Build Coastguard Worker " floor((v_bbox_clipMin.y * 0.5 + 0.5) * float(u_viewportSize.y) - "
1013*35238bceSAndroid Build Coastguard Worker "v_bbox_expansionSize/2.0),\n"
1014*35238bceSAndroid Build Coastguard Worker " ceil((v_bbox_clipMax.x * 0.5 + 0.5) * float(u_viewportSize.x) + "
1015*35238bceSAndroid Build Coastguard Worker "v_bbox_expansionSize/2.0),\n"
1016*35238bceSAndroid Build Coastguard Worker " ceil((v_bbox_clipMax.y * 0.5 + 0.5) * float(u_viewportSize.y) + "
1017*35238bceSAndroid Build Coastguard Worker "v_bbox_expansionSize/2.0));\n"
1018*35238bceSAndroid Build Coastguard Worker " if (gl_FragCoord.x < float(u_viewportPos.x) + wc.x || gl_FragCoord.x > float(u_viewportPos.x) + "
1019*35238bceSAndroid Build Coastguard Worker "wc.z ||\n"
1020*35238bceSAndroid Build Coastguard Worker " gl_FragCoord.y < float(u_viewportPos.y) + wc.y || gl_FragCoord.y > float(u_viewportPos.y) + "
1021*35238bceSAndroid Build Coastguard Worker "wc.w)\n"
1022*35238bceSAndroid Build Coastguard Worker " return false;\n"
1023*35238bceSAndroid Build Coastguard Worker " const highp float dEpsilon = 0.001;\n"
1024*35238bceSAndroid Build Coastguard Worker " if (depth*2.0-1.0 < v_bbox_clipMin.z - dEpsilon || depth*2.0-1.0 > v_bbox_clipMax.z + dEpsilon)\n"
1025*35238bceSAndroid Build Coastguard Worker " return false;\n"
1026*35238bceSAndroid Build Coastguard Worker " return true;\n"
1027*35238bceSAndroid Build Coastguard Worker "}\n";
1028*35238bceSAndroid Build Coastguard Worker default:
1029*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1030*35238bceSAndroid Build Coastguard Worker return "";
1031*35238bceSAndroid Build Coastguard Worker }
1032*35238bceSAndroid Build Coastguard Worker }
1033*35238bceSAndroid Build Coastguard Worker
1034*35238bceSAndroid Build Coastguard Worker class GridRenderCase : public BBoxRenderCase
1035*35238bceSAndroid Build Coastguard Worker {
1036*35238bceSAndroid Build Coastguard Worker public:
1037*35238bceSAndroid Build Coastguard Worker GridRenderCase(Context &context, const char *name, const char *description, uint32_t flags);
1038*35238bceSAndroid Build Coastguard Worker ~GridRenderCase(void);
1039*35238bceSAndroid Build Coastguard Worker
1040*35238bceSAndroid Build Coastguard Worker private:
1041*35238bceSAndroid Build Coastguard Worker void init(void);
1042*35238bceSAndroid Build Coastguard Worker
1043*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
1044*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
1045*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
1046*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
1047*35238bceSAndroid Build Coastguard Worker std::string genGeometrySource(void) const;
1048*35238bceSAndroid Build Coastguard Worker
1049*35238bceSAndroid Build Coastguard Worker IterationConfig generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const;
1050*35238bceSAndroid Build Coastguard Worker void getAttributeData(std::vector<tcu::Vec4> &data) const;
1051*35238bceSAndroid Build Coastguard Worker void renderTestPattern(const IterationConfig &config);
1052*35238bceSAndroid Build Coastguard Worker void verifyRenderResult(const IterationConfig &config);
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker const int m_gridSize;
1055*35238bceSAndroid Build Coastguard Worker };
1056*35238bceSAndroid Build Coastguard Worker
GridRenderCase(Context & context,const char * name,const char * description,uint32_t flags)1057*35238bceSAndroid Build Coastguard Worker GridRenderCase::GridRenderCase(Context &context, const char *name, const char *description, uint32_t flags)
1058*35238bceSAndroid Build Coastguard Worker : BBoxRenderCase(context, name, description, 12, flags)
1059*35238bceSAndroid Build Coastguard Worker , m_gridSize(24)
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker }
1062*35238bceSAndroid Build Coastguard Worker
~GridRenderCase(void)1063*35238bceSAndroid Build Coastguard Worker GridRenderCase::~GridRenderCase(void)
1064*35238bceSAndroid Build Coastguard Worker {
1065*35238bceSAndroid Build Coastguard Worker }
1066*35238bceSAndroid Build Coastguard Worker
init(void)1067*35238bceSAndroid Build Coastguard Worker void GridRenderCase::init(void)
1068*35238bceSAndroid Build Coastguard Worker {
1069*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1070*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << "Rendering yellow-green grid to "
1071*35238bceSAndroid Build Coastguard Worker << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
1072*35238bceSAndroid Build Coastguard Worker << "Grid cells are in random order, varying grid size and location for each iteration.\n"
1073*35238bceSAndroid Build Coastguard Worker << "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated blue channel."
1074*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1075*35238bceSAndroid Build Coastguard Worker
1076*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::init();
1077*35238bceSAndroid Build Coastguard Worker }
1078*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const1079*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::genVertexSource(void) const
1080*35238bceSAndroid Build Coastguard Worker {
1081*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1084*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
1085*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_color;\n"
1086*35238bceSAndroid Build Coastguard Worker "out highp vec4 vtx_color;\n"
1087*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1088*35238bceSAndroid Build Coastguard Worker "\n";
1089*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
1090*35238bceSAndroid Build Coastguard Worker {
1091*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
1092*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
1093*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n"
1094*35238bceSAndroid Build Coastguard Worker "\n"
1095*35238bceSAndroid Build Coastguard Worker "flat out highp float v_"
1096*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1097*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize;\n"
1098*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1099*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1100*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
1101*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1102*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1103*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax;\n"
1104*35238bceSAndroid Build Coastguard Worker "\n";
1105*35238bceSAndroid Build Coastguard Worker }
1106*35238bceSAndroid Build Coastguard Worker
1107*35238bceSAndroid Build Coastguard Worker buf << "void main()\n"
1108*35238bceSAndroid Build Coastguard Worker "{\n"
1109*35238bceSAndroid Build Coastguard Worker " highp vec2 patternOffset = u_posScale.xy;\n"
1110*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
1111*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
1112*35238bceSAndroid Build Coastguard Worker " vtx_color = a_color;\n";
1113*35238bceSAndroid Build Coastguard Worker
1114*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
1115*35238bceSAndroid Build Coastguard Worker {
1116*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
1117*35238bceSAndroid Build Coastguard Worker buf << "\n"
1118*35238bceSAndroid Build Coastguard Worker " v_"
1119*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1120*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize = 0.0;\n"
1121*35238bceSAndroid Build Coastguard Worker " v_"
1122*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1123*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin =\n"
1124*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
1125*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
1126*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
1127*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n"
1128*35238bceSAndroid Build Coastguard Worker " v_"
1129*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1130*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax =\n"
1131*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
1132*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
1133*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
1134*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n";
1135*35238bceSAndroid Build Coastguard Worker }
1136*35238bceSAndroid Build Coastguard Worker
1137*35238bceSAndroid Build Coastguard Worker buf << "}\n";
1138*35238bceSAndroid Build Coastguard Worker
1139*35238bceSAndroid Build Coastguard Worker return buf.str();
1140*35238bceSAndroid Build Coastguard Worker }
1141*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const1142*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::genFragmentSource(void) const
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasGeometryStage) ? ("geo_color") :
1145*35238bceSAndroid Build Coastguard Worker (m_hasTessellationStage) ? ("tess_color") :
1146*35238bceSAndroid Build Coastguard Worker ("vtx_color");
1147*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1148*35238bceSAndroid Build Coastguard Worker
1149*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1150*35238bceSAndroid Build Coastguard Worker "in mediump vec4 "
1151*35238bceSAndroid Build Coastguard Worker << colorInputName
1152*35238bceSAndroid Build Coastguard Worker << ";\n"
1153*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
1154*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
1155*35238bceSAndroid Build Coastguard Worker << "\n"
1156*35238bceSAndroid Build Coastguard Worker "void main()\n"
1157*35238bceSAndroid Build Coastguard Worker "{\n"
1158*35238bceSAndroid Build Coastguard Worker " mediump vec4 baseColor = "
1159*35238bceSAndroid Build Coastguard Worker << colorInputName
1160*35238bceSAndroid Build Coastguard Worker << ";\n"
1161*35238bceSAndroid Build Coastguard Worker " mediump float blueChannel;\n"
1162*35238bceSAndroid Build Coastguard Worker " if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
1163*35238bceSAndroid Build Coastguard Worker " blueChannel = 0.0;\n"
1164*35238bceSAndroid Build Coastguard Worker " else\n"
1165*35238bceSAndroid Build Coastguard Worker " blueChannel = 1.0;\n"
1166*35238bceSAndroid Build Coastguard Worker " o_color = vec4(baseColor.r, baseColor.g, blueChannel, baseColor.a);\n"
1167*35238bceSAndroid Build Coastguard Worker "}\n";
1168*35238bceSAndroid Build Coastguard Worker
1169*35238bceSAndroid Build Coastguard Worker return buf.str();
1170*35238bceSAndroid Build Coastguard Worker }
1171*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const1172*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::genTessellationControlSource(void) const
1173*35238bceSAndroid Build Coastguard Worker {
1174*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1175*35238bceSAndroid Build Coastguard Worker
1176*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1177*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
1178*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
1179*35238bceSAndroid Build Coastguard Worker "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
1180*35238bceSAndroid Build Coastguard Worker "layout(vertices=3) out;\n"
1181*35238bceSAndroid Build Coastguard Worker "\n"
1182*35238bceSAndroid Build Coastguard Worker "in highp vec4 vtx_color[];\n"
1183*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_ctrl_color[];\n"
1184*35238bceSAndroid Build Coastguard Worker "uniform highp float u_tessellationLevel;\n"
1185*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n";
1186*35238bceSAndroid Build Coastguard Worker
1187*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
1188*35238bceSAndroid Build Coastguard Worker {
1189*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
1190*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n";
1191*35238bceSAndroid Build Coastguard Worker }
1192*35238bceSAndroid Build Coastguard Worker
1193*35238bceSAndroid Build Coastguard Worker buf << "patch out highp float vp_bbox_expansionSize;\n"
1194*35238bceSAndroid Build Coastguard Worker "patch out highp vec3 vp_bbox_clipMin;\n"
1195*35238bceSAndroid Build Coastguard Worker "patch out highp vec3 vp_bbox_clipMax;\n";
1196*35238bceSAndroid Build Coastguard Worker
1197*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
1198*35238bceSAndroid Build Coastguard Worker {
1199*35238bceSAndroid Build Coastguard Worker buf << "\n";
1200*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
1201*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
1202*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
1203*35238bceSAndroid Build Coastguard Worker
1204*35238bceSAndroid Build Coastguard Worker buf << "vec4 transformVec(in highp vec4 p)\n"
1205*35238bceSAndroid Build Coastguard Worker "{\n"
1206*35238bceSAndroid Build Coastguard Worker " return "
1207*35238bceSAndroid Build Coastguard Worker << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)"))
1208*35238bceSAndroid Build Coastguard Worker << ";\n"
1209*35238bceSAndroid Build Coastguard Worker "}\n";
1210*35238bceSAndroid Build Coastguard Worker }
1211*35238bceSAndroid Build Coastguard Worker
1212*35238bceSAndroid Build Coastguard Worker buf << "\n"
1213*35238bceSAndroid Build Coastguard Worker "void main()\n"
1214*35238bceSAndroid Build Coastguard Worker "{\n"
1215*35238bceSAndroid Build Coastguard Worker " // convert to nonsensical coordinates, just in case\n"
1216*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
1217*35238bceSAndroid Build Coastguard Worker " tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
1218*35238bceSAndroid Build Coastguard Worker "\n"
1219*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = u_tessellationLevel;\n"
1220*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_tessellationLevel;\n"
1221*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = u_tessellationLevel;\n"
1222*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = u_tessellationLevel;\n";
1223*35238bceSAndroid Build Coastguard Worker
1224*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
1225*35238bceSAndroid Build Coastguard Worker {
1226*35238bceSAndroid Build Coastguard Worker buf << "\n"
1227*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = min(min(transformVec(gl_in[0].gl_Position),\n"
1228*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[1].gl_Position)),\n"
1229*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[2].gl_Position));\n"
1230*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = max(max(transformVec(gl_in[0].gl_Position),\n"
1231*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[1].gl_Position)),\n"
1232*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[2].gl_Position));\n";
1233*35238bceSAndroid Build Coastguard Worker }
1234*35238bceSAndroid Build Coastguard Worker else
1235*35238bceSAndroid Build Coastguard Worker {
1236*35238bceSAndroid Build Coastguard Worker buf << "\n"
1237*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = u_primitiveBBoxMin;\n"
1238*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = u_primitiveBBoxMax;\n";
1239*35238bceSAndroid Build Coastguard Worker }
1240*35238bceSAndroid Build Coastguard Worker
1241*35238bceSAndroid Build Coastguard Worker if (!m_useGlobalState)
1242*35238bceSAndroid Build Coastguard Worker buf << "\n"
1243*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
1244*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";
1245*35238bceSAndroid Build Coastguard Worker
1246*35238bceSAndroid Build Coastguard Worker buf << " vp_bbox_expansionSize = 0.0;\n"
1247*35238bceSAndroid Build Coastguard Worker " vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
1248*35238bceSAndroid Build Coastguard Worker " vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
1249*35238bceSAndroid Build Coastguard Worker " vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
1250*35238bceSAndroid Build Coastguard Worker " vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
1251*35238bceSAndroid Build Coastguard Worker "}\n";
1252*35238bceSAndroid Build Coastguard Worker
1253*35238bceSAndroid Build Coastguard Worker return buf.str();
1254*35238bceSAndroid Build Coastguard Worker }
1255*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const1256*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::genTessellationEvaluationSource(void) const
1257*35238bceSAndroid Build Coastguard Worker {
1258*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1259*35238bceSAndroid Build Coastguard Worker
1260*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1261*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
1262*35238bceSAndroid Build Coastguard Worker "${GPU_SHADER5_REQUIRE}\n"
1263*35238bceSAndroid Build Coastguard Worker "layout(triangles) in;\n"
1264*35238bceSAndroid Build Coastguard Worker "\n"
1265*35238bceSAndroid Build Coastguard Worker "in highp vec4 tess_ctrl_color[];\n"
1266*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_color;\n"
1267*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1268*35238bceSAndroid Build Coastguard Worker "patch in highp float vp_bbox_expansionSize;\n"
1269*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMin;\n"
1270*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMax;\n"
1271*35238bceSAndroid Build Coastguard Worker "flat out highp float v_"
1272*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1273*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize;\n"
1274*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1275*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1276*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
1277*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1278*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1279*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax;\n"
1280*35238bceSAndroid Build Coastguard Worker "\n"
1281*35238bceSAndroid Build Coastguard Worker "precise gl_Position;\n"
1282*35238bceSAndroid Build Coastguard Worker "\n"
1283*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_Y)
1284*35238bceSAndroid Build Coastguard Worker << "void main()\n"
1285*35238bceSAndroid Build Coastguard Worker "{\n"
1286*35238bceSAndroid Build Coastguard Worker " // non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
1287*35238bceSAndroid Build Coastguard Worker " gl_Position = mirrorY(gl_TessCoord.x * gl_in[0].gl_Position.zwyx +\n"
1288*35238bceSAndroid Build Coastguard Worker " gl_TessCoord.y * gl_in[1].gl_Position.zwyx +\n"
1289*35238bceSAndroid Build Coastguard Worker " gl_TessCoord.z * gl_in[2].gl_Position.zwyx);\n"
1290*35238bceSAndroid Build Coastguard Worker " tess_color = tess_ctrl_color[0];\n"
1291*35238bceSAndroid Build Coastguard Worker " v_"
1292*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1293*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize = vp_bbox_expansionSize;\n"
1294*35238bceSAndroid Build Coastguard Worker " v_"
1295*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1296*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin = vp_bbox_clipMin;\n"
1297*35238bceSAndroid Build Coastguard Worker " v_"
1298*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1299*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax = vp_bbox_clipMax;\n"
1300*35238bceSAndroid Build Coastguard Worker "}\n";
1301*35238bceSAndroid Build Coastguard Worker
1302*35238bceSAndroid Build Coastguard Worker return buf.str();
1303*35238bceSAndroid Build Coastguard Worker }
1304*35238bceSAndroid Build Coastguard Worker
genGeometrySource(void) const1305*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::genGeometrySource(void) const
1306*35238bceSAndroid Build Coastguard Worker {
1307*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
1308*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1309*35238bceSAndroid Build Coastguard Worker
1310*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1311*35238bceSAndroid Build Coastguard Worker "${GEOMETRY_SHADER_REQUIRE}\n"
1312*35238bceSAndroid Build Coastguard Worker "layout(triangles) in;\n"
1313*35238bceSAndroid Build Coastguard Worker "layout(max_vertices=9, triangle_strip) out;\n"
1314*35238bceSAndroid Build Coastguard Worker "\n"
1315*35238bceSAndroid Build Coastguard Worker "in highp vec4 "
1316*35238bceSAndroid Build Coastguard Worker << colorInputName
1317*35238bceSAndroid Build Coastguard Worker << "[3];\n"
1318*35238bceSAndroid Build Coastguard Worker "out highp vec4 geo_color;\n"
1319*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1320*35238bceSAndroid Build Coastguard Worker "\n"
1321*35238bceSAndroid Build Coastguard Worker "flat in highp float v_geo_bbox_expansionSize[3];\n"
1322*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMin[3];\n"
1323*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMax[3];\n"
1324*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMin;\n"
1325*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMax;\n"
1326*35238bceSAndroid Build Coastguard Worker "flat out highp float v_bbox_expansionSize;\n"
1327*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_X)
1328*35238bceSAndroid Build Coastguard Worker << "\n"
1329*35238bceSAndroid Build Coastguard Worker "void setVisualizationVaryings()\n"
1330*35238bceSAndroid Build Coastguard Worker "{\n"
1331*35238bceSAndroid Build Coastguard Worker " v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
1332*35238bceSAndroid Build Coastguard Worker " v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
1333*35238bceSAndroid Build Coastguard Worker " v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
1334*35238bceSAndroid Build Coastguard Worker "}\n"
1335*35238bceSAndroid Build Coastguard Worker "void main()\n"
1336*35238bceSAndroid Build Coastguard Worker "{\n"
1337*35238bceSAndroid Build Coastguard Worker " // Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
1338*35238bceSAndroid Build Coastguard Worker " highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
1339*35238bceSAndroid Build Coastguard Worker " highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
1340*35238bceSAndroid Build Coastguard Worker " highp vec4 p2 = mirrorX(gl_in[2].gl_Position);\n"
1341*35238bceSAndroid Build Coastguard Worker " highp vec4 pCentroid = vec4((p0.xyz + p1.xyz + p2.xyz) / 3.0, 1.0);\n"
1342*35238bceSAndroid Build Coastguard Worker " highp vec4 triangleColor = "
1343*35238bceSAndroid Build Coastguard Worker << colorInputName
1344*35238bceSAndroid Build Coastguard Worker << "[0];\n"
1345*35238bceSAndroid Build Coastguard Worker "\n"
1346*35238bceSAndroid Build Coastguard Worker " gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1347*35238bceSAndroid Build Coastguard Worker " gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1348*35238bceSAndroid Build Coastguard Worker " gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1349*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1350*35238bceSAndroid Build Coastguard Worker "\n"
1351*35238bceSAndroid Build Coastguard Worker " gl_Position = p1; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1352*35238bceSAndroid Build Coastguard Worker " gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1353*35238bceSAndroid Build Coastguard Worker " gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1354*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1355*35238bceSAndroid Build Coastguard Worker "\n"
1356*35238bceSAndroid Build Coastguard Worker " gl_Position = p2; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1357*35238bceSAndroid Build Coastguard Worker " gl_Position = p0; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1358*35238bceSAndroid Build Coastguard Worker " gl_Position = pCentroid; geo_color = triangleColor; setVisualizationVaryings(); EmitVertex();\n"
1359*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1360*35238bceSAndroid Build Coastguard Worker "}\n";
1361*35238bceSAndroid Build Coastguard Worker
1362*35238bceSAndroid Build Coastguard Worker return buf.str();
1363*35238bceSAndroid Build Coastguard Worker }
1364*35238bceSAndroid Build Coastguard Worker
generateConfig(int iteration,const tcu::IVec2 & renderTargetSize) const1365*35238bceSAndroid Build Coastguard Worker GridRenderCase::IterationConfig GridRenderCase::generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const
1366*35238bceSAndroid Build Coastguard Worker {
1367*35238bceSAndroid Build Coastguard Worker return generateRandomConfig(0xDEDEDEu * (uint32_t)iteration, renderTargetSize);
1368*35238bceSAndroid Build Coastguard Worker }
1369*35238bceSAndroid Build Coastguard Worker
getAttributeData(std::vector<tcu::Vec4> & data) const1370*35238bceSAndroid Build Coastguard Worker void GridRenderCase::getAttributeData(std::vector<tcu::Vec4> &data) const
1371*35238bceSAndroid Build Coastguard Worker {
1372*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1373*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 yellow(1.0f, 1.0f, 0.0f, 1.0f);
1374*35238bceSAndroid Build Coastguard Worker std::vector<int> cellOrder(m_gridSize * m_gridSize);
1375*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xDE56789);
1376*35238bceSAndroid Build Coastguard Worker
1377*35238bceSAndroid Build Coastguard Worker // generate grid with cells in random order
1378*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
1379*35238bceSAndroid Build Coastguard Worker cellOrder[ndx] = ndx;
1380*35238bceSAndroid Build Coastguard Worker rnd.shuffle(cellOrder.begin(), cellOrder.end());
1381*35238bceSAndroid Build Coastguard Worker
1382*35238bceSAndroid Build Coastguard Worker data.resize(m_gridSize * m_gridSize * 6 * 2);
1383*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
1384*35238bceSAndroid Build Coastguard Worker {
1385*35238bceSAndroid Build Coastguard Worker const int cellNdx = cellOrder[ndx];
1386*35238bceSAndroid Build Coastguard Worker const int cellX = cellNdx % m_gridSize;
1387*35238bceSAndroid Build Coastguard Worker const int cellY = cellNdx / m_gridSize;
1388*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &cellColor = ((cellX + cellY) % 2 == 0) ? (green) : (yellow);
1389*35238bceSAndroid Build Coastguard Worker
1390*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1391*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 0) / float(m_gridSize), float(cellY + 0) / float(m_gridSize), 0.0f, 1.0f);
1392*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1393*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1394*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 1) / float(m_gridSize), float(cellY + 1) / float(m_gridSize), 0.0f, 1.0f);
1395*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1396*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1397*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 0) / float(m_gridSize), float(cellY + 1) / float(m_gridSize), 0.0f, 1.0f);
1398*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 2) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1399*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1400*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 0) / float(m_gridSize), float(cellY + 0) / float(m_gridSize), 0.0f, 1.0f);
1401*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 3) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1402*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1403*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 1) / float(m_gridSize), float(cellY + 0) / float(m_gridSize), 0.0f, 1.0f);
1404*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 4) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1405*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
1406*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(cellX + 1) / float(m_gridSize), float(cellY + 1) / float(m_gridSize), 0.0f, 1.0f);
1407*35238bceSAndroid Build Coastguard Worker data[(ndx * 6 + 5) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = cellColor;
1408*35238bceSAndroid Build Coastguard Worker }
1409*35238bceSAndroid Build Coastguard Worker }
1410*35238bceSAndroid Build Coastguard Worker
renderTestPattern(const IterationConfig & config)1411*35238bceSAndroid Build Coastguard Worker void GridRenderCase::renderTestPattern(const IterationConfig &config)
1412*35238bceSAndroid Build Coastguard Worker {
1413*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1414*35238bceSAndroid Build Coastguard Worker
1415*35238bceSAndroid Build Coastguard Worker setupRender(config);
1416*35238bceSAndroid Build Coastguard Worker
1417*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
1418*35238bceSAndroid Build Coastguard Worker {
1419*35238bceSAndroid Build Coastguard Worker const glw::GLint tessLevelPos = gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
1420*35238bceSAndroid Build Coastguard Worker const glw::GLfloat tessLevel = 2.8f; // will be rounded up
1421*35238bceSAndroid Build Coastguard Worker
1422*35238bceSAndroid Build Coastguard Worker TCU_CHECK(tessLevelPos != -1);
1423*35238bceSAndroid Build Coastguard Worker
1424*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel
1425*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1426*35238bceSAndroid Build Coastguard Worker
1427*35238bceSAndroid Build Coastguard Worker gl.uniform1f(tessLevelPos, tessLevel);
1428*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 3);
1429*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
1430*35238bceSAndroid Build Coastguard Worker }
1431*35238bceSAndroid Build Coastguard Worker
1432*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering grid." << tcu::TestLog::EndMessage;
1433*35238bceSAndroid Build Coastguard Worker
1434*35238bceSAndroid Build Coastguard Worker gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
1435*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
1436*35238bceSAndroid Build Coastguard Worker }
1437*35238bceSAndroid Build Coastguard Worker
verifyRenderResult(const IterationConfig & config)1438*35238bceSAndroid Build Coastguard Worker void GridRenderCase::verifyRenderResult(const IterationConfig &config)
1439*35238bceSAndroid Build Coastguard Worker {
1440*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1441*35238bceSAndroid Build Coastguard Worker const ProjectedBBox projectedBBox = projectBoundingBox(config.bbox);
1442*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportBBoxArea = getViewportBoundingBoxArea(projectedBBox, config.viewportSize);
1443*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportGridOuterArea =
1444*35238bceSAndroid Build Coastguard Worker getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_OUTWARDS);
1445*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportGridInnerArea =
1446*35238bceSAndroid Build Coastguard Worker getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
1447*35238bceSAndroid Build Coastguard Worker tcu::Surface viewportSurface(config.viewportSize.x(), config.viewportSize.y());
1448*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(config.viewportSize.x(), config.viewportSize.y());
1449*35238bceSAndroid Build Coastguard Worker bool anyError = false;
1450*35238bceSAndroid Build Coastguard Worker
1451*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
1452*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Projected bounding box: (clip space)\n"
1453*35238bceSAndroid Build Coastguard Worker << "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
1454*35238bceSAndroid Build Coastguard Worker << "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
1455*35238bceSAndroid Build Coastguard Worker << "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
1456*35238bceSAndroid Build Coastguard Worker << "In viewport coordinates:\n"
1457*35238bceSAndroid Build Coastguard Worker << "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
1458*35238bceSAndroid Build Coastguard Worker << "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
1459*35238bceSAndroid Build Coastguard Worker << "Verifying render results within the bounding box.\n"
1460*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1461*35238bceSAndroid Build Coastguard Worker else
1462*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying render result." << tcu::TestLog::EndMessage;
1463*35238bceSAndroid Build Coastguard Worker
1464*35238bceSAndroid Build Coastguard Worker if (m_fbo)
1465*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
1466*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(),
1467*35238bceSAndroid Build Coastguard Worker viewportSurface.getAccess());
1468*35238bceSAndroid Build Coastguard Worker
1469*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 0, 0, 255));
1470*35238bceSAndroid Build Coastguard Worker
1471*35238bceSAndroid Build Coastguard Worker for (int y = de::max(viewportBBoxArea.y(), 0); y < de::min(viewportBBoxArea.w(), config.viewportSize.y()); ++y)
1472*35238bceSAndroid Build Coastguard Worker for (int x = de::max(viewportBBoxArea.x(), 0); x < de::min(viewportBBoxArea.z(), config.viewportSize.x()); ++x)
1473*35238bceSAndroid Build Coastguard Worker {
1474*35238bceSAndroid Build Coastguard Worker const tcu::RGBA pixel = viewportSurface.getPixel(x, y);
1475*35238bceSAndroid Build Coastguard Worker const bool outsideGrid = x < viewportGridOuterArea.x() || y < viewportGridOuterArea.y() ||
1476*35238bceSAndroid Build Coastguard Worker x > viewportGridOuterArea.z() || y > viewportGridOuterArea.w();
1477*35238bceSAndroid Build Coastguard Worker const bool insideGrid = x > viewportGridInnerArea.x() && y > viewportGridInnerArea.y() &&
1478*35238bceSAndroid Build Coastguard Worker x < viewportGridInnerArea.z() && y < viewportGridInnerArea.w();
1479*35238bceSAndroid Build Coastguard Worker
1480*35238bceSAndroid Build Coastguard Worker bool error = false;
1481*35238bceSAndroid Build Coastguard Worker
1482*35238bceSAndroid Build Coastguard Worker if (outsideGrid)
1483*35238bceSAndroid Build Coastguard Worker {
1484*35238bceSAndroid Build Coastguard Worker // expect black
1485*35238bceSAndroid Build Coastguard Worker if (pixel.getRed() != 0 || pixel.getGreen() != 0 || pixel.getBlue() != 0)
1486*35238bceSAndroid Build Coastguard Worker error = true;
1487*35238bceSAndroid Build Coastguard Worker }
1488*35238bceSAndroid Build Coastguard Worker
1489*35238bceSAndroid Build Coastguard Worker else if (insideGrid)
1490*35238bceSAndroid Build Coastguard Worker {
1491*35238bceSAndroid Build Coastguard Worker // expect green, yellow or a combination of these
1492*35238bceSAndroid Build Coastguard Worker if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
1493*35238bceSAndroid Build Coastguard Worker error = true;
1494*35238bceSAndroid Build Coastguard Worker }
1495*35238bceSAndroid Build Coastguard Worker else
1496*35238bceSAndroid Build Coastguard Worker {
1497*35238bceSAndroid Build Coastguard Worker // boundary, allow anything
1498*35238bceSAndroid Build Coastguard Worker }
1499*35238bceSAndroid Build Coastguard Worker
1500*35238bceSAndroid Build Coastguard Worker if (error)
1501*35238bceSAndroid Build Coastguard Worker {
1502*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
1503*35238bceSAndroid Build Coastguard Worker anyError = true;
1504*35238bceSAndroid Build Coastguard Worker }
1505*35238bceSAndroid Build Coastguard Worker }
1506*35238bceSAndroid Build Coastguard Worker
1507*35238bceSAndroid Build Coastguard Worker if (anyError)
1508*35238bceSAndroid Build Coastguard Worker {
1509*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
1510*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
1511*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
1512*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
1513*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
1514*35238bceSAndroid Build Coastguard Worker
1515*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
1516*35238bceSAndroid Build Coastguard Worker }
1517*35238bceSAndroid Build Coastguard Worker else
1518*35238bceSAndroid Build Coastguard Worker {
1519*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result image ok." << tcu::TestLog::EndMessage
1520*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
1521*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
1522*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
1523*35238bceSAndroid Build Coastguard Worker }
1524*35238bceSAndroid Build Coastguard Worker }
1525*35238bceSAndroid Build Coastguard Worker
1526*35238bceSAndroid Build Coastguard Worker class LineRenderCase : public BBoxRenderCase
1527*35238bceSAndroid Build Coastguard Worker {
1528*35238bceSAndroid Build Coastguard Worker public:
1529*35238bceSAndroid Build Coastguard Worker enum
1530*35238bceSAndroid Build Coastguard Worker {
1531*35238bceSAndroid Build Coastguard Worker LINEFLAG_WIDE = 1u << FLAGBIT_USER_BIT, //!< use wide lines
1532*35238bceSAndroid Build Coastguard Worker };
1533*35238bceSAndroid Build Coastguard Worker
1534*35238bceSAndroid Build Coastguard Worker LineRenderCase(Context &context, const char *name, const char *description, uint32_t flags);
1535*35238bceSAndroid Build Coastguard Worker ~LineRenderCase(void);
1536*35238bceSAndroid Build Coastguard Worker
1537*35238bceSAndroid Build Coastguard Worker private:
1538*35238bceSAndroid Build Coastguard Worker enum
1539*35238bceSAndroid Build Coastguard Worker {
1540*35238bceSAndroid Build Coastguard Worker GREEN_COMPONENT_NDX = 1,
1541*35238bceSAndroid Build Coastguard Worker BLUE_COMPONENT_NDX = 2,
1542*35238bceSAndroid Build Coastguard Worker
1543*35238bceSAndroid Build Coastguard Worker SCAN_ROW_COMPONENT_NDX = GREEN_COMPONENT_NDX, // \note: scans are orthogonal to the line
1544*35238bceSAndroid Build Coastguard Worker SCAN_COL_COMPONENT_NDX = BLUE_COMPONENT_NDX,
1545*35238bceSAndroid Build Coastguard Worker };
1546*35238bceSAndroid Build Coastguard Worker
1547*35238bceSAndroid Build Coastguard Worker enum QueryDirection
1548*35238bceSAndroid Build Coastguard Worker {
1549*35238bceSAndroid Build Coastguard Worker DIRECTION_HORIZONTAL = 0,
1550*35238bceSAndroid Build Coastguard Worker DIRECTION_VERTICAL,
1551*35238bceSAndroid Build Coastguard Worker };
1552*35238bceSAndroid Build Coastguard Worker
1553*35238bceSAndroid Build Coastguard Worker enum ScanResult
1554*35238bceSAndroid Build Coastguard Worker {
1555*35238bceSAndroid Build Coastguard Worker SCANRESULT_NUM_LINES_OK_BIT = (1 << 0),
1556*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_OK_BIT = (1 << 1),
1557*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_WARN_BIT = (1 << 2),
1558*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_ERR_BIT = (1 << 3),
1559*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_CONT_OK_BIT = (1 << 4),
1560*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_CONT_ERR_BIT = (1 << 5),
1561*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_CONT_WARN_BIT = (1 << 6),
1562*35238bceSAndroid Build Coastguard Worker };
1563*35238bceSAndroid Build Coastguard Worker
1564*35238bceSAndroid Build Coastguard Worker void init(void);
1565*35238bceSAndroid Build Coastguard Worker
1566*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
1567*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
1568*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
1569*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
1570*35238bceSAndroid Build Coastguard Worker std::string genGeometrySource(void) const;
1571*35238bceSAndroid Build Coastguard Worker
1572*35238bceSAndroid Build Coastguard Worker IterationConfig generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const;
1573*35238bceSAndroid Build Coastguard Worker void getAttributeData(std::vector<tcu::Vec4> &data) const;
1574*35238bceSAndroid Build Coastguard Worker void renderTestPattern(const IterationConfig &config);
1575*35238bceSAndroid Build Coastguard Worker void verifyRenderResult(const IterationConfig &config);
1576*35238bceSAndroid Build Coastguard Worker
1577*35238bceSAndroid Build Coastguard Worker tcu::IVec2 getNumberOfLinesRange(int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize,
1578*35238bceSAndroid Build Coastguard Worker int viewportArea, QueryDirection queryDir) const;
1579*35238bceSAndroid Build Coastguard Worker uint8_t scanRow(const tcu::ConstPixelBufferAccess &access, int row, int rowBegin, int rowEnd, int rowViewportBegin,
1580*35238bceSAndroid Build Coastguard Worker int rowViewportEnd, const tcu::IVec2 &numLines, int &floodCounter) const;
1581*35238bceSAndroid Build Coastguard Worker uint8_t scanColumn(const tcu::ConstPixelBufferAccess &access, int column, int columnBegin, int columnEnd,
1582*35238bceSAndroid Build Coastguard Worker int columnViewportBegin, int columnViewportEnd, const tcu::IVec2 &numLines,
1583*35238bceSAndroid Build Coastguard Worker int &floodCounter) const;
1584*35238bceSAndroid Build Coastguard Worker bool checkAreaNumLines(const tcu::ConstPixelBufferAccess &access, const tcu::IVec4 &area, int &floodCounter,
1585*35238bceSAndroid Build Coastguard Worker int componentNdx, const tcu::IVec2 &numLines) const;
1586*35238bceSAndroid Build Coastguard Worker uint8_t checkLineContinuity(const tcu::ConstPixelBufferAccess &access, const tcu::IVec2 &begin,
1587*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &end, int componentNdx, int &messageLimitCounter) const;
1588*35238bceSAndroid Build Coastguard Worker tcu::IVec2 getNumMinimaMaxima(const tcu::ConstPixelBufferAccess &access, int componentNdx) const;
1589*35238bceSAndroid Build Coastguard Worker uint8_t checkLineWidths(const tcu::ConstPixelBufferAccess &access, const tcu::IVec2 &begin, const tcu::IVec2 &end,
1590*35238bceSAndroid Build Coastguard Worker int componentNdx, int &floodCounter) const;
1591*35238bceSAndroid Build Coastguard Worker void printLineWidthError(const tcu::IVec2 &pos, int detectedLineWidth, const tcu::IVec2 &lineWidthRange,
1592*35238bceSAndroid Build Coastguard Worker bool isHorizontal, int &floodCounter) const;
1593*35238bceSAndroid Build Coastguard Worker
1594*35238bceSAndroid Build Coastguard Worker const int m_patternSide;
1595*35238bceSAndroid Build Coastguard Worker const bool m_isWideLineCase;
1596*35238bceSAndroid Build Coastguard Worker const int m_wideLineLineWidth;
1597*35238bceSAndroid Build Coastguard Worker };
1598*35238bceSAndroid Build Coastguard Worker
LineRenderCase(Context & context,const char * name,const char * description,uint32_t flags)1599*35238bceSAndroid Build Coastguard Worker LineRenderCase::LineRenderCase(Context &context, const char *name, const char *description, uint32_t flags)
1600*35238bceSAndroid Build Coastguard Worker : BBoxRenderCase(context, name, description, 12, flags)
1601*35238bceSAndroid Build Coastguard Worker , m_patternSide(12)
1602*35238bceSAndroid Build Coastguard Worker , m_isWideLineCase((flags & LINEFLAG_WIDE) != 0)
1603*35238bceSAndroid Build Coastguard Worker , m_wideLineLineWidth(5)
1604*35238bceSAndroid Build Coastguard Worker {
1605*35238bceSAndroid Build Coastguard Worker }
1606*35238bceSAndroid Build Coastguard Worker
~LineRenderCase(void)1607*35238bceSAndroid Build Coastguard Worker LineRenderCase::~LineRenderCase(void)
1608*35238bceSAndroid Build Coastguard Worker {
1609*35238bceSAndroid Build Coastguard Worker }
1610*35238bceSAndroid Build Coastguard Worker
init(void)1611*35238bceSAndroid Build Coastguard Worker void LineRenderCase::init(void)
1612*35238bceSAndroid Build Coastguard Worker {
1613*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1614*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << "Rendering line pattern to "
1615*35238bceSAndroid Build Coastguard Worker << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
1616*35238bceSAndroid Build Coastguard Worker << "Vertical lines are green, horizontal lines blue. Using additive blending.\n"
1617*35238bceSAndroid Build Coastguard Worker << "Line segments are in random order, varying pattern size and location for each iteration.\n"
1618*35238bceSAndroid Build Coastguard Worker << "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
1619*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1620*35238bceSAndroid Build Coastguard Worker
1621*35238bceSAndroid Build Coastguard Worker if (m_isWideLineCase)
1622*35238bceSAndroid Build Coastguard Worker {
1623*35238bceSAndroid Build Coastguard Worker glw::GLfloat lineWidthRange[2] = {0.0f, 0.0f};
1624*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
1625*35238bceSAndroid Build Coastguard Worker
1626*35238bceSAndroid Build Coastguard Worker if (lineWidthRange[1] < (float)m_wideLineLineWidth)
1627*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires line width " + de::toString(m_wideLineLineWidth));
1628*35238bceSAndroid Build Coastguard Worker }
1629*35238bceSAndroid Build Coastguard Worker
1630*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::init();
1631*35238bceSAndroid Build Coastguard Worker }
1632*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const1633*35238bceSAndroid Build Coastguard Worker std::string LineRenderCase::genVertexSource(void) const
1634*35238bceSAndroid Build Coastguard Worker {
1635*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1636*35238bceSAndroid Build Coastguard Worker
1637*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1638*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
1639*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_color;\n"
1640*35238bceSAndroid Build Coastguard Worker "out highp vec4 vtx_color;\n"
1641*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1642*35238bceSAndroid Build Coastguard Worker "uniform highp float u_lineWidth;\n"
1643*35238bceSAndroid Build Coastguard Worker "\n";
1644*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
1645*35238bceSAndroid Build Coastguard Worker {
1646*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
1647*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
1648*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n"
1649*35238bceSAndroid Build Coastguard Worker "\n"
1650*35238bceSAndroid Build Coastguard Worker "flat out highp float v_"
1651*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1652*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize;\n"
1653*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1654*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1655*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
1656*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1657*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1658*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax;\n"
1659*35238bceSAndroid Build Coastguard Worker "\n";
1660*35238bceSAndroid Build Coastguard Worker }
1661*35238bceSAndroid Build Coastguard Worker buf << "void main()\n"
1662*35238bceSAndroid Build Coastguard Worker "{\n"
1663*35238bceSAndroid Build Coastguard Worker " highp vec2 patternOffset = u_posScale.xy;\n"
1664*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
1665*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
1666*35238bceSAndroid Build Coastguard Worker " vtx_color = a_color;\n";
1667*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
1668*35238bceSAndroid Build Coastguard Worker {
1669*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
1670*35238bceSAndroid Build Coastguard Worker buf << "\n"
1671*35238bceSAndroid Build Coastguard Worker " v_"
1672*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1673*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize = u_lineWidth;\n"
1674*35238bceSAndroid Build Coastguard Worker " v_"
1675*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1676*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin =\n"
1677*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
1678*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
1679*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
1680*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n"
1681*35238bceSAndroid Build Coastguard Worker " v_"
1682*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1683*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax =\n"
1684*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
1685*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
1686*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
1687*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n";
1688*35238bceSAndroid Build Coastguard Worker }
1689*35238bceSAndroid Build Coastguard Worker buf << "}\n";
1690*35238bceSAndroid Build Coastguard Worker
1691*35238bceSAndroid Build Coastguard Worker return buf.str();
1692*35238bceSAndroid Build Coastguard Worker }
1693*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const1694*35238bceSAndroid Build Coastguard Worker std::string LineRenderCase::genFragmentSource(void) const
1695*35238bceSAndroid Build Coastguard Worker {
1696*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasGeometryStage) ? ("geo_color") :
1697*35238bceSAndroid Build Coastguard Worker (m_hasTessellationStage) ? ("tess_color") :
1698*35238bceSAndroid Build Coastguard Worker ("vtx_color");
1699*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1700*35238bceSAndroid Build Coastguard Worker
1701*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1702*35238bceSAndroid Build Coastguard Worker "in mediump vec4 "
1703*35238bceSAndroid Build Coastguard Worker << colorInputName
1704*35238bceSAndroid Build Coastguard Worker << ";\n"
1705*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
1706*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
1707*35238bceSAndroid Build Coastguard Worker << "\n"
1708*35238bceSAndroid Build Coastguard Worker "void main()\n"
1709*35238bceSAndroid Build Coastguard Worker "{\n"
1710*35238bceSAndroid Build Coastguard Worker " mediump vec4 baseColor = "
1711*35238bceSAndroid Build Coastguard Worker << colorInputName
1712*35238bceSAndroid Build Coastguard Worker << ";\n"
1713*35238bceSAndroid Build Coastguard Worker " mediump float redChannel;\n"
1714*35238bceSAndroid Build Coastguard Worker " if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
1715*35238bceSAndroid Build Coastguard Worker " redChannel = 0.0;\n"
1716*35238bceSAndroid Build Coastguard Worker " else\n"
1717*35238bceSAndroid Build Coastguard Worker " redChannel = 1.0;\n"
1718*35238bceSAndroid Build Coastguard Worker " o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
1719*35238bceSAndroid Build Coastguard Worker "}\n";
1720*35238bceSAndroid Build Coastguard Worker
1721*35238bceSAndroid Build Coastguard Worker return buf.str();
1722*35238bceSAndroid Build Coastguard Worker }
1723*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const1724*35238bceSAndroid Build Coastguard Worker std::string LineRenderCase::genTessellationControlSource(void) const
1725*35238bceSAndroid Build Coastguard Worker {
1726*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1727*35238bceSAndroid Build Coastguard Worker
1728*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1729*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
1730*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
1731*35238bceSAndroid Build Coastguard Worker "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
1732*35238bceSAndroid Build Coastguard Worker "layout(vertices=2) out;"
1733*35238bceSAndroid Build Coastguard Worker "\n"
1734*35238bceSAndroid Build Coastguard Worker "in highp vec4 vtx_color[];\n"
1735*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_ctrl_color[];\n"
1736*35238bceSAndroid Build Coastguard Worker "uniform highp float u_tessellationLevel;\n"
1737*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1738*35238bceSAndroid Build Coastguard Worker "uniform highp float u_lineWidth;\n";
1739*35238bceSAndroid Build Coastguard Worker
1740*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
1741*35238bceSAndroid Build Coastguard Worker {
1742*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
1743*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n";
1744*35238bceSAndroid Build Coastguard Worker }
1745*35238bceSAndroid Build Coastguard Worker
1746*35238bceSAndroid Build Coastguard Worker buf << "patch out highp float vp_bbox_expansionSize;\n"
1747*35238bceSAndroid Build Coastguard Worker "patch out highp vec3 vp_bbox_clipMin;\n"
1748*35238bceSAndroid Build Coastguard Worker "patch out highp vec3 vp_bbox_clipMax;\n";
1749*35238bceSAndroid Build Coastguard Worker
1750*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
1751*35238bceSAndroid Build Coastguard Worker {
1752*35238bceSAndroid Build Coastguard Worker buf << "\n";
1753*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
1754*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
1755*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
1756*35238bceSAndroid Build Coastguard Worker
1757*35238bceSAndroid Build Coastguard Worker buf << "vec4 transformVec(in highp vec4 p)\n"
1758*35238bceSAndroid Build Coastguard Worker "{\n"
1759*35238bceSAndroid Build Coastguard Worker " return "
1760*35238bceSAndroid Build Coastguard Worker << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)"))
1761*35238bceSAndroid Build Coastguard Worker << ";\n"
1762*35238bceSAndroid Build Coastguard Worker "}\n";
1763*35238bceSAndroid Build Coastguard Worker }
1764*35238bceSAndroid Build Coastguard Worker
1765*35238bceSAndroid Build Coastguard Worker buf << "\n"
1766*35238bceSAndroid Build Coastguard Worker "void main()\n"
1767*35238bceSAndroid Build Coastguard Worker "{\n"
1768*35238bceSAndroid Build Coastguard Worker " // convert to nonsensical coordinates, just in case\n"
1769*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
1770*35238bceSAndroid Build Coastguard Worker " tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
1771*35238bceSAndroid Build Coastguard Worker "\n"
1772*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 0.8; // will be rounded up to 1\n"
1773*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_tessellationLevel;\n";
1774*35238bceSAndroid Build Coastguard Worker
1775*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
1776*35238bceSAndroid Build Coastguard Worker {
1777*35238bceSAndroid Build Coastguard Worker buf << "\n"
1778*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = min(transformVec(gl_in[0].gl_Position),\n"
1779*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[1].gl_Position));\n"
1780*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = max(transformVec(gl_in[0].gl_Position),\n"
1781*35238bceSAndroid Build Coastguard Worker " transformVec(gl_in[1].gl_Position));\n";
1782*35238bceSAndroid Build Coastguard Worker }
1783*35238bceSAndroid Build Coastguard Worker else
1784*35238bceSAndroid Build Coastguard Worker {
1785*35238bceSAndroid Build Coastguard Worker buf << "\n"
1786*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = u_primitiveBBoxMin;\n"
1787*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = u_primitiveBBoxMax;\n";
1788*35238bceSAndroid Build Coastguard Worker }
1789*35238bceSAndroid Build Coastguard Worker
1790*35238bceSAndroid Build Coastguard Worker if (!m_useGlobalState)
1791*35238bceSAndroid Build Coastguard Worker buf << "\n"
1792*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
1793*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";
1794*35238bceSAndroid Build Coastguard Worker
1795*35238bceSAndroid Build Coastguard Worker buf << " vp_bbox_expansionSize = u_lineWidth;\n"
1796*35238bceSAndroid Build Coastguard Worker " vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
1797*35238bceSAndroid Build Coastguard Worker " vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
1798*35238bceSAndroid Build Coastguard Worker " vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
1799*35238bceSAndroid Build Coastguard Worker " vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
1800*35238bceSAndroid Build Coastguard Worker "}\n";
1801*35238bceSAndroid Build Coastguard Worker
1802*35238bceSAndroid Build Coastguard Worker return buf.str();
1803*35238bceSAndroid Build Coastguard Worker }
1804*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const1805*35238bceSAndroid Build Coastguard Worker std::string LineRenderCase::genTessellationEvaluationSource(void) const
1806*35238bceSAndroid Build Coastguard Worker {
1807*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1808*35238bceSAndroid Build Coastguard Worker
1809*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1810*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
1811*35238bceSAndroid Build Coastguard Worker "layout(isolines) in;"
1812*35238bceSAndroid Build Coastguard Worker "\n"
1813*35238bceSAndroid Build Coastguard Worker "in highp vec4 tess_ctrl_color[];\n"
1814*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_color;\n"
1815*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1816*35238bceSAndroid Build Coastguard Worker "\n"
1817*35238bceSAndroid Build Coastguard Worker "patch in highp float vp_bbox_expansionSize;\n"
1818*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMin;\n"
1819*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMax;\n"
1820*35238bceSAndroid Build Coastguard Worker "flat out highp float v_"
1821*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1822*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize;\n"
1823*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1824*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1825*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
1826*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
1827*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "") << "bbox_clipMax;\n"
1828*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_Y)
1829*35238bceSAndroid Build Coastguard Worker << "void main()\n"
1830*35238bceSAndroid Build Coastguard Worker "{\n"
1831*35238bceSAndroid Build Coastguard Worker " // non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
1832*35238bceSAndroid Build Coastguard Worker " gl_Position = mirrorY(mix(gl_in[0].gl_Position.zwyx, gl_in[1].gl_Position.zwyx, gl_TessCoord.x));\n"
1833*35238bceSAndroid Build Coastguard Worker " tess_color = tess_ctrl_color[0];\n"
1834*35238bceSAndroid Build Coastguard Worker " v_"
1835*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1836*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize = vp_bbox_expansionSize;\n"
1837*35238bceSAndroid Build Coastguard Worker " v_"
1838*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1839*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin = vp_bbox_clipMin;\n"
1840*35238bceSAndroid Build Coastguard Worker " v_"
1841*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
1842*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax = vp_bbox_clipMax;\n"
1843*35238bceSAndroid Build Coastguard Worker "}\n";
1844*35238bceSAndroid Build Coastguard Worker
1845*35238bceSAndroid Build Coastguard Worker return buf.str();
1846*35238bceSAndroid Build Coastguard Worker }
1847*35238bceSAndroid Build Coastguard Worker
genGeometrySource(void) const1848*35238bceSAndroid Build Coastguard Worker std::string LineRenderCase::genGeometrySource(void) const
1849*35238bceSAndroid Build Coastguard Worker {
1850*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
1851*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1852*35238bceSAndroid Build Coastguard Worker
1853*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1854*35238bceSAndroid Build Coastguard Worker "${GEOMETRY_SHADER_REQUIRE}\n"
1855*35238bceSAndroid Build Coastguard Worker "layout(lines) in;\n"
1856*35238bceSAndroid Build Coastguard Worker "layout(max_vertices=5, line_strip) out;\n"
1857*35238bceSAndroid Build Coastguard Worker "\n"
1858*35238bceSAndroid Build Coastguard Worker "in highp vec4 "
1859*35238bceSAndroid Build Coastguard Worker << colorInputName
1860*35238bceSAndroid Build Coastguard Worker << "[2];\n"
1861*35238bceSAndroid Build Coastguard Worker "out highp vec4 geo_color;\n"
1862*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
1863*35238bceSAndroid Build Coastguard Worker "\n"
1864*35238bceSAndroid Build Coastguard Worker "\n"
1865*35238bceSAndroid Build Coastguard Worker "flat in highp float v_geo_bbox_expansionSize[2];\n"
1866*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMin[2];\n"
1867*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMax[2];\n"
1868*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMin;\n"
1869*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMax;\n"
1870*35238bceSAndroid Build Coastguard Worker "flat out highp float v_bbox_expansionSize;\n"
1871*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_X)
1872*35238bceSAndroid Build Coastguard Worker << "\n"
1873*35238bceSAndroid Build Coastguard Worker "void setVisualizationVaryings()\n"
1874*35238bceSAndroid Build Coastguard Worker "{\n"
1875*35238bceSAndroid Build Coastguard Worker " v_bbox_expansionSize = v_geo_bbox_expansionSize[0];\n"
1876*35238bceSAndroid Build Coastguard Worker " v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
1877*35238bceSAndroid Build Coastguard Worker " v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
1878*35238bceSAndroid Build Coastguard Worker "}\n"
1879*35238bceSAndroid Build Coastguard Worker "void main()\n"
1880*35238bceSAndroid Build Coastguard Worker "{\n"
1881*35238bceSAndroid Build Coastguard Worker " // Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
1882*35238bceSAndroid Build Coastguard Worker " highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
1883*35238bceSAndroid Build Coastguard Worker " highp vec4 p1 = mirrorX(gl_in[1].gl_Position);\n"
1884*35238bceSAndroid Build Coastguard Worker " highp vec4 lineColor = "
1885*35238bceSAndroid Build Coastguard Worker << colorInputName
1886*35238bceSAndroid Build Coastguard Worker << "[0];\n"
1887*35238bceSAndroid Build Coastguard Worker "\n"
1888*35238bceSAndroid Build Coastguard Worker " // output two separate primitives, just in case\n"
1889*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(p0, p1, 0.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
1890*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
1891*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1892*35238bceSAndroid Build Coastguard Worker "\n"
1893*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(p0, p1, 0.33); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
1894*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(p0, p1, 0.67); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
1895*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(p0, p1, 1.00); geo_color = lineColor; setVisualizationVaryings(); EmitVertex();\n"
1896*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1897*35238bceSAndroid Build Coastguard Worker "}\n";
1898*35238bceSAndroid Build Coastguard Worker
1899*35238bceSAndroid Build Coastguard Worker return buf.str();
1900*35238bceSAndroid Build Coastguard Worker }
1901*35238bceSAndroid Build Coastguard Worker
generateConfig(int iteration,const tcu::IVec2 & renderTargetSize) const1902*35238bceSAndroid Build Coastguard Worker LineRenderCase::IterationConfig LineRenderCase::generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const
1903*35238bceSAndroid Build Coastguard Worker {
1904*35238bceSAndroid Build Coastguard Worker const int numMaxAttempts = 128;
1905*35238bceSAndroid Build Coastguard Worker
1906*35238bceSAndroid Build Coastguard Worker // Avoid too narrow viewports, lines could merge together. Require viewport is at least 2.5x the size of the line bodies.
1907*35238bceSAndroid Build Coastguard Worker for (int attemptNdx = 0; attemptNdx < numMaxAttempts; ++attemptNdx)
1908*35238bceSAndroid Build Coastguard Worker {
1909*35238bceSAndroid Build Coastguard Worker const IterationConfig &config =
1910*35238bceSAndroid Build Coastguard Worker generateRandomConfig((0xDEDEDEu * (uint32_t)iteration) ^ (0xABAB13 * attemptNdx), renderTargetSize);
1911*35238bceSAndroid Build Coastguard Worker
1912*35238bceSAndroid Build Coastguard Worker if ((float)config.viewportSize.x() * (config.patternSize.x() * 0.5f) >
1913*35238bceSAndroid Build Coastguard Worker 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth &&
1914*35238bceSAndroid Build Coastguard Worker (float)config.viewportSize.y() * (config.patternSize.y() * 0.5f) >
1915*35238bceSAndroid Build Coastguard Worker 2.5f * (float)m_patternSide * (float)m_wideLineLineWidth)
1916*35238bceSAndroid Build Coastguard Worker {
1917*35238bceSAndroid Build Coastguard Worker return config;
1918*35238bceSAndroid Build Coastguard Worker }
1919*35238bceSAndroid Build Coastguard Worker }
1920*35238bceSAndroid Build Coastguard Worker
1921*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1922*35238bceSAndroid Build Coastguard Worker return IterationConfig();
1923*35238bceSAndroid Build Coastguard Worker }
1924*35238bceSAndroid Build Coastguard Worker
getAttributeData(std::vector<tcu::Vec4> & data) const1925*35238bceSAndroid Build Coastguard Worker void LineRenderCase::getAttributeData(std::vector<tcu::Vec4> &data) const
1926*35238bceSAndroid Build Coastguard Worker {
1927*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1928*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
1929*35238bceSAndroid Build Coastguard Worker std::vector<int> cellOrder(m_patternSide * m_patternSide * 2);
1930*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xDE12345);
1931*35238bceSAndroid Build Coastguard Worker
1932*35238bceSAndroid Build Coastguard Worker // generate crosshatch pattern with segments in random order
1933*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
1934*35238bceSAndroid Build Coastguard Worker cellOrder[ndx] = ndx;
1935*35238bceSAndroid Build Coastguard Worker rnd.shuffle(cellOrder.begin(), cellOrder.end());
1936*35238bceSAndroid Build Coastguard Worker
1937*35238bceSAndroid Build Coastguard Worker data.resize(cellOrder.size() * 4);
1938*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
1939*35238bceSAndroid Build Coastguard Worker {
1940*35238bceSAndroid Build Coastguard Worker const int segmentID = cellOrder[ndx];
1941*35238bceSAndroid Build Coastguard Worker const int direction = segmentID & 0x01;
1942*35238bceSAndroid Build Coastguard Worker const int majorCoord = (segmentID >> 1) / m_patternSide;
1943*35238bceSAndroid Build Coastguard Worker const int minorCoord = (segmentID >> 1) % m_patternSide;
1944*35238bceSAndroid Build Coastguard Worker
1945*35238bceSAndroid Build Coastguard Worker if (direction)
1946*35238bceSAndroid Build Coastguard Worker {
1947*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(
1948*35238bceSAndroid Build Coastguard Worker float(minorCoord) / float(m_patternSide), float(majorCoord) / float(m_patternSide), 0.0f, 1.0f);
1949*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
1950*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(
1951*35238bceSAndroid Build Coastguard Worker float(minorCoord) / float(m_patternSide), float(majorCoord + 1) / float(m_patternSide), 0.0f, 1.0f);
1952*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
1953*35238bceSAndroid Build Coastguard Worker }
1954*35238bceSAndroid Build Coastguard Worker else
1955*35238bceSAndroid Build Coastguard Worker {
1956*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(
1957*35238bceSAndroid Build Coastguard Worker float(majorCoord) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
1958*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 0) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
1959*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] = tcu::Vec4(
1960*35238bceSAndroid Build Coastguard Worker float(majorCoord + 1) / float(m_patternSide), float(minorCoord) / float(m_patternSide), 0.0f, 1.0f);
1961*35238bceSAndroid Build Coastguard Worker data[(ndx * 2 + 1) * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
1962*35238bceSAndroid Build Coastguard Worker }
1963*35238bceSAndroid Build Coastguard Worker }
1964*35238bceSAndroid Build Coastguard Worker }
1965*35238bceSAndroid Build Coastguard Worker
renderTestPattern(const IterationConfig & config)1966*35238bceSAndroid Build Coastguard Worker void LineRenderCase::renderTestPattern(const IterationConfig &config)
1967*35238bceSAndroid Build Coastguard Worker {
1968*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1969*35238bceSAndroid Build Coastguard Worker
1970*35238bceSAndroid Build Coastguard Worker setupRender(config);
1971*35238bceSAndroid Build Coastguard Worker
1972*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
1973*35238bceSAndroid Build Coastguard Worker {
1974*35238bceSAndroid Build Coastguard Worker const glw::GLint tessLevelPos = gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
1975*35238bceSAndroid Build Coastguard Worker const glw::GLfloat tessLevel = 2.8f; // will be rounded up
1976*35238bceSAndroid Build Coastguard Worker
1977*35238bceSAndroid Build Coastguard Worker TCU_CHECK(tessLevelPos != -1);
1978*35238bceSAndroid Build Coastguard Worker
1979*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel
1980*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1981*35238bceSAndroid Build Coastguard Worker
1982*35238bceSAndroid Build Coastguard Worker gl.uniform1f(tessLevelPos, tessLevel);
1983*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 2);
1984*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
1985*35238bceSAndroid Build Coastguard Worker }
1986*35238bceSAndroid Build Coastguard Worker
1987*35238bceSAndroid Build Coastguard Worker if (m_isWideLineCase)
1988*35238bceSAndroid Build Coastguard Worker gl.lineWidth((float)m_wideLineLineWidth);
1989*35238bceSAndroid Build Coastguard Worker
1990*35238bceSAndroid Build Coastguard Worker gl.uniform1f(gl.getUniformLocation(m_program->getProgram(), "u_lineWidth"),
1991*35238bceSAndroid Build Coastguard Worker (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f));
1992*35238bceSAndroid Build Coastguard Worker
1993*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;
1994*35238bceSAndroid Build Coastguard Worker
1995*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
1996*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_ONE, GL_ONE);
1997*35238bceSAndroid Build Coastguard Worker gl.blendEquation(GL_FUNC_ADD);
1998*35238bceSAndroid Build Coastguard Worker
1999*35238bceSAndroid Build Coastguard Worker gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_LINES), 0, m_patternSide * m_patternSide * 2 * 2);
2000*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
2001*35238bceSAndroid Build Coastguard Worker }
2002*35238bceSAndroid Build Coastguard Worker
verifyRenderResult(const IterationConfig & config)2003*35238bceSAndroid Build Coastguard Worker void LineRenderCase::verifyRenderResult(const IterationConfig &config)
2004*35238bceSAndroid Build Coastguard Worker {
2005*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2006*35238bceSAndroid Build Coastguard Worker const bool isMsaa = m_context.getRenderTarget().getNumSamples() > 1;
2007*35238bceSAndroid Build Coastguard Worker const ProjectedBBox projectedBBox = projectBoundingBox(config.bbox);
2008*35238bceSAndroid Build Coastguard Worker const float lineWidth = (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
2009*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportBBoxArea = getViewportBoundingBoxArea(projectedBBox, config.viewportSize, lineWidth);
2010*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportPatternArea =
2011*35238bceSAndroid Build Coastguard Worker getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
2012*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 expectedHorizontalLines =
2013*35238bceSAndroid Build Coastguard Worker getNumberOfLinesRange(viewportBBoxArea.y(), viewportBBoxArea.w(), config.patternPos.y(), config.patternSize.y(),
2014*35238bceSAndroid Build Coastguard Worker config.viewportSize.y(), DIRECTION_VERTICAL);
2015*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 expectedVerticalLines =
2016*35238bceSAndroid Build Coastguard Worker getNumberOfLinesRange(viewportBBoxArea.x(), viewportBBoxArea.z(), config.patternPos.x(), config.patternSize.x(),
2017*35238bceSAndroid Build Coastguard Worker config.viewportSize.x(), DIRECTION_HORIZONTAL);
2018*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 verificationArea = tcu::IVec4(de::max(viewportBBoxArea.x(), 0), de::max(viewportBBoxArea.y(), 0),
2019*35238bceSAndroid Build Coastguard Worker de::min(viewportBBoxArea.z(), config.viewportSize.x()),
2020*35238bceSAndroid Build Coastguard Worker de::min(viewportBBoxArea.w(), config.viewportSize.y()));
2021*35238bceSAndroid Build Coastguard Worker
2022*35238bceSAndroid Build Coastguard Worker tcu::Surface viewportSurface(config.viewportSize.x(), config.viewportSize.y());
2023*35238bceSAndroid Build Coastguard Worker int messageLimitCounter = 8;
2024*35238bceSAndroid Build Coastguard Worker
2025*35238bceSAndroid Build Coastguard Worker enum ScanResultCodes
2026*35238bceSAndroid Build Coastguard Worker {
2027*35238bceSAndroid Build Coastguard Worker SCANRESULT_NUM_LINES_ERR = 0,
2028*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_MSAA = 1,
2029*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_WARN = 2,
2030*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_WIDTH_ERR = 3,
2031*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_CONT_ERR = 4,
2032*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_CONT_WARN = 5,
2033*35238bceSAndroid Build Coastguard Worker SCANRESULT_LINE_LAST
2034*35238bceSAndroid Build Coastguard Worker };
2035*35238bceSAndroid Build Coastguard Worker
2036*35238bceSAndroid Build Coastguard Worker int rowScanResult[SCANRESULT_LINE_LAST] = {0, 0, 0, 0, 0, 0};
2037*35238bceSAndroid Build Coastguard Worker int columnScanResult[SCANRESULT_LINE_LAST] = {0, 0, 0, 0, 0, 0};
2038*35238bceSAndroid Build Coastguard Worker bool anyError = false;
2039*35238bceSAndroid Build Coastguard Worker bool msaaRelaxationRequired = false;
2040*35238bceSAndroid Build Coastguard Worker bool hwIssueRelaxationRequired = false;
2041*35238bceSAndroid Build Coastguard Worker
2042*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
2043*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Projected bounding box: (clip space)\n"
2044*35238bceSAndroid Build Coastguard Worker << "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
2045*35238bceSAndroid Build Coastguard Worker << "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
2046*35238bceSAndroid Build Coastguard Worker << "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
2047*35238bceSAndroid Build Coastguard Worker << "In viewport coordinates:\n"
2048*35238bceSAndroid Build Coastguard Worker << "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
2049*35238bceSAndroid Build Coastguard Worker << "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
2050*35238bceSAndroid Build Coastguard Worker << "Verifying render results within the bounding box:\n"
2051*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2052*35238bceSAndroid Build Coastguard Worker else
2053*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying render result:" << tcu::TestLog::EndMessage;
2054*35238bceSAndroid Build Coastguard Worker
2055*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2056*35238bceSAndroid Build Coastguard Worker << "\tCalculating number of horizontal and vertical lines within the bounding box, expecting:\n"
2057*35238bceSAndroid Build Coastguard Worker << "\t[" << expectedHorizontalLines.x() << ", " << expectedHorizontalLines.y()
2058*35238bceSAndroid Build Coastguard Worker << "] horizontal lines.\n"
2059*35238bceSAndroid Build Coastguard Worker << "\t[" << expectedVerticalLines.x() << ", " << expectedVerticalLines.y()
2060*35238bceSAndroid Build Coastguard Worker << "] vertical lines.\n"
2061*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2062*35238bceSAndroid Build Coastguard Worker
2063*35238bceSAndroid Build Coastguard Worker if (m_fbo)
2064*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
2065*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(),
2066*35238bceSAndroid Build Coastguard Worker viewportSurface.getAccess());
2067*35238bceSAndroid Build Coastguard Worker
2068*35238bceSAndroid Build Coastguard Worker // scan rows
2069*35238bceSAndroid Build Coastguard Worker for (int y = de::max(verificationArea.y(), viewportPatternArea.y());
2070*35238bceSAndroid Build Coastguard Worker y < de::min(verificationArea.w(), viewportPatternArea.w()); ++y)
2071*35238bceSAndroid Build Coastguard Worker {
2072*35238bceSAndroid Build Coastguard Worker const uint8_t result =
2073*35238bceSAndroid Build Coastguard Worker scanRow(viewportSurface.getAccess(), y, verificationArea.x(), verificationArea.z(),
2074*35238bceSAndroid Build Coastguard Worker de::max(verificationArea.x(), viewportPatternArea.x()),
2075*35238bceSAndroid Build Coastguard Worker de::min(verificationArea.z(), viewportPatternArea.z()), expectedVerticalLines, messageLimitCounter);
2076*35238bceSAndroid Build Coastguard Worker
2077*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
2078*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_NUM_LINES_ERR]++;
2079*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
2080*35238bceSAndroid Build Coastguard Worker {
2081*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
2082*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_LINE_CONT_WARN]++;
2083*35238bceSAndroid Build Coastguard Worker else
2084*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_LINE_CONT_ERR]++;
2085*35238bceSAndroid Build Coastguard Worker }
2086*35238bceSAndroid Build Coastguard Worker else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
2087*35238bceSAndroid Build Coastguard Worker {
2088*35238bceSAndroid Build Coastguard Worker if (m_isWideLineCase && isMsaa)
2089*35238bceSAndroid Build Coastguard Worker {
2090*35238bceSAndroid Build Coastguard Worker // multisampled wide lines might not be supported
2091*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
2092*35238bceSAndroid Build Coastguard Worker }
2093*35238bceSAndroid Build Coastguard Worker else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 && (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
2094*35238bceSAndroid Build Coastguard Worker {
2095*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
2096*35238bceSAndroid Build Coastguard Worker }
2097*35238bceSAndroid Build Coastguard Worker else
2098*35238bceSAndroid Build Coastguard Worker rowScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
2099*35238bceSAndroid Build Coastguard Worker }
2100*35238bceSAndroid Build Coastguard Worker }
2101*35238bceSAndroid Build Coastguard Worker
2102*35238bceSAndroid Build Coastguard Worker // scan columns
2103*35238bceSAndroid Build Coastguard Worker for (int x = de::max(verificationArea.x(), viewportPatternArea.x());
2104*35238bceSAndroid Build Coastguard Worker x < de::min(verificationArea.z(), viewportPatternArea.z()); ++x)
2105*35238bceSAndroid Build Coastguard Worker {
2106*35238bceSAndroid Build Coastguard Worker const uint8_t result = scanColumn(viewportSurface.getAccess(), x, verificationArea.y(), verificationArea.w(),
2107*35238bceSAndroid Build Coastguard Worker de::min(verificationArea.y(), viewportPatternArea.y()),
2108*35238bceSAndroid Build Coastguard Worker de::min(verificationArea.w(), viewportPatternArea.w()),
2109*35238bceSAndroid Build Coastguard Worker expectedHorizontalLines, messageLimitCounter);
2110*35238bceSAndroid Build Coastguard Worker
2111*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
2112*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_NUM_LINES_ERR]++;
2113*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
2114*35238bceSAndroid Build Coastguard Worker {
2115*35238bceSAndroid Build Coastguard Worker if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
2116*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_LINE_CONT_WARN]++;
2117*35238bceSAndroid Build Coastguard Worker else
2118*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_LINE_CONT_ERR]++;
2119*35238bceSAndroid Build Coastguard Worker }
2120*35238bceSAndroid Build Coastguard Worker else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
2121*35238bceSAndroid Build Coastguard Worker {
2122*35238bceSAndroid Build Coastguard Worker if (m_isWideLineCase && isMsaa)
2123*35238bceSAndroid Build Coastguard Worker {
2124*35238bceSAndroid Build Coastguard Worker // multisampled wide lines might not be supported
2125*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
2126*35238bceSAndroid Build Coastguard Worker }
2127*35238bceSAndroid Build Coastguard Worker else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 && (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
2128*35238bceSAndroid Build Coastguard Worker {
2129*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
2130*35238bceSAndroid Build Coastguard Worker }
2131*35238bceSAndroid Build Coastguard Worker else
2132*35238bceSAndroid Build Coastguard Worker columnScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
2133*35238bceSAndroid Build Coastguard Worker }
2134*35238bceSAndroid Build Coastguard Worker }
2135*35238bceSAndroid Build Coastguard Worker
2136*35238bceSAndroid Build Coastguard Worker if (columnScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0)
2137*35238bceSAndroid Build Coastguard Worker anyError = true;
2138*35238bceSAndroid Build Coastguard Worker else if (columnScanResult[SCANRESULT_LINE_CONT_ERR] != 0 || rowScanResult[SCANRESULT_LINE_CONT_ERR] != 0)
2139*35238bceSAndroid Build Coastguard Worker anyError = true;
2140*35238bceSAndroid Build Coastguard Worker else if (columnScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0)
2141*35238bceSAndroid Build Coastguard Worker msaaRelaxationRequired = true;
2142*35238bceSAndroid Build Coastguard Worker else if (columnScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0)
2143*35238bceSAndroid Build Coastguard Worker hwIssueRelaxationRequired = true;
2144*35238bceSAndroid Build Coastguard Worker else if (columnScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
2145*35238bceSAndroid Build Coastguard Worker {
2146*35238bceSAndroid Build Coastguard Worker // found missing lines in a columnw and row line continuity check reported a warning (not an error) -> line width precision issue
2147*35238bceSAndroid Build Coastguard Worker if (rowScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && rowScanResult[SCANRESULT_LINE_CONT_WARN])
2148*35238bceSAndroid Build Coastguard Worker hwIssueRelaxationRequired = true;
2149*35238bceSAndroid Build Coastguard Worker else
2150*35238bceSAndroid Build Coastguard Worker anyError = true;
2151*35238bceSAndroid Build Coastguard Worker }
2152*35238bceSAndroid Build Coastguard Worker else if (rowScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
2153*35238bceSAndroid Build Coastguard Worker {
2154*35238bceSAndroid Build Coastguard Worker // found missing lines in a row and column line continuity check reported a warning (not an error) -> line width precision issue
2155*35238bceSAndroid Build Coastguard Worker if (columnScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && columnScanResult[SCANRESULT_LINE_CONT_WARN])
2156*35238bceSAndroid Build Coastguard Worker hwIssueRelaxationRequired = true;
2157*35238bceSAndroid Build Coastguard Worker else
2158*35238bceSAndroid Build Coastguard Worker anyError = true;
2159*35238bceSAndroid Build Coastguard Worker }
2160*35238bceSAndroid Build Coastguard Worker
2161*35238bceSAndroid Build Coastguard Worker if (anyError || msaaRelaxationRequired || hwIssueRelaxationRequired)
2162*35238bceSAndroid Build Coastguard Worker {
2163*35238bceSAndroid Build Coastguard Worker if (messageLimitCounter < 0)
2164*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-messageLimitCounter)
2165*35238bceSAndroid Build Coastguard Worker << " row/column error descriptions." << tcu::TestLog::EndMessage;
2166*35238bceSAndroid Build Coastguard Worker
2167*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
2168*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
2169*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
2170*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
2171*35238bceSAndroid Build Coastguard Worker
2172*35238bceSAndroid Build Coastguard Worker if (anyError)
2173*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2174*35238bceSAndroid Build Coastguard Worker else if (hwIssueRelaxationRequired)
2175*35238bceSAndroid Build Coastguard Worker {
2176*35238bceSAndroid Build Coastguard Worker // Line width hw issue
2177*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Line width verification failed");
2178*35238bceSAndroid Build Coastguard Worker }
2179*35238bceSAndroid Build Coastguard Worker else
2180*35238bceSAndroid Build Coastguard Worker {
2181*35238bceSAndroid Build Coastguard Worker // MSAA wide lines are optional
2182*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Multisampled wide line verification failed");
2183*35238bceSAndroid Build Coastguard Worker }
2184*35238bceSAndroid Build Coastguard Worker }
2185*35238bceSAndroid Build Coastguard Worker else
2186*35238bceSAndroid Build Coastguard Worker {
2187*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result image ok." << tcu::TestLog::EndMessage
2188*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
2189*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
2190*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
2191*35238bceSAndroid Build Coastguard Worker }
2192*35238bceSAndroid Build Coastguard Worker }
2193*35238bceSAndroid Build Coastguard Worker
getNumberOfLinesRange(int queryAreaBegin,int queryAreaEnd,float patternStart,float patternSize,int viewportArea,QueryDirection queryDir) const2194*35238bceSAndroid Build Coastguard Worker tcu::IVec2 LineRenderCase::getNumberOfLinesRange(int queryAreaBegin, int queryAreaEnd, float patternStart,
2195*35238bceSAndroid Build Coastguard Worker float patternSize, int viewportArea, QueryDirection queryDir) const
2196*35238bceSAndroid Build Coastguard Worker {
2197*35238bceSAndroid Build Coastguard Worker // pattern is not symmetric due to mirroring
2198*35238bceSAndroid Build Coastguard Worker const int patternStartNdx = (queryDir == DIRECTION_HORIZONTAL) ? ((m_hasGeometryStage) ? (1) : (0)) :
2199*35238bceSAndroid Build Coastguard Worker ((m_hasTessellationStage) ? (1) : (0));
2200*35238bceSAndroid Build Coastguard Worker const int patternEndNdx = patternStartNdx + m_patternSide;
2201*35238bceSAndroid Build Coastguard Worker
2202*35238bceSAndroid Build Coastguard Worker int numLinesMin = 0;
2203*35238bceSAndroid Build Coastguard Worker int numLinesMax = 0;
2204*35238bceSAndroid Build Coastguard Worker
2205*35238bceSAndroid Build Coastguard Worker for (int lineNdx = patternStartNdx; lineNdx < patternEndNdx; ++lineNdx)
2206*35238bceSAndroid Build Coastguard Worker {
2207*35238bceSAndroid Build Coastguard Worker const float linePos = (patternStart + (float(lineNdx) / float(m_patternSide)) * patternSize) * 0.5f + 0.5f;
2208*35238bceSAndroid Build Coastguard Worker const float lineWidth = (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
2209*35238bceSAndroid Build Coastguard Worker
2210*35238bceSAndroid Build Coastguard Worker if (linePos * (float)viewportArea > (float)queryAreaBegin + 1.0f &&
2211*35238bceSAndroid Build Coastguard Worker linePos * (float)viewportArea < (float)queryAreaEnd - 1.0f)
2212*35238bceSAndroid Build Coastguard Worker {
2213*35238bceSAndroid Build Coastguard Worker // line center is within the area
2214*35238bceSAndroid Build Coastguard Worker ++numLinesMin;
2215*35238bceSAndroid Build Coastguard Worker ++numLinesMax;
2216*35238bceSAndroid Build Coastguard Worker }
2217*35238bceSAndroid Build Coastguard Worker else if (linePos * (float)viewportArea > (float)queryAreaBegin - lineWidth * 0.5f - 1.0f &&
2218*35238bceSAndroid Build Coastguard Worker linePos * (float)viewportArea < (float)queryAreaEnd + lineWidth * 0.5f + 1.0f)
2219*35238bceSAndroid Build Coastguard Worker {
2220*35238bceSAndroid Build Coastguard Worker // line could leak into area
2221*35238bceSAndroid Build Coastguard Worker ++numLinesMax;
2222*35238bceSAndroid Build Coastguard Worker }
2223*35238bceSAndroid Build Coastguard Worker }
2224*35238bceSAndroid Build Coastguard Worker
2225*35238bceSAndroid Build Coastguard Worker return tcu::IVec2(numLinesMin, numLinesMax);
2226*35238bceSAndroid Build Coastguard Worker }
2227*35238bceSAndroid Build Coastguard Worker
scanRow(const tcu::ConstPixelBufferAccess & access,int row,int rowBegin,int rowEnd,int rowViewportBegin,int rowViewportEnd,const tcu::IVec2 & numLines,int & messageLimitCounter) const2228*35238bceSAndroid Build Coastguard Worker uint8_t LineRenderCase::scanRow(const tcu::ConstPixelBufferAccess &access, int row, int rowBegin, int rowEnd,
2229*35238bceSAndroid Build Coastguard Worker int rowViewportBegin, int rowViewportEnd, const tcu::IVec2 &numLines,
2230*35238bceSAndroid Build Coastguard Worker int &messageLimitCounter) const
2231*35238bceSAndroid Build Coastguard Worker {
2232*35238bceSAndroid Build Coastguard Worker const bool numLinesOk = checkAreaNumLines(access, tcu::IVec4(rowBegin, row, rowEnd - rowBegin, 1),
2233*35238bceSAndroid Build Coastguard Worker messageLimitCounter, SCAN_ROW_COMPONENT_NDX, numLines);
2234*35238bceSAndroid Build Coastguard Worker const uint8_t lineWidthRes = checkLineWidths(access, tcu::IVec2(rowBegin, row), tcu::IVec2(rowEnd, row),
2235*35238bceSAndroid Build Coastguard Worker SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
2236*35238bceSAndroid Build Coastguard Worker const uint8_t lineContinuityRes =
2237*35238bceSAndroid Build Coastguard Worker checkLineContinuity(access, tcu::IVec2(rowViewportBegin, row), tcu::IVec2(rowViewportEnd, row),
2238*35238bceSAndroid Build Coastguard Worker SCAN_COL_COMPONENT_NDX, messageLimitCounter);
2239*35238bceSAndroid Build Coastguard Worker uint8_t result = 0;
2240*35238bceSAndroid Build Coastguard Worker
2241*35238bceSAndroid Build Coastguard Worker if (numLinesOk)
2242*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_NUM_LINES_OK_BIT;
2243*35238bceSAndroid Build Coastguard Worker
2244*35238bceSAndroid Build Coastguard Worker if (lineContinuityRes == 0)
2245*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_LINE_CONT_OK_BIT;
2246*35238bceSAndroid Build Coastguard Worker else
2247*35238bceSAndroid Build Coastguard Worker result |= lineContinuityRes;
2248*35238bceSAndroid Build Coastguard Worker
2249*35238bceSAndroid Build Coastguard Worker if (lineWidthRes == 0)
2250*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_LINE_WIDTH_OK_BIT;
2251*35238bceSAndroid Build Coastguard Worker else
2252*35238bceSAndroid Build Coastguard Worker result |= lineWidthRes;
2253*35238bceSAndroid Build Coastguard Worker
2254*35238bceSAndroid Build Coastguard Worker return result;
2255*35238bceSAndroid Build Coastguard Worker }
2256*35238bceSAndroid Build Coastguard Worker
scanColumn(const tcu::ConstPixelBufferAccess & access,int column,int columnBegin,int columnEnd,int columnViewportBegin,int columnViewportEnd,const tcu::IVec2 & numLines,int & messageLimitCounter) const2257*35238bceSAndroid Build Coastguard Worker uint8_t LineRenderCase::scanColumn(const tcu::ConstPixelBufferAccess &access, int column, int columnBegin,
2258*35238bceSAndroid Build Coastguard Worker int columnEnd, int columnViewportBegin, int columnViewportEnd,
2259*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &numLines, int &messageLimitCounter) const
2260*35238bceSAndroid Build Coastguard Worker {
2261*35238bceSAndroid Build Coastguard Worker const bool numLinesOk = checkAreaNumLines(access, tcu::IVec4(column, columnBegin, 1, columnEnd - columnBegin),
2262*35238bceSAndroid Build Coastguard Worker messageLimitCounter, SCAN_COL_COMPONENT_NDX, numLines);
2263*35238bceSAndroid Build Coastguard Worker const uint8_t lineWidthRes = checkLineWidths(access, tcu::IVec2(column, columnBegin), tcu::IVec2(column, columnEnd),
2264*35238bceSAndroid Build Coastguard Worker SCAN_COL_COMPONENT_NDX, messageLimitCounter);
2265*35238bceSAndroid Build Coastguard Worker const uint8_t lineContinuityRes =
2266*35238bceSAndroid Build Coastguard Worker checkLineContinuity(access, tcu::IVec2(column, columnViewportBegin), tcu::IVec2(column, columnViewportEnd),
2267*35238bceSAndroid Build Coastguard Worker SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
2268*35238bceSAndroid Build Coastguard Worker uint8_t result = 0;
2269*35238bceSAndroid Build Coastguard Worker
2270*35238bceSAndroid Build Coastguard Worker if (numLinesOk)
2271*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_NUM_LINES_OK_BIT;
2272*35238bceSAndroid Build Coastguard Worker
2273*35238bceSAndroid Build Coastguard Worker if (lineContinuityRes == 0)
2274*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_LINE_CONT_OK_BIT;
2275*35238bceSAndroid Build Coastguard Worker else
2276*35238bceSAndroid Build Coastguard Worker result |= lineContinuityRes;
2277*35238bceSAndroid Build Coastguard Worker
2278*35238bceSAndroid Build Coastguard Worker if (lineWidthRes == 0)
2279*35238bceSAndroid Build Coastguard Worker result |= (uint8_t)SCANRESULT_LINE_WIDTH_OK_BIT;
2280*35238bceSAndroid Build Coastguard Worker else
2281*35238bceSAndroid Build Coastguard Worker result |= lineWidthRes;
2282*35238bceSAndroid Build Coastguard Worker
2283*35238bceSAndroid Build Coastguard Worker return result;
2284*35238bceSAndroid Build Coastguard Worker }
2285*35238bceSAndroid Build Coastguard Worker
checkAreaNumLines(const tcu::ConstPixelBufferAccess & access,const tcu::IVec4 & area,int & messageLimitCounter,int componentNdx,const tcu::IVec2 & numLines) const2286*35238bceSAndroid Build Coastguard Worker bool LineRenderCase::checkAreaNumLines(const tcu::ConstPixelBufferAccess &access, const tcu::IVec4 &area,
2287*35238bceSAndroid Build Coastguard Worker int &messageLimitCounter, int componentNdx, const tcu::IVec2 &numLines) const
2288*35238bceSAndroid Build Coastguard Worker {
2289*35238bceSAndroid Build Coastguard Worker // Num maxima == num lines
2290*35238bceSAndroid Build Coastguard Worker const tcu::ConstPixelBufferAccess subAccess =
2291*35238bceSAndroid Build Coastguard Worker tcu::getSubregion(access, area.x(), area.y(), 0, area.z(), area.w(), 1);
2292*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 numMinimaMaxima = getNumMinimaMaxima(subAccess, componentNdx);
2293*35238bceSAndroid Build Coastguard Worker const int numMaxima = numMinimaMaxima.y();
2294*35238bceSAndroid Build Coastguard Worker
2295*35238bceSAndroid Build Coastguard Worker // In valid range
2296*35238bceSAndroid Build Coastguard Worker if (numMaxima >= numLines.x() && numMaxima <= numLines.y())
2297*35238bceSAndroid Build Coastguard Worker return true;
2298*35238bceSAndroid Build Coastguard Worker
2299*35238bceSAndroid Build Coastguard Worker if (--messageLimitCounter < 0)
2300*35238bceSAndroid Build Coastguard Worker return false;
2301*35238bceSAndroid Build Coastguard Worker
2302*35238bceSAndroid Build Coastguard Worker if (area.z() == 1)
2303*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "On column " << area.x() << ", y: [" << area.y() << ","
2304*35238bceSAndroid Build Coastguard Worker << (area.y() + area.w()) << "):\n"
2305*35238bceSAndroid Build Coastguard Worker << "\tExpected [" << numLines.x() << ", " << numLines.y()
2306*35238bceSAndroid Build Coastguard Worker << "] lines but the number of lines in the area is " << numMaxima
2307*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2308*35238bceSAndroid Build Coastguard Worker else
2309*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "On row " << area.y() << ", x: [" << area.x() << ","
2310*35238bceSAndroid Build Coastguard Worker << (area.x() + area.z()) << "):\n"
2311*35238bceSAndroid Build Coastguard Worker << "\tExpected [" << numLines.x() << ", " << numLines.y()
2312*35238bceSAndroid Build Coastguard Worker << "] lines but the number of lines in the area is " << numMaxima
2313*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2314*35238bceSAndroid Build Coastguard Worker
2315*35238bceSAndroid Build Coastguard Worker return false;
2316*35238bceSAndroid Build Coastguard Worker }
2317*35238bceSAndroid Build Coastguard Worker
getNumMinimaMaxima(const tcu::ConstPixelBufferAccess & access,int componentNdx) const2318*35238bceSAndroid Build Coastguard Worker tcu::IVec2 LineRenderCase::getNumMinimaMaxima(const tcu::ConstPixelBufferAccess &access, int componentNdx) const
2319*35238bceSAndroid Build Coastguard Worker {
2320*35238bceSAndroid Build Coastguard Worker DE_ASSERT(access.getWidth() == 1 || access.getHeight() == 1);
2321*35238bceSAndroid Build Coastguard Worker
2322*35238bceSAndroid Build Coastguard Worker int previousValue = -1;
2323*35238bceSAndroid Build Coastguard Worker int previousSign = 0;
2324*35238bceSAndroid Build Coastguard Worker int numMinima = 0;
2325*35238bceSAndroid Build Coastguard Worker int numMaxima = 0;
2326*35238bceSAndroid Build Coastguard Worker
2327*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < access.getHeight(); ++y)
2328*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < access.getWidth(); ++x)
2329*35238bceSAndroid Build Coastguard Worker {
2330*35238bceSAndroid Build Coastguard Worker const int componentValue = access.getPixelInt(x, y)[componentNdx];
2331*35238bceSAndroid Build Coastguard Worker
2332*35238bceSAndroid Build Coastguard Worker if (previousValue != -1)
2333*35238bceSAndroid Build Coastguard Worker {
2334*35238bceSAndroid Build Coastguard Worker const int sign = (componentValue > previousValue) ? (+1) :
2335*35238bceSAndroid Build Coastguard Worker (componentValue < previousValue) ? (-1) :
2336*35238bceSAndroid Build Coastguard Worker (0);
2337*35238bceSAndroid Build Coastguard Worker
2338*35238bceSAndroid Build Coastguard Worker // local minima/maxima in sign changes (zero signless)
2339*35238bceSAndroid Build Coastguard Worker if (sign != 0 && sign == -previousSign)
2340*35238bceSAndroid Build Coastguard Worker {
2341*35238bceSAndroid Build Coastguard Worker previousSign = sign;
2342*35238bceSAndroid Build Coastguard Worker
2343*35238bceSAndroid Build Coastguard Worker if (sign > 0)
2344*35238bceSAndroid Build Coastguard Worker ++numMinima;
2345*35238bceSAndroid Build Coastguard Worker else
2346*35238bceSAndroid Build Coastguard Worker ++numMaxima;
2347*35238bceSAndroid Build Coastguard Worker }
2348*35238bceSAndroid Build Coastguard Worker else if (sign != 0 && previousSign == 0)
2349*35238bceSAndroid Build Coastguard Worker {
2350*35238bceSAndroid Build Coastguard Worker previousSign = sign;
2351*35238bceSAndroid Build Coastguard Worker
2352*35238bceSAndroid Build Coastguard Worker // local extreme at the start boundary
2353*35238bceSAndroid Build Coastguard Worker if (sign > 0)
2354*35238bceSAndroid Build Coastguard Worker ++numMinima;
2355*35238bceSAndroid Build Coastguard Worker else
2356*35238bceSAndroid Build Coastguard Worker ++numMaxima;
2357*35238bceSAndroid Build Coastguard Worker }
2358*35238bceSAndroid Build Coastguard Worker }
2359*35238bceSAndroid Build Coastguard Worker
2360*35238bceSAndroid Build Coastguard Worker previousValue = componentValue;
2361*35238bceSAndroid Build Coastguard Worker }
2362*35238bceSAndroid Build Coastguard Worker
2363*35238bceSAndroid Build Coastguard Worker // local extreme at the end boundary
2364*35238bceSAndroid Build Coastguard Worker if (previousSign > 0)
2365*35238bceSAndroid Build Coastguard Worker ++numMaxima;
2366*35238bceSAndroid Build Coastguard Worker else if (previousSign < 0)
2367*35238bceSAndroid Build Coastguard Worker ++numMinima;
2368*35238bceSAndroid Build Coastguard Worker else
2369*35238bceSAndroid Build Coastguard Worker {
2370*35238bceSAndroid Build Coastguard Worker ++numMaxima;
2371*35238bceSAndroid Build Coastguard Worker ++numMinima;
2372*35238bceSAndroid Build Coastguard Worker }
2373*35238bceSAndroid Build Coastguard Worker
2374*35238bceSAndroid Build Coastguard Worker return tcu::IVec2(numMinima, numMaxima);
2375*35238bceSAndroid Build Coastguard Worker }
2376*35238bceSAndroid Build Coastguard Worker
checkLineContinuity(const tcu::ConstPixelBufferAccess & access,const tcu::IVec2 & begin,const tcu::IVec2 & end,int componentNdx,int & messageLimitCounter) const2377*35238bceSAndroid Build Coastguard Worker uint8_t LineRenderCase::checkLineContinuity(const tcu::ConstPixelBufferAccess &access, const tcu::IVec2 &begin,
2378*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &end, int componentNdx, int &messageLimitCounter) const
2379*35238bceSAndroid Build Coastguard Worker {
2380*35238bceSAndroid Build Coastguard Worker bool line = false;
2381*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 advance = (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
2382*35238bceSAndroid Build Coastguard Worker int missedPixels = 0;
2383*35238bceSAndroid Build Coastguard Worker int totalPixels = 0;
2384*35238bceSAndroid Build Coastguard Worker uint8_t errorMask = 0;
2385*35238bceSAndroid Build Coastguard Worker
2386*35238bceSAndroid Build Coastguard Worker for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
2387*35238bceSAndroid Build Coastguard Worker {
2388*35238bceSAndroid Build Coastguard Worker const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);
2389*35238bceSAndroid Build Coastguard Worker
2390*35238bceSAndroid Build Coastguard Worker if (hit)
2391*35238bceSAndroid Build Coastguard Worker line = true;
2392*35238bceSAndroid Build Coastguard Worker else if (line && !hit)
2393*35238bceSAndroid Build Coastguard Worker {
2394*35238bceSAndroid Build Coastguard Worker // non-continuous line detected
2395*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 advanceNeighbor = tcu::IVec2(1, 1) - advance;
2396*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 cursorNeighborPos = cursor + advanceNeighbor;
2397*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 cursorNeighborNeg = cursor - advanceNeighbor;
2398*35238bceSAndroid Build Coastguard Worker // hw precision issues may lead to a line being non-straight -> check neighboring pixels
2399*35238bceSAndroid Build Coastguard Worker if ((access.getPixelInt(cursorNeighborPos.x(), cursorNeighborPos.y())[componentNdx] == 0) &&
2400*35238bceSAndroid Build Coastguard Worker (access.getPixelInt(cursorNeighborNeg.x(), cursorNeighborNeg.y())[componentNdx] == 0))
2401*35238bceSAndroid Build Coastguard Worker ++missedPixels;
2402*35238bceSAndroid Build Coastguard Worker }
2403*35238bceSAndroid Build Coastguard Worker ++totalPixels;
2404*35238bceSAndroid Build Coastguard Worker }
2405*35238bceSAndroid Build Coastguard Worker
2406*35238bceSAndroid Build Coastguard Worker if (missedPixels > 0)
2407*35238bceSAndroid Build Coastguard Worker {
2408*35238bceSAndroid Build Coastguard Worker if (--messageLimitCounter >= 0)
2409*35238bceSAndroid Build Coastguard Worker {
2410*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Found non-continuous "
2411*35238bceSAndroid Build Coastguard Worker << ((advance.x() == 1) ? ("horizontal") : ("vertical")) << " line near " << begin << ". "
2412*35238bceSAndroid Build Coastguard Worker << "Missed pixels: " << missedPixels << tcu::TestLog::EndMessage;
2413*35238bceSAndroid Build Coastguard Worker }
2414*35238bceSAndroid Build Coastguard Worker // allow 10% missing pixels for warning
2415*35238bceSAndroid Build Coastguard Worker if (missedPixels <= deRoundFloatToInt32((float)totalPixels * 0.1f))
2416*35238bceSAndroid Build Coastguard Worker errorMask = SCANRESULT_LINE_CONT_WARN_BIT;
2417*35238bceSAndroid Build Coastguard Worker else
2418*35238bceSAndroid Build Coastguard Worker errorMask = SCANRESULT_LINE_CONT_ERR_BIT;
2419*35238bceSAndroid Build Coastguard Worker }
2420*35238bceSAndroid Build Coastguard Worker
2421*35238bceSAndroid Build Coastguard Worker return errorMask;
2422*35238bceSAndroid Build Coastguard Worker }
2423*35238bceSAndroid Build Coastguard Worker
checkLineWidths(const tcu::ConstPixelBufferAccess & access,const tcu::IVec2 & begin,const tcu::IVec2 & end,int componentNdx,int & messageLimitCounter) const2424*35238bceSAndroid Build Coastguard Worker uint8_t LineRenderCase::checkLineWidths(const tcu::ConstPixelBufferAccess &access, const tcu::IVec2 &begin,
2425*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &end, int componentNdx, int &messageLimitCounter) const
2426*35238bceSAndroid Build Coastguard Worker {
2427*35238bceSAndroid Build Coastguard Worker const bool multisample = m_context.getRenderTarget().getNumSamples() > 1;
2428*35238bceSAndroid Build Coastguard Worker const int lineRenderWidth = (m_isWideLineCase) ? (m_wideLineLineWidth) : 1;
2429*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 lineWidthRange =
2430*35238bceSAndroid Build Coastguard Worker (multisample) ? (tcu::IVec2(lineRenderWidth,
2431*35238bceSAndroid Build Coastguard Worker lineRenderWidth + 1)) // multisampled "smooth" lines may spread to neighboring pixel
2432*35238bceSAndroid Build Coastguard Worker :
2433*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(lineRenderWidth, lineRenderWidth));
2434*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 relaxedLineWidthRange = (tcu::IVec2(lineRenderWidth - 1, lineRenderWidth + 1));
2435*35238bceSAndroid Build Coastguard Worker
2436*35238bceSAndroid Build Coastguard Worker int lineWidth = 0;
2437*35238bceSAndroid Build Coastguard Worker bool bboxLimitedLine = false;
2438*35238bceSAndroid Build Coastguard Worker uint8_t errorMask = 0;
2439*35238bceSAndroid Build Coastguard Worker
2440*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 advance = (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
2441*35238bceSAndroid Build Coastguard Worker
2442*35238bceSAndroid Build Coastguard Worker // fragments before begin?
2443*35238bceSAndroid Build Coastguard Worker if (access.getPixelInt(begin.x(), begin.y())[componentNdx] != 0)
2444*35238bceSAndroid Build Coastguard Worker {
2445*35238bceSAndroid Build Coastguard Worker bboxLimitedLine = true;
2446*35238bceSAndroid Build Coastguard Worker
2447*35238bceSAndroid Build Coastguard Worker for (tcu::IVec2 cursor = begin - advance;; cursor -= advance)
2448*35238bceSAndroid Build Coastguard Worker {
2449*35238bceSAndroid Build Coastguard Worker if (cursor.x() < 0 || cursor.y() < 0)
2450*35238bceSAndroid Build Coastguard Worker {
2451*35238bceSAndroid Build Coastguard Worker break;
2452*35238bceSAndroid Build Coastguard Worker }
2453*35238bceSAndroid Build Coastguard Worker else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
2454*35238bceSAndroid Build Coastguard Worker {
2455*35238bceSAndroid Build Coastguard Worker ++lineWidth;
2456*35238bceSAndroid Build Coastguard Worker }
2457*35238bceSAndroid Build Coastguard Worker else
2458*35238bceSAndroid Build Coastguard Worker break;
2459*35238bceSAndroid Build Coastguard Worker }
2460*35238bceSAndroid Build Coastguard Worker }
2461*35238bceSAndroid Build Coastguard Worker
2462*35238bceSAndroid Build Coastguard Worker for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
2463*35238bceSAndroid Build Coastguard Worker {
2464*35238bceSAndroid Build Coastguard Worker const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);
2465*35238bceSAndroid Build Coastguard Worker
2466*35238bceSAndroid Build Coastguard Worker if (hit)
2467*35238bceSAndroid Build Coastguard Worker ++lineWidth;
2468*35238bceSAndroid Build Coastguard Worker else if (lineWidth)
2469*35238bceSAndroid Build Coastguard Worker {
2470*35238bceSAndroid Build Coastguard Worker // Line is allowed to be be thinner if it borders the bbox boundary (since part of the line might have been discarded).
2471*35238bceSAndroid Build Coastguard Worker const bool incorrectLineWidth =
2472*35238bceSAndroid Build Coastguard Worker (lineWidth < lineWidthRange.x() && !bboxLimitedLine) || (lineWidth > lineWidthRange.y());
2473*35238bceSAndroid Build Coastguard Worker
2474*35238bceSAndroid Build Coastguard Worker if (incorrectLineWidth)
2475*35238bceSAndroid Build Coastguard Worker {
2476*35238bceSAndroid Build Coastguard Worker const bool incorrectRelaxedLineWidth = (lineWidth < relaxedLineWidthRange.x() && !bboxLimitedLine) ||
2477*35238bceSAndroid Build Coastguard Worker (lineWidth > relaxedLineWidthRange.y());
2478*35238bceSAndroid Build Coastguard Worker
2479*35238bceSAndroid Build Coastguard Worker if (incorrectRelaxedLineWidth)
2480*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
2481*35238bceSAndroid Build Coastguard Worker else
2482*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
2483*35238bceSAndroid Build Coastguard Worker
2484*35238bceSAndroid Build Coastguard Worker printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
2485*35238bceSAndroid Build Coastguard Worker }
2486*35238bceSAndroid Build Coastguard Worker
2487*35238bceSAndroid Build Coastguard Worker lineWidth = 0;
2488*35238bceSAndroid Build Coastguard Worker bboxLimitedLine = false;
2489*35238bceSAndroid Build Coastguard Worker }
2490*35238bceSAndroid Build Coastguard Worker }
2491*35238bceSAndroid Build Coastguard Worker
2492*35238bceSAndroid Build Coastguard Worker // fragments after end?
2493*35238bceSAndroid Build Coastguard Worker if (lineWidth)
2494*35238bceSAndroid Build Coastguard Worker {
2495*35238bceSAndroid Build Coastguard Worker for (tcu::IVec2 cursor = end;; cursor += advance)
2496*35238bceSAndroid Build Coastguard Worker {
2497*35238bceSAndroid Build Coastguard Worker if (cursor.x() >= access.getWidth() || cursor.y() >= access.getHeight())
2498*35238bceSAndroid Build Coastguard Worker {
2499*35238bceSAndroid Build Coastguard Worker if (lineWidth > lineWidthRange.y())
2500*35238bceSAndroid Build Coastguard Worker {
2501*35238bceSAndroid Build Coastguard Worker if (lineWidth > relaxedLineWidthRange.y())
2502*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
2503*35238bceSAndroid Build Coastguard Worker else
2504*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
2505*35238bceSAndroid Build Coastguard Worker
2506*35238bceSAndroid Build Coastguard Worker printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
2507*35238bceSAndroid Build Coastguard Worker }
2508*35238bceSAndroid Build Coastguard Worker
2509*35238bceSAndroid Build Coastguard Worker break;
2510*35238bceSAndroid Build Coastguard Worker }
2511*35238bceSAndroid Build Coastguard Worker else if (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0)
2512*35238bceSAndroid Build Coastguard Worker {
2513*35238bceSAndroid Build Coastguard Worker ++lineWidth;
2514*35238bceSAndroid Build Coastguard Worker }
2515*35238bceSAndroid Build Coastguard Worker else if (lineWidth)
2516*35238bceSAndroid Build Coastguard Worker {
2517*35238bceSAndroid Build Coastguard Worker // only check that line width is not larger than expected. Line width may be smaller
2518*35238bceSAndroid Build Coastguard Worker // since the scanning 'cursor' is now outside the bounding box.
2519*35238bceSAndroid Build Coastguard Worker const bool incorrectLineWidth = (lineWidth > lineWidthRange.y());
2520*35238bceSAndroid Build Coastguard Worker
2521*35238bceSAndroid Build Coastguard Worker if (incorrectLineWidth)
2522*35238bceSAndroid Build Coastguard Worker {
2523*35238bceSAndroid Build Coastguard Worker const bool incorrectRelaxedLineWidth = (lineWidth > relaxedLineWidthRange.y());
2524*35238bceSAndroid Build Coastguard Worker
2525*35238bceSAndroid Build Coastguard Worker if (incorrectRelaxedLineWidth)
2526*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
2527*35238bceSAndroid Build Coastguard Worker else
2528*35238bceSAndroid Build Coastguard Worker errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
2529*35238bceSAndroid Build Coastguard Worker
2530*35238bceSAndroid Build Coastguard Worker printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
2531*35238bceSAndroid Build Coastguard Worker }
2532*35238bceSAndroid Build Coastguard Worker
2533*35238bceSAndroid Build Coastguard Worker lineWidth = 0;
2534*35238bceSAndroid Build Coastguard Worker }
2535*35238bceSAndroid Build Coastguard Worker }
2536*35238bceSAndroid Build Coastguard Worker }
2537*35238bceSAndroid Build Coastguard Worker
2538*35238bceSAndroid Build Coastguard Worker return errorMask;
2539*35238bceSAndroid Build Coastguard Worker }
2540*35238bceSAndroid Build Coastguard Worker
printLineWidthError(const tcu::IVec2 & pos,int detectedLineWidth,const tcu::IVec2 & lineWidthRange,bool isHorizontal,int & messageLimitCounter) const2541*35238bceSAndroid Build Coastguard Worker void LineRenderCase::printLineWidthError(const tcu::IVec2 &pos, int detectedLineWidth, const tcu::IVec2 &lineWidthRange,
2542*35238bceSAndroid Build Coastguard Worker bool isHorizontal, int &messageLimitCounter) const
2543*35238bceSAndroid Build Coastguard Worker {
2544*35238bceSAndroid Build Coastguard Worker if (--messageLimitCounter < 0)
2545*35238bceSAndroid Build Coastguard Worker return;
2546*35238bceSAndroid Build Coastguard Worker
2547*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Found incorrect line width near " << pos << ": ("
2548*35238bceSAndroid Build Coastguard Worker << ((isHorizontal) ? ("horizontal") : ("vertical")) << " line)\n"
2549*35238bceSAndroid Build Coastguard Worker << "\tExpected line width in range [" << lineWidthRange.x() << ", " << lineWidthRange.y()
2550*35238bceSAndroid Build Coastguard Worker << "] but found " << detectedLineWidth << tcu::TestLog::EndMessage;
2551*35238bceSAndroid Build Coastguard Worker }
2552*35238bceSAndroid Build Coastguard Worker
2553*35238bceSAndroid Build Coastguard Worker class PointRenderCase : public BBoxRenderCase
2554*35238bceSAndroid Build Coastguard Worker {
2555*35238bceSAndroid Build Coastguard Worker public:
2556*35238bceSAndroid Build Coastguard Worker enum
2557*35238bceSAndroid Build Coastguard Worker {
2558*35238bceSAndroid Build Coastguard Worker POINTFLAG_WIDE = 1u << FLAGBIT_USER_BIT, //!< use wide points
2559*35238bceSAndroid Build Coastguard Worker };
2560*35238bceSAndroid Build Coastguard Worker struct GeneratedPoint
2561*35238bceSAndroid Build Coastguard Worker {
2562*35238bceSAndroid Build Coastguard Worker tcu::Vec2 center;
2563*35238bceSAndroid Build Coastguard Worker int size;
2564*35238bceSAndroid Build Coastguard Worker bool even;
2565*35238bceSAndroid Build Coastguard Worker };
2566*35238bceSAndroid Build Coastguard Worker
2567*35238bceSAndroid Build Coastguard Worker PointRenderCase(Context &context, const char *name, const char *description, uint32_t flags);
2568*35238bceSAndroid Build Coastguard Worker ~PointRenderCase(void);
2569*35238bceSAndroid Build Coastguard Worker
2570*35238bceSAndroid Build Coastguard Worker private:
2571*35238bceSAndroid Build Coastguard Worker enum ResultPointType
2572*35238bceSAndroid Build Coastguard Worker {
2573*35238bceSAndroid Build Coastguard Worker POINT_FULL = 0,
2574*35238bceSAndroid Build Coastguard Worker POINT_PARTIAL
2575*35238bceSAndroid Build Coastguard Worker };
2576*35238bceSAndroid Build Coastguard Worker
2577*35238bceSAndroid Build Coastguard Worker void init(void);
2578*35238bceSAndroid Build Coastguard Worker void deinit(void);
2579*35238bceSAndroid Build Coastguard Worker
2580*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
2581*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
2582*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
2583*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
2584*35238bceSAndroid Build Coastguard Worker std::string genGeometrySource(void) const;
2585*35238bceSAndroid Build Coastguard Worker
2586*35238bceSAndroid Build Coastguard Worker IterationConfig generateConfig(int iteration, const tcu::IVec2 &renderTargetSize) const;
2587*35238bceSAndroid Build Coastguard Worker void generateAttributeData(void);
2588*35238bceSAndroid Build Coastguard Worker void getAttributeData(std::vector<tcu::Vec4> &data) const;
2589*35238bceSAndroid Build Coastguard Worker void renderTestPattern(const IterationConfig &config);
2590*35238bceSAndroid Build Coastguard Worker void verifyRenderResult(const IterationConfig &config);
2591*35238bceSAndroid Build Coastguard Worker
2592*35238bceSAndroid Build Coastguard Worker void genReferencePointData(const IterationConfig &config, std::vector<GeneratedPoint> &data) const;
2593*35238bceSAndroid Build Coastguard Worker bool verifyNarrowPointPattern(const tcu::Surface &viewport, const std::vector<GeneratedPoint> &refPoints,
2594*35238bceSAndroid Build Coastguard Worker const ProjectedBBox &bbox, int &logFloodCounter);
2595*35238bceSAndroid Build Coastguard Worker bool verifyWidePointPattern(const tcu::Surface &viewport, const std::vector<GeneratedPoint> &refPoints,
2596*35238bceSAndroid Build Coastguard Worker const ProjectedBBox &bbox, int &logFloodCounter);
2597*35238bceSAndroid Build Coastguard Worker bool verifyWidePoint(const tcu::Surface &viewport, const GeneratedPoint &refPoint, const ProjectedBBox &bbox,
2598*35238bceSAndroid Build Coastguard Worker ResultPointType pointType, int &logFloodCounter);
2599*35238bceSAndroid Build Coastguard Worker bool verifyWidePointAt(const tcu::IVec2 &pointPos, const tcu::Surface &viewport, const GeneratedPoint &refPoint,
2600*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 &bbox, ResultPointType pointType, int componentNdx, int &logFloodCounter);
2601*35238bceSAndroid Build Coastguard Worker tcu::IVec2 scanPointWidthAt(const tcu::IVec2 &pointPos, const tcu::Surface &viewport, int expectedPointSize,
2602*35238bceSAndroid Build Coastguard Worker int componentNdx) const;
2603*35238bceSAndroid Build Coastguard Worker
2604*35238bceSAndroid Build Coastguard Worker const int m_numStripes;
2605*35238bceSAndroid Build Coastguard Worker const bool m_isWidePointCase;
2606*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> m_attribData;
2607*35238bceSAndroid Build Coastguard Worker };
2608*35238bceSAndroid Build Coastguard Worker
PointRenderCase(Context & context,const char * name,const char * description,uint32_t flags)2609*35238bceSAndroid Build Coastguard Worker PointRenderCase::PointRenderCase(Context &context, const char *name, const char *description, uint32_t flags)
2610*35238bceSAndroid Build Coastguard Worker : BBoxRenderCase(context, name, description, 12, flags)
2611*35238bceSAndroid Build Coastguard Worker , m_numStripes(4)
2612*35238bceSAndroid Build Coastguard Worker , m_isWidePointCase((flags & POINTFLAG_WIDE) != 0)
2613*35238bceSAndroid Build Coastguard Worker {
2614*35238bceSAndroid Build Coastguard Worker }
2615*35238bceSAndroid Build Coastguard Worker
~PointRenderCase(void)2616*35238bceSAndroid Build Coastguard Worker PointRenderCase::~PointRenderCase(void)
2617*35238bceSAndroid Build Coastguard Worker {
2618*35238bceSAndroid Build Coastguard Worker }
2619*35238bceSAndroid Build Coastguard Worker
init(void)2620*35238bceSAndroid Build Coastguard Worker void PointRenderCase::init(void)
2621*35238bceSAndroid Build Coastguard Worker {
2622*35238bceSAndroid Build Coastguard Worker if (m_isWidePointCase)
2623*35238bceSAndroid Build Coastguard Worker {
2624*35238bceSAndroid Build Coastguard Worker const bool supportsGL45 =
2625*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
2626*35238bceSAndroid Build Coastguard Worker
2627*35238bceSAndroid Build Coastguard Worker if (!supportsGL45)
2628*35238bceSAndroid Build Coastguard Worker {
2629*35238bceSAndroid Build Coastguard Worker // extensions
2630*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
2631*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_geometry_point_size extension");
2632*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage && !m_hasGeometryStage &&
2633*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_point_size"))
2634*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_point_size extension");
2635*35238bceSAndroid Build Coastguard Worker }
2636*35238bceSAndroid Build Coastguard Worker
2637*35238bceSAndroid Build Coastguard Worker // Enable program point size for desktop GL
2638*35238bceSAndroid Build Coastguard Worker if (supportsGL45)
2639*35238bceSAndroid Build Coastguard Worker {
2640*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2641*35238bceSAndroid Build Coastguard Worker gl.enable(GL_PROGRAM_POINT_SIZE);
2642*35238bceSAndroid Build Coastguard Worker }
2643*35238bceSAndroid Build Coastguard Worker
2644*35238bceSAndroid Build Coastguard Worker // point size range
2645*35238bceSAndroid Build Coastguard Worker {
2646*35238bceSAndroid Build Coastguard Worker glw::GLfloat pointSizeRange[2] = {0.0f, 0.0f};
2647*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
2648*35238bceSAndroid Build Coastguard Worker
2649*35238bceSAndroid Build Coastguard Worker if (pointSizeRange[1] < 5.0f)
2650*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires point size 5.0");
2651*35238bceSAndroid Build Coastguard Worker }
2652*35238bceSAndroid Build Coastguard Worker }
2653*35238bceSAndroid Build Coastguard Worker
2654*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
2655*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << "Rendering point pattern to "
2656*35238bceSAndroid Build Coastguard Worker << ((m_renderTarget == RENDERTARGET_DEFAULT) ? ("default frame buffer") : ("fbo")) << ".\n"
2657*35238bceSAndroid Build Coastguard Worker << "Half of the points are green, half blue. Using additive blending.\n"
2658*35238bceSAndroid Build Coastguard Worker << "Points are in random order, varying pattern size and location for each iteration.\n"
2659*35238bceSAndroid Build Coastguard Worker << "Marking all discardable fragments (fragments outside the bounding box) with a fully saturated red channel."
2660*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2661*35238bceSAndroid Build Coastguard Worker
2662*35238bceSAndroid Build Coastguard Worker generateAttributeData();
2663*35238bceSAndroid Build Coastguard Worker
2664*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::init();
2665*35238bceSAndroid Build Coastguard Worker }
2666*35238bceSAndroid Build Coastguard Worker
deinit(void)2667*35238bceSAndroid Build Coastguard Worker void PointRenderCase::deinit(void)
2668*35238bceSAndroid Build Coastguard Worker {
2669*35238bceSAndroid Build Coastguard Worker // clear data
2670*35238bceSAndroid Build Coastguard Worker m_attribData = std::vector<tcu::Vec4>();
2671*35238bceSAndroid Build Coastguard Worker
2672*35238bceSAndroid Build Coastguard Worker // deinit parent
2673*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::deinit();
2674*35238bceSAndroid Build Coastguard Worker }
2675*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const2676*35238bceSAndroid Build Coastguard Worker std::string PointRenderCase::genVertexSource(void) const
2677*35238bceSAndroid Build Coastguard Worker {
2678*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2679*35238bceSAndroid Build Coastguard Worker
2680*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2681*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
2682*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_color;\n"
2683*35238bceSAndroid Build Coastguard Worker "out highp vec4 vtx_color;\n"
2684*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
2685*35238bceSAndroid Build Coastguard Worker "\n";
2686*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
2687*35238bceSAndroid Build Coastguard Worker {
2688*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
2689*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
2690*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n"
2691*35238bceSAndroid Build Coastguard Worker "\n"
2692*35238bceSAndroid Build Coastguard Worker "flat out highp float v_"
2693*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2694*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize;\n"
2695*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
2696*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2697*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
2698*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
2699*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2700*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax;\n"
2701*35238bceSAndroid Build Coastguard Worker "\n";
2702*35238bceSAndroid Build Coastguard Worker }
2703*35238bceSAndroid Build Coastguard Worker
2704*35238bceSAndroid Build Coastguard Worker buf << "void main()\n"
2705*35238bceSAndroid Build Coastguard Worker "{\n"
2706*35238bceSAndroid Build Coastguard Worker " highp vec2 patternOffset = u_posScale.xy;\n"
2707*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
2708*35238bceSAndroid Build Coastguard Worker " highp float pointSize = "
2709*35238bceSAndroid Build Coastguard Worker << ((m_isWidePointCase && !m_hasTessellationStage && !m_hasGeometryStage) ?
2710*35238bceSAndroid Build Coastguard Worker ("(a_color.g > 0.0) ? (5.0) : (3.0)") :
2711*35238bceSAndroid Build Coastguard Worker ("1.0"))
2712*35238bceSAndroid Build Coastguard Worker << ";\n"
2713*35238bceSAndroid Build Coastguard Worker << " gl_Position = vec4(a_position.xy * patternScale + patternOffset, a_position.z, a_position.w);\n"
2714*35238bceSAndroid Build Coastguard Worker " gl_PointSize = pointSize;\n"
2715*35238bceSAndroid Build Coastguard Worker " vtx_color = a_color;\n";
2716*35238bceSAndroid Build Coastguard Worker
2717*35238bceSAndroid Build Coastguard Worker if (!m_hasTessellationStage)
2718*35238bceSAndroid Build Coastguard Worker {
2719*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState);
2720*35238bceSAndroid Build Coastguard Worker buf << "\n"
2721*35238bceSAndroid Build Coastguard Worker " v_"
2722*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2723*35238bceSAndroid Build Coastguard Worker << "bbox_expansionSize = pointSize;\n"
2724*35238bceSAndroid Build Coastguard Worker " v_"
2725*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2726*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin =\n"
2727*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
2728*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
2729*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMin.x, u_primitiveBBoxMin.y, u_primitiveBBoxMin.z) / "
2730*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n"
2731*35238bceSAndroid Build Coastguard Worker " v_"
2732*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2733*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax =\n"
2734*35238bceSAndroid Build Coastguard Worker " min(vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
2735*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMin.w,\n"
2736*35238bceSAndroid Build Coastguard Worker " vec3(u_primitiveBBoxMax.x, u_primitiveBBoxMax.y, u_primitiveBBoxMax.z) / "
2737*35238bceSAndroid Build Coastguard Worker "u_primitiveBBoxMax.w);\n";
2738*35238bceSAndroid Build Coastguard Worker }
2739*35238bceSAndroid Build Coastguard Worker
2740*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2741*35238bceSAndroid Build Coastguard Worker return buf.str();
2742*35238bceSAndroid Build Coastguard Worker }
2743*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const2744*35238bceSAndroid Build Coastguard Worker std::string PointRenderCase::genFragmentSource(void) const
2745*35238bceSAndroid Build Coastguard Worker {
2746*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasGeometryStage) ? ("geo_color") :
2747*35238bceSAndroid Build Coastguard Worker (m_hasTessellationStage) ? ("tess_color") :
2748*35238bceSAndroid Build Coastguard Worker ("vtx_color");
2749*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2750*35238bceSAndroid Build Coastguard Worker
2751*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2752*35238bceSAndroid Build Coastguard Worker "in mediump vec4 "
2753*35238bceSAndroid Build Coastguard Worker << colorInputName
2754*35238bceSAndroid Build Coastguard Worker << ";\n"
2755*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
2756*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_INSIDE_BBOX)
2757*35238bceSAndroid Build Coastguard Worker << "\n"
2758*35238bceSAndroid Build Coastguard Worker "void main()\n"
2759*35238bceSAndroid Build Coastguard Worker "{\n"
2760*35238bceSAndroid Build Coastguard Worker " mediump vec4 baseColor = "
2761*35238bceSAndroid Build Coastguard Worker << colorInputName
2762*35238bceSAndroid Build Coastguard Worker << ";\n"
2763*35238bceSAndroid Build Coastguard Worker " mediump float redChannel;\n"
2764*35238bceSAndroid Build Coastguard Worker " if (fragmentInsideTheBBox(gl_FragCoord.z))\n"
2765*35238bceSAndroid Build Coastguard Worker " redChannel = 0.0;\n"
2766*35238bceSAndroid Build Coastguard Worker " else\n"
2767*35238bceSAndroid Build Coastguard Worker " redChannel = 1.0;\n"
2768*35238bceSAndroid Build Coastguard Worker " o_color = vec4(redChannel, baseColor.g, baseColor.b, baseColor.a);\n"
2769*35238bceSAndroid Build Coastguard Worker "}\n";
2770*35238bceSAndroid Build Coastguard Worker
2771*35238bceSAndroid Build Coastguard Worker return buf.str();
2772*35238bceSAndroid Build Coastguard Worker }
2773*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const2774*35238bceSAndroid Build Coastguard Worker std::string PointRenderCase::genTessellationControlSource(void) const
2775*35238bceSAndroid Build Coastguard Worker {
2776*35238bceSAndroid Build Coastguard Worker const bool tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
2777*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2778*35238bceSAndroid Build Coastguard Worker
2779*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2780*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
2781*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
2782*35238bceSAndroid Build Coastguard Worker "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
2783*35238bceSAndroid Build Coastguard Worker << ((tessellationWidePoints) ? ("${TESSELLATION_POINT_SIZE_REQUIRE}\n") : (""))
2784*35238bceSAndroid Build Coastguard Worker << "layout(vertices=1) out;"
2785*35238bceSAndroid Build Coastguard Worker "\n"
2786*35238bceSAndroid Build Coastguard Worker "in highp vec4 vtx_color[];\n"
2787*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_ctrl_color[];\n"
2788*35238bceSAndroid Build Coastguard Worker "uniform highp float u_tessellationLevel;\n"
2789*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n";
2790*35238bceSAndroid Build Coastguard Worker
2791*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
2792*35238bceSAndroid Build Coastguard Worker {
2793*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_primitiveBBoxMin;\n"
2794*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_primitiveBBoxMax;\n";
2795*35238bceSAndroid Build Coastguard Worker }
2796*35238bceSAndroid Build Coastguard Worker
2797*35238bceSAndroid Build Coastguard Worker buf << "patch out highp vec3 vp_bbox_clipMin;\n"
2798*35238bceSAndroid Build Coastguard Worker "patch out highp vec3 vp_bbox_clipMax;\n";
2799*35238bceSAndroid Build Coastguard Worker
2800*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
2801*35238bceSAndroid Build Coastguard Worker {
2802*35238bceSAndroid Build Coastguard Worker buf << "\n";
2803*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
2804*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_X);
2805*35238bceSAndroid Build Coastguard Worker buf << genShaderFunction(SHADER_FUNC_MIRROR_Y);
2806*35238bceSAndroid Build Coastguard Worker
2807*35238bceSAndroid Build Coastguard Worker buf << "vec4 transformVec(in highp vec4 p)\n"
2808*35238bceSAndroid Build Coastguard Worker "{\n"
2809*35238bceSAndroid Build Coastguard Worker " return "
2810*35238bceSAndroid Build Coastguard Worker << ((m_hasGeometryStage) ? ("mirrorX(mirrorY(p))") : ("mirrorY(p)"))
2811*35238bceSAndroid Build Coastguard Worker << ";\n"
2812*35238bceSAndroid Build Coastguard Worker "}\n";
2813*35238bceSAndroid Build Coastguard Worker }
2814*35238bceSAndroid Build Coastguard Worker
2815*35238bceSAndroid Build Coastguard Worker buf << "\n"
2816*35238bceSAndroid Build Coastguard Worker "void main()\n"
2817*35238bceSAndroid Build Coastguard Worker "{\n"
2818*35238bceSAndroid Build Coastguard Worker " // convert to nonsensical coordinates, just in case\n"
2819*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position.wzxy;\n"
2820*35238bceSAndroid Build Coastguard Worker " tess_ctrl_color[gl_InvocationID] = vtx_color[gl_InvocationID];\n"
2821*35238bceSAndroid Build Coastguard Worker "\n"
2822*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = u_tessellationLevel;\n"
2823*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_tessellationLevel;\n"
2824*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = u_tessellationLevel;\n"
2825*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = u_tessellationLevel;\n"
2826*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 0.8; // will be rounded up to 1\n"
2827*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = 0.8; // will be rounded up to 1\n";
2828*35238bceSAndroid Build Coastguard Worker
2829*35238bceSAndroid Build Coastguard Worker if (m_calcPerPrimitiveBBox)
2830*35238bceSAndroid Build Coastguard Worker {
2831*35238bceSAndroid Build Coastguard Worker buf << "\n";
2832*35238bceSAndroid Build Coastguard Worker
2833*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
2834*35238bceSAndroid Build Coastguard Worker buf << " const vec2 minExpansion = vec2(0.07 + 0.05, 0.07 + 0.02); // eval and geometry shader\n"
2835*35238bceSAndroid Build Coastguard Worker " const vec2 maxExpansion = vec2(0.07 + 0.05, 0.07 + 0.03); // eval and geometry shader\n";
2836*35238bceSAndroid Build Coastguard Worker else
2837*35238bceSAndroid Build Coastguard Worker buf << " const vec2 minExpansion = vec2(0.07, 0.07); // eval shader\n"
2838*35238bceSAndroid Build Coastguard Worker " const vec2 maxExpansion = vec2(0.07, 0.07); // eval shader\n";
2839*35238bceSAndroid Build Coastguard Worker
2840*35238bceSAndroid Build Coastguard Worker buf << " highp vec2 patternScale = u_posScale.zw;\n"
2841*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = transformVec(gl_in[0].gl_Position) - vec4(minExpansion * patternScale, 0.0, "
2842*35238bceSAndroid Build Coastguard Worker "0.0);\n"
2843*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = transformVec(gl_in[0].gl_Position) + vec4(maxExpansion * patternScale, 0.0, "
2844*35238bceSAndroid Build Coastguard Worker "0.0);\n";
2845*35238bceSAndroid Build Coastguard Worker }
2846*35238bceSAndroid Build Coastguard Worker else
2847*35238bceSAndroid Build Coastguard Worker {
2848*35238bceSAndroid Build Coastguard Worker buf << "\n"
2849*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMin = u_primitiveBBoxMin;\n"
2850*35238bceSAndroid Build Coastguard Worker " highp vec4 bboxMax = u_primitiveBBoxMax;\n";
2851*35238bceSAndroid Build Coastguard Worker }
2852*35238bceSAndroid Build Coastguard Worker if (!m_useGlobalState)
2853*35238bceSAndroid Build Coastguard Worker buf << "\n"
2854*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[0] = bboxMin;\n"
2855*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = bboxMax;\n";
2856*35238bceSAndroid Build Coastguard Worker
2857*35238bceSAndroid Build Coastguard Worker buf << " vp_bbox_clipMin = min(vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMin.w,\n"
2858*35238bceSAndroid Build Coastguard Worker " vec3(bboxMin.x, bboxMin.y, bboxMin.z) / bboxMax.w);\n"
2859*35238bceSAndroid Build Coastguard Worker " vp_bbox_clipMax = max(vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMin.w,\n"
2860*35238bceSAndroid Build Coastguard Worker " vec3(bboxMax.x, bboxMax.y, bboxMax.z) / bboxMax.w);\n"
2861*35238bceSAndroid Build Coastguard Worker "}\n";
2862*35238bceSAndroid Build Coastguard Worker
2863*35238bceSAndroid Build Coastguard Worker return buf.str();
2864*35238bceSAndroid Build Coastguard Worker }
2865*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const2866*35238bceSAndroid Build Coastguard Worker std::string PointRenderCase::genTessellationEvaluationSource(void) const
2867*35238bceSAndroid Build Coastguard Worker {
2868*35238bceSAndroid Build Coastguard Worker const bool tessellationWidePoints = (m_isWidePointCase) && (!m_hasGeometryStage);
2869*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2870*35238bceSAndroid Build Coastguard Worker
2871*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2872*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
2873*35238bceSAndroid Build Coastguard Worker << ((tessellationWidePoints) ? ("${TESSELLATION_POINT_SIZE_REQUIRE}\n") : (""))
2874*35238bceSAndroid Build Coastguard Worker << "layout(quads, point_mode) in;"
2875*35238bceSAndroid Build Coastguard Worker "\n"
2876*35238bceSAndroid Build Coastguard Worker "in highp vec4 tess_ctrl_color[];\n"
2877*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_color;\n"
2878*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
2879*35238bceSAndroid Build Coastguard Worker "\n"
2880*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMin;\n"
2881*35238bceSAndroid Build Coastguard Worker "patch in highp vec3 vp_bbox_clipMax;\n"
2882*35238bceSAndroid Build Coastguard Worker << ((!m_hasGeometryStage) ? ("flat out highp float v_bbox_expansionSize;\n") : ("")) << "flat out highp vec3 v_"
2883*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2884*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin;\n"
2885*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_"
2886*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2887*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax;\n"
2888*35238bceSAndroid Build Coastguard Worker "\n"
2889*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_Y)
2890*35238bceSAndroid Build Coastguard Worker << "void main()\n"
2891*35238bceSAndroid Build Coastguard Worker "{\n"
2892*35238bceSAndroid Build Coastguard Worker " // non-trivial tessellation evaluation shader, convert from nonsensical coords, flip vertically\n"
2893*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
2894*35238bceSAndroid Build Coastguard Worker " highp vec4 offset = vec4((gl_TessCoord.xy * 2.0 - vec2(1.0)) * 0.07 * patternScale, 0.0, 0.0);\n"
2895*35238bceSAndroid Build Coastguard Worker " highp float pointSize = "
2896*35238bceSAndroid Build Coastguard Worker << ((tessellationWidePoints) ? ("(tess_ctrl_color[0].g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
2897*35238bceSAndroid Build Coastguard Worker << ";\n"
2898*35238bceSAndroid Build Coastguard Worker " gl_Position = mirrorY(gl_in[0].gl_Position.zwyx + offset);\n";
2899*35238bceSAndroid Build Coastguard Worker
2900*35238bceSAndroid Build Coastguard Worker if (tessellationWidePoints)
2901*35238bceSAndroid Build Coastguard Worker buf << " gl_PointSize = pointSize;\n";
2902*35238bceSAndroid Build Coastguard Worker
2903*35238bceSAndroid Build Coastguard Worker buf << " tess_color = tess_ctrl_color[0];\n"
2904*35238bceSAndroid Build Coastguard Worker << ((!m_hasGeometryStage) ? ("v_bbox_expansionSize = pointSize;\n") : ("")) << " v_"
2905*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2906*35238bceSAndroid Build Coastguard Worker << "bbox_clipMin = vp_bbox_clipMin;\n"
2907*35238bceSAndroid Build Coastguard Worker " v_"
2908*35238bceSAndroid Build Coastguard Worker << (m_hasGeometryStage ? "geo_" : "")
2909*35238bceSAndroid Build Coastguard Worker << "bbox_clipMax = vp_bbox_clipMax;\n"
2910*35238bceSAndroid Build Coastguard Worker "}\n";
2911*35238bceSAndroid Build Coastguard Worker
2912*35238bceSAndroid Build Coastguard Worker return buf.str();
2913*35238bceSAndroid Build Coastguard Worker }
2914*35238bceSAndroid Build Coastguard Worker
genGeometrySource(void) const2915*35238bceSAndroid Build Coastguard Worker std::string PointRenderCase::genGeometrySource(void) const
2916*35238bceSAndroid Build Coastguard Worker {
2917*35238bceSAndroid Build Coastguard Worker const char *const colorInputName = (m_hasTessellationStage) ? ("tess_color") : ("vtx_color");
2918*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2919*35238bceSAndroid Build Coastguard Worker
2920*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2921*35238bceSAndroid Build Coastguard Worker "${GEOMETRY_SHADER_REQUIRE}\n"
2922*35238bceSAndroid Build Coastguard Worker << ((m_isWidePointCase) ? ("${GEOMETRY_POINT_SIZE}\n") : (""))
2923*35238bceSAndroid Build Coastguard Worker << "layout(points) in;\n"
2924*35238bceSAndroid Build Coastguard Worker "layout(max_vertices=3, points) out;\n"
2925*35238bceSAndroid Build Coastguard Worker "\n"
2926*35238bceSAndroid Build Coastguard Worker "in highp vec4 "
2927*35238bceSAndroid Build Coastguard Worker << colorInputName
2928*35238bceSAndroid Build Coastguard Worker << "[1];\n"
2929*35238bceSAndroid Build Coastguard Worker "out highp vec4 geo_color;\n"
2930*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_posScale;\n"
2931*35238bceSAndroid Build Coastguard Worker "\n"
2932*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMin[1];\n"
2933*35238bceSAndroid Build Coastguard Worker "flat in highp vec3 v_geo_bbox_clipMax[1];\n"
2934*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMin;\n"
2935*35238bceSAndroid Build Coastguard Worker "flat out highp vec3 v_bbox_clipMax;\n"
2936*35238bceSAndroid Build Coastguard Worker "flat out highp float v_bbox_expansionSize;\n"
2937*35238bceSAndroid Build Coastguard Worker "\n"
2938*35238bceSAndroid Build Coastguard Worker << genShaderFunction(SHADER_FUNC_MIRROR_X)
2939*35238bceSAndroid Build Coastguard Worker << "\n"
2940*35238bceSAndroid Build Coastguard Worker "void main()\n"
2941*35238bceSAndroid Build Coastguard Worker "{\n"
2942*35238bceSAndroid Build Coastguard Worker " // Non-trivial geometry shader: 1-to-3 amplification, mirror horizontally\n"
2943*35238bceSAndroid Build Coastguard Worker " highp vec4 p0 = mirrorX(gl_in[0].gl_Position);\n"
2944*35238bceSAndroid Build Coastguard Worker " highp vec4 pointColor = "
2945*35238bceSAndroid Build Coastguard Worker << colorInputName
2946*35238bceSAndroid Build Coastguard Worker << "[0];\n"
2947*35238bceSAndroid Build Coastguard Worker " highp vec2 patternScale = u_posScale.zw;\n"
2948*35238bceSAndroid Build Coastguard Worker " highp float pointSize = "
2949*35238bceSAndroid Build Coastguard Worker << (m_isWidePointCase ? ("(pointColor.g > 0.0) ? (5.0) : (3.0)") : ("1.0"))
2950*35238bceSAndroid Build Coastguard Worker << ";\n"
2951*35238bceSAndroid Build Coastguard Worker "\n"
2952*35238bceSAndroid Build Coastguard Worker " highp vec4 offsets[3] =\n"
2953*35238bceSAndroid Build Coastguard Worker " vec4[3](\n"
2954*35238bceSAndroid Build Coastguard Worker " vec4( 0.05 * patternScale.x, 0.03 * patternScale.y, 0.0, 0.0),\n"
2955*35238bceSAndroid Build Coastguard Worker " vec4(-0.01 * patternScale.x,-0.02 * patternScale.y, 0.0, 0.0),\n"
2956*35238bceSAndroid Build Coastguard Worker " vec4(-0.05 * patternScale.x, 0.02 * patternScale.y, 0.0, 0.0)\n"
2957*35238bceSAndroid Build Coastguard Worker " );\n"
2958*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < 3; ++ndx)\n"
2959*35238bceSAndroid Build Coastguard Worker " {\n"
2960*35238bceSAndroid Build Coastguard Worker " gl_Position = p0 + offsets[ndx];\n";
2961*35238bceSAndroid Build Coastguard Worker
2962*35238bceSAndroid Build Coastguard Worker if (m_isWidePointCase)
2963*35238bceSAndroid Build Coastguard Worker buf << " gl_PointSize = pointSize;\n";
2964*35238bceSAndroid Build Coastguard Worker
2965*35238bceSAndroid Build Coastguard Worker buf << " v_bbox_clipMin = v_geo_bbox_clipMin[0];\n"
2966*35238bceSAndroid Build Coastguard Worker " v_bbox_clipMax = v_geo_bbox_clipMax[0];\n"
2967*35238bceSAndroid Build Coastguard Worker " v_bbox_expansionSize = pointSize;\n"
2968*35238bceSAndroid Build Coastguard Worker " geo_color = pointColor;\n"
2969*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2970*35238bceSAndroid Build Coastguard Worker " }\n"
2971*35238bceSAndroid Build Coastguard Worker "}\n";
2972*35238bceSAndroid Build Coastguard Worker
2973*35238bceSAndroid Build Coastguard Worker return buf.str();
2974*35238bceSAndroid Build Coastguard Worker }
2975*35238bceSAndroid Build Coastguard Worker
generateConfig(int iteration,const tcu::IVec2 & renderTargetSize) const2976*35238bceSAndroid Build Coastguard Worker PointRenderCase::IterationConfig PointRenderCase::generateConfig(int iteration,
2977*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &renderTargetSize) const
2978*35238bceSAndroid Build Coastguard Worker {
2979*35238bceSAndroid Build Coastguard Worker IterationConfig config = generateRandomConfig(0xDEDEDEu * (uint32_t)iteration, renderTargetSize);
2980*35238bceSAndroid Build Coastguard Worker
2981*35238bceSAndroid Build Coastguard Worker // equal or larger -> expand according to shader expansion
2982*35238bceSAndroid Build Coastguard Worker if (m_bboxSize == BBOXSIZE_EQUAL || m_bboxSize == BBOXSIZE_LARGER)
2983*35238bceSAndroid Build Coastguard Worker {
2984*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 patternScale = config.patternSize;
2985*35238bceSAndroid Build Coastguard Worker
2986*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
2987*35238bceSAndroid Build Coastguard Worker {
2988*35238bceSAndroid Build Coastguard Worker config.bbox.min -= tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
2989*35238bceSAndroid Build Coastguard Worker config.bbox.max += tcu::Vec4(0.07f * patternScale.x(), 0.07f * patternScale.y(), 0.0f, 0.0f);
2990*35238bceSAndroid Build Coastguard Worker }
2991*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
2992*35238bceSAndroid Build Coastguard Worker {
2993*35238bceSAndroid Build Coastguard Worker config.bbox.min -= tcu::Vec4(0.05f * patternScale.x(), 0.02f * patternScale.y(), 0.0f, 0.0f);
2994*35238bceSAndroid Build Coastguard Worker config.bbox.max += tcu::Vec4(0.05f * patternScale.x(), 0.03f * patternScale.y(), 0.0f, 0.0f);
2995*35238bceSAndroid Build Coastguard Worker }
2996*35238bceSAndroid Build Coastguard Worker }
2997*35238bceSAndroid Build Coastguard Worker
2998*35238bceSAndroid Build Coastguard Worker return config;
2999*35238bceSAndroid Build Coastguard Worker }
3000*35238bceSAndroid Build Coastguard Worker
generateAttributeData(void)3001*35238bceSAndroid Build Coastguard Worker void PointRenderCase::generateAttributeData(void)
3002*35238bceSAndroid Build Coastguard Worker {
3003*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
3004*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
3005*35238bceSAndroid Build Coastguard Worker std::vector<int> cellOrder(m_numStripes * m_numStripes * 2);
3006*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xDE22446);
3007*35238bceSAndroid Build Coastguard Worker
3008*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
3009*35238bceSAndroid Build Coastguard Worker cellOrder[ndx] = ndx;
3010*35238bceSAndroid Build Coastguard Worker rnd.shuffle(cellOrder.begin(), cellOrder.end());
3011*35238bceSAndroid Build Coastguard Worker
3012*35238bceSAndroid Build Coastguard Worker m_attribData.resize(cellOrder.size() * 2);
3013*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
3014*35238bceSAndroid Build Coastguard Worker {
3015*35238bceSAndroid Build Coastguard Worker const int pointID = cellOrder[ndx];
3016*35238bceSAndroid Build Coastguard Worker const int direction = pointID & 0x01;
3017*35238bceSAndroid Build Coastguard Worker const int majorCoord = (pointID >> 1) / m_numStripes;
3018*35238bceSAndroid Build Coastguard Worker const int minorCoord = (pointID >> 1) % m_numStripes;
3019*35238bceSAndroid Build Coastguard Worker
3020*35238bceSAndroid Build Coastguard Worker if (direction)
3021*35238bceSAndroid Build Coastguard Worker {
3022*35238bceSAndroid Build Coastguard Worker m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
3023*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(minorCoord) / float(m_numStripes), float(majorCoord) / float(m_numStripes), 0.0f, 1.0f);
3024*35238bceSAndroid Build Coastguard Worker m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = green;
3025*35238bceSAndroid Build Coastguard Worker }
3026*35238bceSAndroid Build Coastguard Worker else
3027*35238bceSAndroid Build Coastguard Worker {
3028*35238bceSAndroid Build Coastguard Worker m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_POS_VEC_NDX] =
3029*35238bceSAndroid Build Coastguard Worker tcu::Vec4(((float)majorCoord + 0.5f) / float(m_numStripes),
3030*35238bceSAndroid Build Coastguard Worker ((float)minorCoord + 0.5f) / float(m_numStripes), 0.0f, 1.0f);
3031*35238bceSAndroid Build Coastguard Worker m_attribData[ndx * VA_NUM_ATTRIB_VECS + VA_COL_VEC_NDX] = blue;
3032*35238bceSAndroid Build Coastguard Worker }
3033*35238bceSAndroid Build Coastguard Worker }
3034*35238bceSAndroid Build Coastguard Worker }
3035*35238bceSAndroid Build Coastguard Worker
getAttributeData(std::vector<tcu::Vec4> & data) const3036*35238bceSAndroid Build Coastguard Worker void PointRenderCase::getAttributeData(std::vector<tcu::Vec4> &data) const
3037*35238bceSAndroid Build Coastguard Worker {
3038*35238bceSAndroid Build Coastguard Worker data = m_attribData;
3039*35238bceSAndroid Build Coastguard Worker }
3040*35238bceSAndroid Build Coastguard Worker
renderTestPattern(const IterationConfig & config)3041*35238bceSAndroid Build Coastguard Worker void PointRenderCase::renderTestPattern(const IterationConfig &config)
3042*35238bceSAndroid Build Coastguard Worker {
3043*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3044*35238bceSAndroid Build Coastguard Worker
3045*35238bceSAndroid Build Coastguard Worker setupRender(config);
3046*35238bceSAndroid Build Coastguard Worker
3047*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
3048*35238bceSAndroid Build Coastguard Worker {
3049*35238bceSAndroid Build Coastguard Worker const glw::GLint tessLevelPos = gl.getUniformLocation(m_program->getProgram(), "u_tessellationLevel");
3050*35238bceSAndroid Build Coastguard Worker const glw::GLfloat tessLevel = 0.8f; // will be rounded up
3051*35238bceSAndroid Build Coastguard Worker
3052*35238bceSAndroid Build Coastguard Worker TCU_CHECK(tessLevelPos != -1);
3053*35238bceSAndroid Build Coastguard Worker
3054*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "u_tessellationLevel = " << tessLevel
3055*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3056*35238bceSAndroid Build Coastguard Worker
3057*35238bceSAndroid Build Coastguard Worker gl.uniform1f(tessLevelPos, tessLevel);
3058*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 1);
3059*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "patch param");
3060*35238bceSAndroid Build Coastguard Worker }
3061*35238bceSAndroid Build Coastguard Worker
3062*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering pattern." << tcu::TestLog::EndMessage;
3063*35238bceSAndroid Build Coastguard Worker
3064*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
3065*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_ONE, GL_ONE);
3066*35238bceSAndroid Build Coastguard Worker gl.blendEquation(GL_FUNC_ADD);
3067*35238bceSAndroid Build Coastguard Worker
3068*35238bceSAndroid Build Coastguard Worker gl.drawArrays((m_hasTessellationStage) ? (GL_PATCHES) : (GL_POINTS), 0, m_numStripes * m_numStripes * 2);
3069*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
3070*35238bceSAndroid Build Coastguard Worker }
3071*35238bceSAndroid Build Coastguard Worker
verifyRenderResult(const IterationConfig & config)3072*35238bceSAndroid Build Coastguard Worker void PointRenderCase::verifyRenderResult(const IterationConfig &config)
3073*35238bceSAndroid Build Coastguard Worker {
3074*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3075*35238bceSAndroid Build Coastguard Worker const ProjectedBBox projectedBBox = projectBoundingBox(config.bbox);
3076*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportBBoxArea = getViewportBoundingBoxArea(projectedBBox, config.viewportSize);
3077*35238bceSAndroid Build Coastguard Worker
3078*35238bceSAndroid Build Coastguard Worker tcu::Surface viewportSurface(config.viewportSize.x(), config.viewportSize.y());
3079*35238bceSAndroid Build Coastguard Worker int logFloodCounter = 8;
3080*35238bceSAndroid Build Coastguard Worker bool anyError;
3081*35238bceSAndroid Build Coastguard Worker std::vector<GeneratedPoint> refPoints;
3082*35238bceSAndroid Build Coastguard Worker
3083*35238bceSAndroid Build Coastguard Worker if (!m_calcPerPrimitiveBBox)
3084*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Projected bounding box: (clip space)\n"
3085*35238bceSAndroid Build Coastguard Worker << "\tx: [" << projectedBBox.min.x() << "," << projectedBBox.max.x() << "]\n"
3086*35238bceSAndroid Build Coastguard Worker << "\ty: [" << projectedBBox.min.y() << "," << projectedBBox.max.y() << "]\n"
3087*35238bceSAndroid Build Coastguard Worker << "\tz: [" << projectedBBox.min.z() << "," << projectedBBox.max.z() << "]\n"
3088*35238bceSAndroid Build Coastguard Worker << "In viewport coordinates:\n"
3089*35238bceSAndroid Build Coastguard Worker << "\tx: [" << viewportBBoxArea.x() << ", " << viewportBBoxArea.z() << "]\n"
3090*35238bceSAndroid Build Coastguard Worker << "\ty: [" << viewportBBoxArea.y() << ", " << viewportBBoxArea.w() << "]\n"
3091*35238bceSAndroid Build Coastguard Worker << "Verifying render results within the bounding box:\n"
3092*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3093*35238bceSAndroid Build Coastguard Worker else
3094*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying render result:" << tcu::TestLog::EndMessage;
3095*35238bceSAndroid Build Coastguard Worker
3096*35238bceSAndroid Build Coastguard Worker if (m_fbo)
3097*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER, **m_fbo);
3098*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), config.viewportPos.x(), config.viewportPos.y(),
3099*35238bceSAndroid Build Coastguard Worker viewportSurface.getAccess());
3100*35238bceSAndroid Build Coastguard Worker
3101*35238bceSAndroid Build Coastguard Worker genReferencePointData(config, refPoints);
3102*35238bceSAndroid Build Coastguard Worker
3103*35238bceSAndroid Build Coastguard Worker if (m_isWidePointCase)
3104*35238bceSAndroid Build Coastguard Worker anyError = verifyWidePointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);
3105*35238bceSAndroid Build Coastguard Worker else
3106*35238bceSAndroid Build Coastguard Worker anyError = verifyNarrowPointPattern(viewportSurface, refPoints, projectedBBox, logFloodCounter);
3107*35238bceSAndroid Build Coastguard Worker
3108*35238bceSAndroid Build Coastguard Worker if (anyError)
3109*35238bceSAndroid Build Coastguard Worker {
3110*35238bceSAndroid Build Coastguard Worker if (logFloodCounter < 0)
3111*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-logFloodCounter) << " error descriptions."
3112*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3113*35238bceSAndroid Build Coastguard Worker
3114*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
3115*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
3116*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
3117*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
3118*35238bceSAndroid Build Coastguard Worker
3119*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
3120*35238bceSAndroid Build Coastguard Worker }
3121*35238bceSAndroid Build Coastguard Worker else
3122*35238bceSAndroid Build Coastguard Worker {
3123*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result image ok." << tcu::TestLog::EndMessage
3124*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
3125*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewportSurface.getAccess())
3126*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
3127*35238bceSAndroid Build Coastguard Worker }
3128*35238bceSAndroid Build Coastguard Worker }
3129*35238bceSAndroid Build Coastguard Worker
3130*35238bceSAndroid Build Coastguard Worker struct PointSorter
3131*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gles31::Functional::__anon39b763e60111::PointSorter3132*35238bceSAndroid Build Coastguard Worker bool operator()(const PointRenderCase::GeneratedPoint &a, const PointRenderCase::GeneratedPoint &b) const
3133*35238bceSAndroid Build Coastguard Worker {
3134*35238bceSAndroid Build Coastguard Worker if (a.center.y() < b.center.y())
3135*35238bceSAndroid Build Coastguard Worker return true;
3136*35238bceSAndroid Build Coastguard Worker else if (a.center.y() > b.center.y())
3137*35238bceSAndroid Build Coastguard Worker return false;
3138*35238bceSAndroid Build Coastguard Worker else
3139*35238bceSAndroid Build Coastguard Worker return (a.center.x() < b.center.x());
3140*35238bceSAndroid Build Coastguard Worker }
3141*35238bceSAndroid Build Coastguard Worker };
3142*35238bceSAndroid Build Coastguard Worker
genReferencePointData(const IterationConfig & config,std::vector<GeneratedPoint> & data) const3143*35238bceSAndroid Build Coastguard Worker void PointRenderCase::genReferencePointData(const IterationConfig &config, std::vector<GeneratedPoint> &data) const
3144*35238bceSAndroid Build Coastguard Worker {
3145*35238bceSAndroid Build Coastguard Worker std::vector<GeneratedPoint> currentPoints;
3146*35238bceSAndroid Build Coastguard Worker
3147*35238bceSAndroid Build Coastguard Worker // vertex shader
3148*35238bceSAndroid Build Coastguard Worker currentPoints.resize(m_attribData.size() / 2);
3149*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
3150*35238bceSAndroid Build Coastguard Worker {
3151*35238bceSAndroid Build Coastguard Worker currentPoints[ndx].center = m_attribData[ndx * 2].swizzle(0, 1);
3152*35238bceSAndroid Build Coastguard Worker currentPoints[ndx].even = (m_attribData[ndx * 2 + 1].y() == 1.0f); // is green
3153*35238bceSAndroid Build Coastguard Worker currentPoints[ndx].size = ((m_isWidePointCase) ? ((currentPoints[ndx].even) ? 5 : 3) : 1);
3154*35238bceSAndroid Build Coastguard Worker }
3155*35238bceSAndroid Build Coastguard Worker
3156*35238bceSAndroid Build Coastguard Worker // tessellation
3157*35238bceSAndroid Build Coastguard Worker if (m_hasTessellationStage)
3158*35238bceSAndroid Build Coastguard Worker {
3159*35238bceSAndroid Build Coastguard Worker std::vector<GeneratedPoint> tessellatedPoints;
3160*35238bceSAndroid Build Coastguard Worker
3161*35238bceSAndroid Build Coastguard Worker tessellatedPoints.resize(currentPoints.size() * 4);
3162*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
3163*35238bceSAndroid Build Coastguard Worker {
3164*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 position =
3165*35238bceSAndroid Build Coastguard Worker tcu::Vec2(currentPoints[ndx].center.x(), 1.0f - currentPoints[ndx].center.y()); // mirror Y
3166*35238bceSAndroid Build Coastguard Worker
3167*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 0].center = position + tcu::Vec2(-0.07f, -0.07f);
3168*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 0].size = currentPoints[ndx].size;
3169*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 0].even = currentPoints[ndx].even;
3170*35238bceSAndroid Build Coastguard Worker
3171*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 1].center = position + tcu::Vec2(0.07f, -0.07f);
3172*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 1].size = currentPoints[ndx].size;
3173*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 1].even = currentPoints[ndx].even;
3174*35238bceSAndroid Build Coastguard Worker
3175*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 2].center = position + tcu::Vec2(0.07f, 0.07f);
3176*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 2].size = currentPoints[ndx].size;
3177*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 2].even = currentPoints[ndx].even;
3178*35238bceSAndroid Build Coastguard Worker
3179*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 3].center = position + tcu::Vec2(-0.07f, 0.07f);
3180*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 3].size = currentPoints[ndx].size;
3181*35238bceSAndroid Build Coastguard Worker tessellatedPoints[4 * ndx + 3].even = currentPoints[ndx].even;
3182*35238bceSAndroid Build Coastguard Worker }
3183*35238bceSAndroid Build Coastguard Worker
3184*35238bceSAndroid Build Coastguard Worker currentPoints.swap(tessellatedPoints);
3185*35238bceSAndroid Build Coastguard Worker }
3186*35238bceSAndroid Build Coastguard Worker
3187*35238bceSAndroid Build Coastguard Worker // geometry
3188*35238bceSAndroid Build Coastguard Worker if (m_hasGeometryStage)
3189*35238bceSAndroid Build Coastguard Worker {
3190*35238bceSAndroid Build Coastguard Worker std::vector<GeneratedPoint> geometryShadedPoints;
3191*35238bceSAndroid Build Coastguard Worker
3192*35238bceSAndroid Build Coastguard Worker geometryShadedPoints.resize(currentPoints.size() * 3);
3193*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
3194*35238bceSAndroid Build Coastguard Worker {
3195*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 position =
3196*35238bceSAndroid Build Coastguard Worker tcu::Vec2(1.0f - currentPoints[ndx].center.x(), currentPoints[ndx].center.y()); // mirror X
3197*35238bceSAndroid Build Coastguard Worker
3198*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 0].center = position + tcu::Vec2(0.05f, 0.03f);
3199*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 0].size = currentPoints[ndx].size;
3200*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 0].even = currentPoints[ndx].even;
3201*35238bceSAndroid Build Coastguard Worker
3202*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 1].center = position + tcu::Vec2(-0.01f, -0.02f);
3203*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 1].size = currentPoints[ndx].size;
3204*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 1].even = currentPoints[ndx].even;
3205*35238bceSAndroid Build Coastguard Worker
3206*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 2].center = position + tcu::Vec2(-0.05f, 0.02f);
3207*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 2].size = currentPoints[ndx].size;
3208*35238bceSAndroid Build Coastguard Worker geometryShadedPoints[3 * ndx + 2].even = currentPoints[ndx].even;
3209*35238bceSAndroid Build Coastguard Worker }
3210*35238bceSAndroid Build Coastguard Worker
3211*35238bceSAndroid Build Coastguard Worker currentPoints.swap(geometryShadedPoints);
3212*35238bceSAndroid Build Coastguard Worker }
3213*35238bceSAndroid Build Coastguard Worker
3214*35238bceSAndroid Build Coastguard Worker // sort from left to right, top to bottom
3215*35238bceSAndroid Build Coastguard Worker std::sort(currentPoints.begin(), currentPoints.end(), PointSorter());
3216*35238bceSAndroid Build Coastguard Worker
3217*35238bceSAndroid Build Coastguard Worker // map to pattern space
3218*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)currentPoints.size(); ++ndx)
3219*35238bceSAndroid Build Coastguard Worker currentPoints[ndx].center = currentPoints[ndx].center * config.patternSize + config.patternPos;
3220*35238bceSAndroid Build Coastguard Worker
3221*35238bceSAndroid Build Coastguard Worker currentPoints.swap(data);
3222*35238bceSAndroid Build Coastguard Worker }
3223*35238bceSAndroid Build Coastguard Worker
verifyNarrowPointPattern(const tcu::Surface & viewport,const std::vector<GeneratedPoint> & refPoints,const ProjectedBBox & bbox,int & logFloodCounter)3224*35238bceSAndroid Build Coastguard Worker bool PointRenderCase::verifyNarrowPointPattern(const tcu::Surface &viewport,
3225*35238bceSAndroid Build Coastguard Worker const std::vector<GeneratedPoint> &refPoints, const ProjectedBBox &bbox,
3226*35238bceSAndroid Build Coastguard Worker int &logFloodCounter)
3227*35238bceSAndroid Build Coastguard Worker {
3228*35238bceSAndroid Build Coastguard Worker bool anyError = false;
3229*35238bceSAndroid Build Coastguard Worker
3230*35238bceSAndroid Build Coastguard Worker // check that there is something near each sample
3231*35238bceSAndroid Build Coastguard Worker for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
3232*35238bceSAndroid Build Coastguard Worker {
3233*35238bceSAndroid Build Coastguard Worker const float epsilon = 1.0e-6f;
3234*35238bceSAndroid Build Coastguard Worker const GeneratedPoint &refPoint = refPoints[pointNdx];
3235*35238bceSAndroid Build Coastguard Worker
3236*35238bceSAndroid Build Coastguard Worker // skip points not in the the bbox, treat boundary as "in"
3237*35238bceSAndroid Build Coastguard Worker if (refPoint.center.x() < bbox.min.x() - epsilon || refPoint.center.y() < bbox.min.y() - epsilon ||
3238*35238bceSAndroid Build Coastguard Worker refPoint.center.x() > bbox.max.x() + epsilon || refPoint.center.y() > bbox.max.y() + epsilon)
3239*35238bceSAndroid Build Coastguard Worker continue;
3240*35238bceSAndroid Build Coastguard Worker else
3241*35238bceSAndroid Build Coastguard Worker {
3242*35238bceSAndroid Build Coastguard Worker // transform to viewport coords
3243*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 pixelCenter(
3244*35238bceSAndroid Build Coastguard Worker deRoundFloatToInt32((refPoint.center.x() * 0.5f + 0.5f) * (float)viewport.getWidth()),
3245*35238bceSAndroid Build Coastguard Worker deRoundFloatToInt32((refPoint.center.y() * 0.5f + 0.5f) * (float)viewport.getHeight()));
3246*35238bceSAndroid Build Coastguard Worker
3247*35238bceSAndroid Build Coastguard Worker // find rasterized point in the result
3248*35238bceSAndroid Build Coastguard Worker if (pixelCenter.x() < 1 || pixelCenter.y() < 1 || pixelCenter.x() >= viewport.getWidth() - 1 ||
3249*35238bceSAndroid Build Coastguard Worker pixelCenter.y() >= viewport.getHeight() - 1)
3250*35238bceSAndroid Build Coastguard Worker {
3251*35238bceSAndroid Build Coastguard Worker // viewport boundary, assume point is fine
3252*35238bceSAndroid Build Coastguard Worker }
3253*35238bceSAndroid Build Coastguard Worker else
3254*35238bceSAndroid Build Coastguard Worker {
3255*35238bceSAndroid Build Coastguard Worker const int componentNdx = (refPoint.even) ? (1) : (2); // analyze either green or blue channel
3256*35238bceSAndroid Build Coastguard Worker bool foundResult = false;
3257*35238bceSAndroid Build Coastguard Worker
3258*35238bceSAndroid Build Coastguard Worker // check neighborhood
3259*35238bceSAndroid Build Coastguard Worker for (int dy = -1; dy < 2 && !foundResult; ++dy)
3260*35238bceSAndroid Build Coastguard Worker for (int dx = -1; dx < 2 && !foundResult; ++dx)
3261*35238bceSAndroid Build Coastguard Worker {
3262*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 testPos(pixelCenter.x() + dx, pixelCenter.y() + dy);
3263*35238bceSAndroid Build Coastguard Worker const tcu::RGBA color = viewport.getPixel(testPos.x(), testPos.y());
3264*35238bceSAndroid Build Coastguard Worker
3265*35238bceSAndroid Build Coastguard Worker if (color.toIVec()[componentNdx] > 0)
3266*35238bceSAndroid Build Coastguard Worker foundResult = true;
3267*35238bceSAndroid Build Coastguard Worker }
3268*35238bceSAndroid Build Coastguard Worker
3269*35238bceSAndroid Build Coastguard Worker if (!foundResult)
3270*35238bceSAndroid Build Coastguard Worker {
3271*35238bceSAndroid Build Coastguard Worker anyError = true;
3272*35238bceSAndroid Build Coastguard Worker
3273*35238bceSAndroid Build Coastguard Worker if (--logFloodCounter >= 0)
3274*35238bceSAndroid Build Coastguard Worker {
3275*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Missing point near " << pixelCenter
3276*35238bceSAndroid Build Coastguard Worker << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
3277*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3278*35238bceSAndroid Build Coastguard Worker }
3279*35238bceSAndroid Build Coastguard Worker }
3280*35238bceSAndroid Build Coastguard Worker }
3281*35238bceSAndroid Build Coastguard Worker }
3282*35238bceSAndroid Build Coastguard Worker }
3283*35238bceSAndroid Build Coastguard Worker
3284*35238bceSAndroid Build Coastguard Worker return anyError;
3285*35238bceSAndroid Build Coastguard Worker }
3286*35238bceSAndroid Build Coastguard Worker
verifyWidePointPattern(const tcu::Surface & viewport,const std::vector<GeneratedPoint> & refPoints,const ProjectedBBox & bbox,int & logFloodCounter)3287*35238bceSAndroid Build Coastguard Worker bool PointRenderCase::verifyWidePointPattern(const tcu::Surface &viewport, const std::vector<GeneratedPoint> &refPoints,
3288*35238bceSAndroid Build Coastguard Worker const ProjectedBBox &bbox, int &logFloodCounter)
3289*35238bceSAndroid Build Coastguard Worker {
3290*35238bceSAndroid Build Coastguard Worker bool anyError = false;
3291*35238bceSAndroid Build Coastguard Worker
3292*35238bceSAndroid Build Coastguard Worker // check that there is something near each sample
3293*35238bceSAndroid Build Coastguard Worker for (int pointNdx = 0; pointNdx < (int)refPoints.size(); ++pointNdx)
3294*35238bceSAndroid Build Coastguard Worker {
3295*35238bceSAndroid Build Coastguard Worker const GeneratedPoint &refPoint = refPoints[pointNdx];
3296*35238bceSAndroid Build Coastguard Worker
3297*35238bceSAndroid Build Coastguard Worker if (refPoint.center.x() >= bbox.min.x() && refPoint.center.y() >= bbox.min.y() &&
3298*35238bceSAndroid Build Coastguard Worker refPoint.center.x() <= bbox.max.x() && refPoint.center.y() <= bbox.max.y())
3299*35238bceSAndroid Build Coastguard Worker {
3300*35238bceSAndroid Build Coastguard Worker // point fully in the bounding box
3301*35238bceSAndroid Build Coastguard Worker anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_FULL, logFloodCounter);
3302*35238bceSAndroid Build Coastguard Worker }
3303*35238bceSAndroid Build Coastguard Worker else if (refPoint.center.x() >= bbox.min.x() + (float)refPoint.size / 2.0f &&
3304*35238bceSAndroid Build Coastguard Worker refPoint.center.y() >= bbox.min.y() - (float)refPoint.size / 2.0f &&
3305*35238bceSAndroid Build Coastguard Worker refPoint.center.x() <= bbox.max.x() + (float)refPoint.size / 2.0f &&
3306*35238bceSAndroid Build Coastguard Worker refPoint.center.y() <= bbox.max.y() - (float)refPoint.size / 2.0f)
3307*35238bceSAndroid Build Coastguard Worker {
3308*35238bceSAndroid Build Coastguard Worker // point leaks into bounding box
3309*35238bceSAndroid Build Coastguard Worker anyError |= !verifyWidePoint(viewport, refPoint, bbox, POINT_PARTIAL, logFloodCounter);
3310*35238bceSAndroid Build Coastguard Worker }
3311*35238bceSAndroid Build Coastguard Worker }
3312*35238bceSAndroid Build Coastguard Worker
3313*35238bceSAndroid Build Coastguard Worker return anyError;
3314*35238bceSAndroid Build Coastguard Worker }
3315*35238bceSAndroid Build Coastguard Worker
verifyWidePoint(const tcu::Surface & viewport,const GeneratedPoint & refPoint,const ProjectedBBox & bbox,ResultPointType pointType,int & logFloodCounter)3316*35238bceSAndroid Build Coastguard Worker bool PointRenderCase::verifyWidePoint(const tcu::Surface &viewport, const GeneratedPoint &refPoint,
3317*35238bceSAndroid Build Coastguard Worker const ProjectedBBox &bbox, ResultPointType pointType, int &logFloodCounter)
3318*35238bceSAndroid Build Coastguard Worker {
3319*35238bceSAndroid Build Coastguard Worker const int componentNdx = (refPoint.even) ? (1) : (2);
3320*35238bceSAndroid Build Coastguard Worker const int halfPointSizeCeil = (refPoint.size + 1) / 2;
3321*35238bceSAndroid Build Coastguard Worker const int halfPointSizeFloor = (refPoint.size + 1) / 2;
3322*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 viewportBBoxArea =
3323*35238bceSAndroid Build Coastguard Worker getViewportBoundingBoxArea(bbox, tcu::IVec2(viewport.getWidth(), viewport.getHeight()), (float)refPoint.size);
3324*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 verificationArea = tcu::IVec4(de::max(viewportBBoxArea.x(), 0), de::max(viewportBBoxArea.y(), 0),
3325*35238bceSAndroid Build Coastguard Worker de::min(viewportBBoxArea.z(), viewport.getWidth()),
3326*35238bceSAndroid Build Coastguard Worker de::min(viewportBBoxArea.w(), viewport.getHeight()));
3327*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 pointPos =
3328*35238bceSAndroid Build Coastguard Worker tcu::IVec2(deRoundFloatToInt32((refPoint.center.x() * 0.5f + 0.5f) * (float)viewport.getWidth()),
3329*35238bceSAndroid Build Coastguard Worker deRoundFloatToInt32((refPoint.center.y() * 0.5f + 0.5f) * (float)viewport.getHeight()));
3330*35238bceSAndroid Build Coastguard Worker
3331*35238bceSAndroid Build Coastguard Worker // find any fragment within the point that is inside the bbox, start search at the center
3332*35238bceSAndroid Build Coastguard Worker
3333*35238bceSAndroid Build Coastguard Worker if (pointPos.x() >= verificationArea.x() && pointPos.y() >= verificationArea.y() &&
3334*35238bceSAndroid Build Coastguard Worker pointPos.x() < verificationArea.z() && pointPos.y() < verificationArea.w())
3335*35238bceSAndroid Build Coastguard Worker {
3336*35238bceSAndroid Build Coastguard Worker if (viewport.getPixel(pointPos.x(), pointPos.y()).toIVec()[componentNdx])
3337*35238bceSAndroid Build Coastguard Worker return verifyWidePointAt(pointPos, viewport, refPoint, verificationArea, pointType, componentNdx,
3338*35238bceSAndroid Build Coastguard Worker logFloodCounter);
3339*35238bceSAndroid Build Coastguard Worker }
3340*35238bceSAndroid Build Coastguard Worker
3341*35238bceSAndroid Build Coastguard Worker for (int dy = -halfPointSizeCeil; dy <= halfPointSizeCeil; ++dy)
3342*35238bceSAndroid Build Coastguard Worker for (int dx = -halfPointSizeCeil; dx <= halfPointSizeCeil; ++dx)
3343*35238bceSAndroid Build Coastguard Worker {
3344*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 testPos = pointPos + tcu::IVec2(dx, dy);
3345*35238bceSAndroid Build Coastguard Worker
3346*35238bceSAndroid Build Coastguard Worker if (dx == 0 && dy == 0)
3347*35238bceSAndroid Build Coastguard Worker continue;
3348*35238bceSAndroid Build Coastguard Worker
3349*35238bceSAndroid Build Coastguard Worker if (testPos.x() >= verificationArea.x() && testPos.y() >= verificationArea.y() &&
3350*35238bceSAndroid Build Coastguard Worker testPos.x() < verificationArea.z() && testPos.y() < verificationArea.w())
3351*35238bceSAndroid Build Coastguard Worker {
3352*35238bceSAndroid Build Coastguard Worker if (viewport.getPixel(testPos.x(), testPos.y()).toIVec()[componentNdx])
3353*35238bceSAndroid Build Coastguard Worker return verifyWidePointAt(testPos, viewport, refPoint, verificationArea, pointType, componentNdx,
3354*35238bceSAndroid Build Coastguard Worker logFloodCounter);
3355*35238bceSAndroid Build Coastguard Worker }
3356*35238bceSAndroid Build Coastguard Worker }
3357*35238bceSAndroid Build Coastguard Worker
3358*35238bceSAndroid Build Coastguard Worker // could not find point, this is only ok near boundaries
3359*35238bceSAndroid Build Coastguard Worker if (pointPos.x() + halfPointSizeFloor < verificationArea.x() - 1 ||
3360*35238bceSAndroid Build Coastguard Worker pointPos.y() + halfPointSizeFloor < verificationArea.y() - 1 ||
3361*35238bceSAndroid Build Coastguard Worker pointPos.x() - halfPointSizeFloor >= verificationArea.z() - 1 ||
3362*35238bceSAndroid Build Coastguard Worker pointPos.y() - halfPointSizeFloor >= verificationArea.w() - 1)
3363*35238bceSAndroid Build Coastguard Worker return true;
3364*35238bceSAndroid Build Coastguard Worker
3365*35238bceSAndroid Build Coastguard Worker if (--logFloodCounter >= 0)
3366*35238bceSAndroid Build Coastguard Worker {
3367*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Missing wide point near " << pointPos
3368*35238bceSAndroid Build Coastguard Worker << ", vertex coordinates=" << refPoint.center.swizzle(0, 1) << "."
3369*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3370*35238bceSAndroid Build Coastguard Worker }
3371*35238bceSAndroid Build Coastguard Worker
3372*35238bceSAndroid Build Coastguard Worker return false;
3373*35238bceSAndroid Build Coastguard Worker }
3374*35238bceSAndroid Build Coastguard Worker
verifyWidePointAt(const tcu::IVec2 & pointPos,const tcu::Surface & viewport,const GeneratedPoint & refPoint,const tcu::IVec4 & bbox,ResultPointType pointType,int componentNdx,int & logFloodCounter)3375*35238bceSAndroid Build Coastguard Worker bool PointRenderCase::verifyWidePointAt(const tcu::IVec2 &pointPos, const tcu::Surface &viewport,
3376*35238bceSAndroid Build Coastguard Worker const GeneratedPoint &refPoint, const tcu::IVec4 &bbox,
3377*35238bceSAndroid Build Coastguard Worker ResultPointType pointType, int componentNdx, int &logFloodCounter)
3378*35238bceSAndroid Build Coastguard Worker {
3379*35238bceSAndroid Build Coastguard Worker const int expectedPointSize = refPoint.size;
3380*35238bceSAndroid Build Coastguard Worker bool viewportClippedTop = false;
3381*35238bceSAndroid Build Coastguard Worker bool viewportClippedBottom = false;
3382*35238bceSAndroid Build Coastguard Worker bool primitiveClippedTop = false;
3383*35238bceSAndroid Build Coastguard Worker bool primitiveClippedBottom = false;
3384*35238bceSAndroid Build Coastguard Worker std::vector<tcu::IVec2> widthsUpwards;
3385*35238bceSAndroid Build Coastguard Worker std::vector<tcu::IVec2> widthsDownwards;
3386*35238bceSAndroid Build Coastguard Worker std::vector<tcu::IVec2> widths;
3387*35238bceSAndroid Build Coastguard Worker
3388*35238bceSAndroid Build Coastguard Worker // search upwards
3389*35238bceSAndroid Build Coastguard Worker for (int y = pointPos.y();; --y)
3390*35238bceSAndroid Build Coastguard Worker {
3391*35238bceSAndroid Build Coastguard Worker if (y < bbox.y() || y < 0)
3392*35238bceSAndroid Build Coastguard Worker {
3393*35238bceSAndroid Build Coastguard Worker if (y < bbox.y())
3394*35238bceSAndroid Build Coastguard Worker primitiveClippedTop = true;
3395*35238bceSAndroid Build Coastguard Worker if (y < 0)
3396*35238bceSAndroid Build Coastguard Worker viewportClippedTop = true;
3397*35238bceSAndroid Build Coastguard Worker break;
3398*35238bceSAndroid Build Coastguard Worker }
3399*35238bceSAndroid Build Coastguard Worker else if (pointPos.y() - y > expectedPointSize)
3400*35238bceSAndroid Build Coastguard Worker {
3401*35238bceSAndroid Build Coastguard Worker // no need to go further than point height
3402*35238bceSAndroid Build Coastguard Worker break;
3403*35238bceSAndroid Build Coastguard Worker }
3404*35238bceSAndroid Build Coastguard Worker else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
3405*35238bceSAndroid Build Coastguard Worker {
3406*35238bceSAndroid Build Coastguard Worker break;
3407*35238bceSAndroid Build Coastguard Worker }
3408*35238bceSAndroid Build Coastguard Worker else
3409*35238bceSAndroid Build Coastguard Worker {
3410*35238bceSAndroid Build Coastguard Worker widthsUpwards.push_back(
3411*35238bceSAndroid Build Coastguard Worker scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
3412*35238bceSAndroid Build Coastguard Worker }
3413*35238bceSAndroid Build Coastguard Worker }
3414*35238bceSAndroid Build Coastguard Worker
3415*35238bceSAndroid Build Coastguard Worker // top is clipped
3416*35238bceSAndroid Build Coastguard Worker if ((viewportClippedTop || (pointType == POINT_PARTIAL && primitiveClippedTop)) && !widthsUpwards.empty())
3417*35238bceSAndroid Build Coastguard Worker {
3418*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &range = widthsUpwards.back();
3419*35238bceSAndroid Build Coastguard Worker const bool squareFits = (range.y() - range.x() + 1) >= expectedPointSize;
3420*35238bceSAndroid Build Coastguard Worker const bool widthClipped = (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z());
3421*35238bceSAndroid Build Coastguard Worker
3422*35238bceSAndroid Build Coastguard Worker if (squareFits || widthClipped)
3423*35238bceSAndroid Build Coastguard Worker return true;
3424*35238bceSAndroid Build Coastguard Worker }
3425*35238bceSAndroid Build Coastguard Worker
3426*35238bceSAndroid Build Coastguard Worker // and downwards
3427*35238bceSAndroid Build Coastguard Worker for (int y = pointPos.y() + 1;; ++y)
3428*35238bceSAndroid Build Coastguard Worker {
3429*35238bceSAndroid Build Coastguard Worker if (y >= bbox.w() || y >= viewport.getHeight())
3430*35238bceSAndroid Build Coastguard Worker {
3431*35238bceSAndroid Build Coastguard Worker if (y >= bbox.w())
3432*35238bceSAndroid Build Coastguard Worker primitiveClippedBottom = true;
3433*35238bceSAndroid Build Coastguard Worker if (y >= viewport.getHeight())
3434*35238bceSAndroid Build Coastguard Worker viewportClippedBottom = true;
3435*35238bceSAndroid Build Coastguard Worker break;
3436*35238bceSAndroid Build Coastguard Worker }
3437*35238bceSAndroid Build Coastguard Worker else if (y - pointPos.y() > expectedPointSize)
3438*35238bceSAndroid Build Coastguard Worker {
3439*35238bceSAndroid Build Coastguard Worker // no need to go further than point height
3440*35238bceSAndroid Build Coastguard Worker break;
3441*35238bceSAndroid Build Coastguard Worker }
3442*35238bceSAndroid Build Coastguard Worker else if (viewport.getPixel(pointPos.x(), y).toIVec()[componentNdx] == 0)
3443*35238bceSAndroid Build Coastguard Worker {
3444*35238bceSAndroid Build Coastguard Worker break;
3445*35238bceSAndroid Build Coastguard Worker }
3446*35238bceSAndroid Build Coastguard Worker else
3447*35238bceSAndroid Build Coastguard Worker {
3448*35238bceSAndroid Build Coastguard Worker widthsDownwards.push_back(
3449*35238bceSAndroid Build Coastguard Worker scanPointWidthAt(tcu::IVec2(pointPos.x(), y), viewport, expectedPointSize, componentNdx));
3450*35238bceSAndroid Build Coastguard Worker }
3451*35238bceSAndroid Build Coastguard Worker }
3452*35238bceSAndroid Build Coastguard Worker
3453*35238bceSAndroid Build Coastguard Worker // bottom is clipped
3454*35238bceSAndroid Build Coastguard Worker if ((viewportClippedBottom || (pointType == POINT_PARTIAL && primitiveClippedBottom)) &&
3455*35238bceSAndroid Build Coastguard Worker !(widthsDownwards.empty() && widthsUpwards.empty()))
3456*35238bceSAndroid Build Coastguard Worker {
3457*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &range = (widthsDownwards.empty()) ? (widthsUpwards.front()) : (widthsDownwards.back());
3458*35238bceSAndroid Build Coastguard Worker const bool squareFits = (range.y() - range.x() + 1) >= expectedPointSize;
3459*35238bceSAndroid Build Coastguard Worker const bool bboxClipped = (pointType == POINT_PARTIAL) && (range.x() <= bbox.x() || range.y() >= bbox.z() - 1);
3460*35238bceSAndroid Build Coastguard Worker const bool viewportClipped = range.x() <= 0 || range.y() >= viewport.getWidth() - 1;
3461*35238bceSAndroid Build Coastguard Worker
3462*35238bceSAndroid Build Coastguard Worker if (squareFits || bboxClipped || viewportClipped)
3463*35238bceSAndroid Build Coastguard Worker return true;
3464*35238bceSAndroid Build Coastguard Worker }
3465*35238bceSAndroid Build Coastguard Worker
3466*35238bceSAndroid Build Coastguard Worker // would square point would fit into the rasterized area
3467*35238bceSAndroid Build Coastguard Worker
3468*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)widthsUpwards.size(); ++ndx)
3469*35238bceSAndroid Build Coastguard Worker widths.push_back(widthsUpwards[(int)widthsUpwards.size() - ndx - 1]);
3470*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)widthsDownwards.size(); ++ndx)
3471*35238bceSAndroid Build Coastguard Worker widths.push_back(widthsDownwards[ndx]);
3472*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!widths.empty());
3473*35238bceSAndroid Build Coastguard Worker
3474*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < (int)widths.size() - expectedPointSize + 1; ++y)
3475*35238bceSAndroid Build Coastguard Worker {
3476*35238bceSAndroid Build Coastguard Worker tcu::IVec2 unionRange = widths[y];
3477*35238bceSAndroid Build Coastguard Worker
3478*35238bceSAndroid Build Coastguard Worker for (int dy = 1; dy < expectedPointSize; ++dy)
3479*35238bceSAndroid Build Coastguard Worker {
3480*35238bceSAndroid Build Coastguard Worker unionRange.x() = de::max(unionRange.x(), widths[y + dy].x());
3481*35238bceSAndroid Build Coastguard Worker unionRange.y() = de::min(unionRange.y(), widths[y + dy].y());
3482*35238bceSAndroid Build Coastguard Worker }
3483*35238bceSAndroid Build Coastguard Worker
3484*35238bceSAndroid Build Coastguard Worker // would a N x N block fit here?
3485*35238bceSAndroid Build Coastguard Worker {
3486*35238bceSAndroid Build Coastguard Worker const bool squareFits = (unionRange.y() - unionRange.x() + 1) >= expectedPointSize;
3487*35238bceSAndroid Build Coastguard Worker const bool bboxClipped =
3488*35238bceSAndroid Build Coastguard Worker (pointType == POINT_PARTIAL) && (unionRange.x() <= bbox.x() || unionRange.y() >= bbox.z() - 1);
3489*35238bceSAndroid Build Coastguard Worker const bool viewportClipped = unionRange.x() <= 0 || unionRange.y() >= viewport.getWidth() - 1;
3490*35238bceSAndroid Build Coastguard Worker
3491*35238bceSAndroid Build Coastguard Worker if (squareFits || bboxClipped || viewportClipped)
3492*35238bceSAndroid Build Coastguard Worker return true;
3493*35238bceSAndroid Build Coastguard Worker }
3494*35238bceSAndroid Build Coastguard Worker }
3495*35238bceSAndroid Build Coastguard Worker
3496*35238bceSAndroid Build Coastguard Worker if (--logFloodCounter >= 0)
3497*35238bceSAndroid Build Coastguard Worker {
3498*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Missing " << expectedPointSize << "x" << expectedPointSize
3499*35238bceSAndroid Build Coastguard Worker << " point near " << pointPos << ", vertex coordinates=" << refPoint.center.swizzle(0, 1)
3500*35238bceSAndroid Build Coastguard Worker << "." << tcu::TestLog::EndMessage;
3501*35238bceSAndroid Build Coastguard Worker }
3502*35238bceSAndroid Build Coastguard Worker return false;
3503*35238bceSAndroid Build Coastguard Worker }
3504*35238bceSAndroid Build Coastguard Worker
scanPointWidthAt(const tcu::IVec2 & pointPos,const tcu::Surface & viewport,int expectedPointSize,int componentNdx) const3505*35238bceSAndroid Build Coastguard Worker tcu::IVec2 PointRenderCase::scanPointWidthAt(const tcu::IVec2 &pointPos, const tcu::Surface &viewport,
3506*35238bceSAndroid Build Coastguard Worker int expectedPointSize, int componentNdx) const
3507*35238bceSAndroid Build Coastguard Worker {
3508*35238bceSAndroid Build Coastguard Worker int minX = pointPos.x();
3509*35238bceSAndroid Build Coastguard Worker int maxX = pointPos.x();
3510*35238bceSAndroid Build Coastguard Worker
3511*35238bceSAndroid Build Coastguard Worker // search horizontally for a point edges
3512*35238bceSAndroid Build Coastguard Worker for (int x = pointPos.x() - 1; x >= 0; --x)
3513*35238bceSAndroid Build Coastguard Worker {
3514*35238bceSAndroid Build Coastguard Worker if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
3515*35238bceSAndroid Build Coastguard Worker break;
3516*35238bceSAndroid Build Coastguard Worker
3517*35238bceSAndroid Build Coastguard Worker // no need to go further than point width
3518*35238bceSAndroid Build Coastguard Worker if (pointPos.x() - x > expectedPointSize)
3519*35238bceSAndroid Build Coastguard Worker break;
3520*35238bceSAndroid Build Coastguard Worker
3521*35238bceSAndroid Build Coastguard Worker minX = x;
3522*35238bceSAndroid Build Coastguard Worker }
3523*35238bceSAndroid Build Coastguard Worker for (int x = pointPos.x() + 1; x < viewport.getWidth(); ++x)
3524*35238bceSAndroid Build Coastguard Worker {
3525*35238bceSAndroid Build Coastguard Worker if (viewport.getPixel(x, pointPos.y()).toIVec()[componentNdx] == 0)
3526*35238bceSAndroid Build Coastguard Worker break;
3527*35238bceSAndroid Build Coastguard Worker
3528*35238bceSAndroid Build Coastguard Worker // no need to go further than point width
3529*35238bceSAndroid Build Coastguard Worker if (x - pointPos.x() > expectedPointSize)
3530*35238bceSAndroid Build Coastguard Worker break;
3531*35238bceSAndroid Build Coastguard Worker
3532*35238bceSAndroid Build Coastguard Worker maxX = x;
3533*35238bceSAndroid Build Coastguard Worker }
3534*35238bceSAndroid Build Coastguard Worker
3535*35238bceSAndroid Build Coastguard Worker return tcu::IVec2(minX, maxX);
3536*35238bceSAndroid Build Coastguard Worker }
3537*35238bceSAndroid Build Coastguard Worker
3538*35238bceSAndroid Build Coastguard Worker class BlitFboCase : public TestCase
3539*35238bceSAndroid Build Coastguard Worker {
3540*35238bceSAndroid Build Coastguard Worker public:
3541*35238bceSAndroid Build Coastguard Worker enum RenderTarget
3542*35238bceSAndroid Build Coastguard Worker {
3543*35238bceSAndroid Build Coastguard Worker TARGET_DEFAULT = 0,
3544*35238bceSAndroid Build Coastguard Worker TARGET_FBO,
3545*35238bceSAndroid Build Coastguard Worker
3546*35238bceSAndroid Build Coastguard Worker TARGET_LAST
3547*35238bceSAndroid Build Coastguard Worker };
3548*35238bceSAndroid Build Coastguard Worker
3549*35238bceSAndroid Build Coastguard Worker BlitFboCase(Context &context, const char *name, const char *description, RenderTarget src, RenderTarget dst);
3550*35238bceSAndroid Build Coastguard Worker ~BlitFboCase(void);
3551*35238bceSAndroid Build Coastguard Worker
3552*35238bceSAndroid Build Coastguard Worker private:
3553*35238bceSAndroid Build Coastguard Worker enum
3554*35238bceSAndroid Build Coastguard Worker {
3555*35238bceSAndroid Build Coastguard Worker FBO_SIZE = 256,
3556*35238bceSAndroid Build Coastguard Worker };
3557*35238bceSAndroid Build Coastguard Worker
3558*35238bceSAndroid Build Coastguard Worker struct BlitArgs
3559*35238bceSAndroid Build Coastguard Worker {
3560*35238bceSAndroid Build Coastguard Worker tcu::IVec4 src;
3561*35238bceSAndroid Build Coastguard Worker tcu::IVec4 dst;
3562*35238bceSAndroid Build Coastguard Worker tcu::Vec4 bboxMin;
3563*35238bceSAndroid Build Coastguard Worker tcu::Vec4 bboxMax;
3564*35238bceSAndroid Build Coastguard Worker bool linear;
3565*35238bceSAndroid Build Coastguard Worker };
3566*35238bceSAndroid Build Coastguard Worker
3567*35238bceSAndroid Build Coastguard Worker void init(void);
3568*35238bceSAndroid Build Coastguard Worker void deinit(void);
3569*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
3570*35238bceSAndroid Build Coastguard Worker
3571*35238bceSAndroid Build Coastguard Worker void fillSourceWithPattern(void);
3572*35238bceSAndroid Build Coastguard Worker bool verifyImage(const BlitArgs &args);
3573*35238bceSAndroid Build Coastguard Worker
3574*35238bceSAndroid Build Coastguard Worker const RenderTarget m_src;
3575*35238bceSAndroid Build Coastguard Worker const RenderTarget m_dst;
3576*35238bceSAndroid Build Coastguard Worker
3577*35238bceSAndroid Build Coastguard Worker std::vector<BlitArgs> m_iterations;
3578*35238bceSAndroid Build Coastguard Worker int m_iteration;
3579*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Framebuffer> m_srcFbo;
3580*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Framebuffer> m_dstFbo;
3581*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Renderbuffer> m_srcRbo;
3582*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Renderbuffer> m_dstRbo;
3583*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_program;
3584*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Buffer> m_vbo;
3585*35238bceSAndroid Build Coastguard Worker glw::GLuint m_vao;
3586*35238bceSAndroid Build Coastguard Worker };
3587*35238bceSAndroid Build Coastguard Worker
BlitFboCase(Context & context,const char * name,const char * description,RenderTarget src,RenderTarget dst)3588*35238bceSAndroid Build Coastguard Worker BlitFboCase::BlitFboCase(Context &context, const char *name, const char *description, RenderTarget src,
3589*35238bceSAndroid Build Coastguard Worker RenderTarget dst)
3590*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
3591*35238bceSAndroid Build Coastguard Worker , m_src(src)
3592*35238bceSAndroid Build Coastguard Worker , m_dst(dst)
3593*35238bceSAndroid Build Coastguard Worker , m_iteration(0)
3594*35238bceSAndroid Build Coastguard Worker , m_vao(0)
3595*35238bceSAndroid Build Coastguard Worker {
3596*35238bceSAndroid Build Coastguard Worker DE_ASSERT(src < TARGET_LAST);
3597*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dst < TARGET_LAST);
3598*35238bceSAndroid Build Coastguard Worker }
3599*35238bceSAndroid Build Coastguard Worker
~BlitFboCase(void)3600*35238bceSAndroid Build Coastguard Worker BlitFboCase::~BlitFboCase(void)
3601*35238bceSAndroid Build Coastguard Worker {
3602*35238bceSAndroid Build Coastguard Worker deinit();
3603*35238bceSAndroid Build Coastguard Worker }
3604*35238bceSAndroid Build Coastguard Worker
init(void)3605*35238bceSAndroid Build Coastguard Worker void BlitFboCase::init(void)
3606*35238bceSAndroid Build Coastguard Worker {
3607*35238bceSAndroid Build Coastguard Worker const int numIterations = 12;
3608*35238bceSAndroid Build Coastguard Worker const bool defaultFBMultisampled = (m_context.getRenderTarget().getNumSamples() > 1);
3609*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3610*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xABC123);
3611*35238bceSAndroid Build Coastguard Worker
3612*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Using BlitFramebuffer to blit area from "
3613*35238bceSAndroid Build Coastguard Worker << ((m_src == TARGET_DEFAULT) ? ("default fb") : ("fbo")) << " to "
3614*35238bceSAndroid Build Coastguard Worker << ((m_dst == TARGET_DEFAULT) ? ("default fb") : ("fbo")) << ".\n"
3615*35238bceSAndroid Build Coastguard Worker << "Varying blit arguments and primitive bounding box between iterations.\n"
3616*35238bceSAndroid Build Coastguard Worker << "Expecting bounding box to have no effect on blitting.\n"
3617*35238bceSAndroid Build Coastguard Worker << "Source framebuffer is filled with green-yellow grid.\n"
3618*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3619*35238bceSAndroid Build Coastguard Worker
3620*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
3621*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
3622*35238bceSAndroid Build Coastguard Worker
3623*35238bceSAndroid Build Coastguard Worker if (m_dst == TARGET_DEFAULT && defaultFBMultisampled)
3624*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires non-multisampled default framebuffer");
3625*35238bceSAndroid Build Coastguard Worker
3626*35238bceSAndroid Build Coastguard Worker // resources
3627*35238bceSAndroid Build Coastguard Worker
3628*35238bceSAndroid Build Coastguard Worker if (m_src == TARGET_FBO)
3629*35238bceSAndroid Build Coastguard Worker {
3630*35238bceSAndroid Build Coastguard Worker m_srcRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
3631*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, **m_srcRbo);
3632*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
3633*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "src rbo");
3634*35238bceSAndroid Build Coastguard Worker
3635*35238bceSAndroid Build Coastguard Worker m_srcFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
3636*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, **m_srcFbo);
3637*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_srcRbo);
3638*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "src fbo");
3639*35238bceSAndroid Build Coastguard Worker }
3640*35238bceSAndroid Build Coastguard Worker
3641*35238bceSAndroid Build Coastguard Worker if (m_dst == TARGET_FBO)
3642*35238bceSAndroid Build Coastguard Worker {
3643*35238bceSAndroid Build Coastguard Worker m_dstRbo = de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(m_context.getRenderContext()));
3644*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, **m_dstRbo);
3645*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, FBO_SIZE, FBO_SIZE);
3646*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dst rbo");
3647*35238bceSAndroid Build Coastguard Worker
3648*35238bceSAndroid Build Coastguard Worker m_dstFbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
3649*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, **m_dstFbo);
3650*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_dstRbo);
3651*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dst fbo");
3652*35238bceSAndroid Build Coastguard Worker }
3653*35238bceSAndroid Build Coastguard Worker
3654*35238bceSAndroid Build Coastguard Worker {
3655*35238bceSAndroid Build Coastguard Worker const char *const vertexSource = "${GLSL_VERSION_DECL}\n"
3656*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
3657*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_position;\n"
3658*35238bceSAndroid Build Coastguard Worker "void main()\n"
3659*35238bceSAndroid Build Coastguard Worker "{\n"
3660*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
3661*35238bceSAndroid Build Coastguard Worker " v_position = a_position;\n"
3662*35238bceSAndroid Build Coastguard Worker "}\n";
3663*35238bceSAndroid Build Coastguard Worker const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
3664*35238bceSAndroid Build Coastguard Worker "in mediump vec4 v_position;\n"
3665*35238bceSAndroid Build Coastguard Worker "layout(location=0) out mediump vec4 dEQP_FragColor;\n"
3666*35238bceSAndroid Build Coastguard Worker "void main()\n"
3667*35238bceSAndroid Build Coastguard Worker "{\n"
3668*35238bceSAndroid Build Coastguard Worker " const mediump vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
3669*35238bceSAndroid Build Coastguard Worker " const mediump vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
3670*35238bceSAndroid Build Coastguard Worker " dEQP_FragColor = (step(0.1, mod(v_position.x, 0.2)) == step(0.1, "
3671*35238bceSAndroid Build Coastguard Worker "mod(v_position.y, 0.2))) ? (green) : (yellow);\n"
3672*35238bceSAndroid Build Coastguard Worker "}\n";
3673*35238bceSAndroid Build Coastguard Worker
3674*35238bceSAndroid Build Coastguard Worker m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(
3675*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(), glu::ProgramSources()
3676*35238bceSAndroid Build Coastguard Worker << glu::VertexSource(specializeShader(m_context, vertexSource))
3677*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(specializeShader(m_context, fragmentSource))));
3678*35238bceSAndroid Build Coastguard Worker
3679*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
3680*35238bceSAndroid Build Coastguard Worker {
3681*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
3682*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
3683*35238bceSAndroid Build Coastguard Worker }
3684*35238bceSAndroid Build Coastguard Worker }
3685*35238bceSAndroid Build Coastguard Worker
3686*35238bceSAndroid Build Coastguard Worker // Generate VAO for desktop OpenGL
3687*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
3688*35238bceSAndroid Build Coastguard Worker {
3689*35238bceSAndroid Build Coastguard Worker gl.genVertexArrays(1, &m_vao);
3690*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(m_vao);
3691*35238bceSAndroid Build Coastguard Worker }
3692*35238bceSAndroid Build Coastguard Worker
3693*35238bceSAndroid Build Coastguard Worker {
3694*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 s_quadCoords[] = {
3695*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
3696*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
3697*35238bceSAndroid Build Coastguard Worker tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
3698*35238bceSAndroid Build Coastguard Worker tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
3699*35238bceSAndroid Build Coastguard Worker };
3700*35238bceSAndroid Build Coastguard Worker
3701*35238bceSAndroid Build Coastguard Worker m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
3702*35238bceSAndroid Build Coastguard Worker
3703*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
3704*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, sizeof(s_quadCoords), s_quadCoords, GL_STATIC_DRAW);
3705*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set buf");
3706*35238bceSAndroid Build Coastguard Worker }
3707*35238bceSAndroid Build Coastguard Worker
3708*35238bceSAndroid Build Coastguard Worker // gen iterations
3709*35238bceSAndroid Build Coastguard Worker
3710*35238bceSAndroid Build Coastguard Worker {
3711*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 srcSize =
3712*35238bceSAndroid Build Coastguard Worker (m_src == TARGET_DEFAULT) ?
3713*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
3714*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(FBO_SIZE, FBO_SIZE));
3715*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 dstSize =
3716*35238bceSAndroid Build Coastguard Worker (m_dst == TARGET_DEFAULT) ?
3717*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
3718*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(FBO_SIZE, FBO_SIZE));
3719*35238bceSAndroid Build Coastguard Worker
3720*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "srcSize = " << srcSize << "\n"
3721*35238bceSAndroid Build Coastguard Worker << "dstSize = " << dstSize << "\n"
3722*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3723*35238bceSAndroid Build Coastguard Worker
3724*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numIterations; ++ndx)
3725*35238bceSAndroid Build Coastguard Worker {
3726*35238bceSAndroid Build Coastguard Worker BlitArgs args;
3727*35238bceSAndroid Build Coastguard Worker
3728*35238bceSAndroid Build Coastguard Worker if (m_src == TARGET_DEFAULT && defaultFBMultisampled)
3729*35238bceSAndroid Build Coastguard Worker {
3730*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 unionSize =
3731*35238bceSAndroid Build Coastguard Worker tcu::IVec2(de::min(srcSize.x(), dstSize.x()), de::min(srcSize.y(), dstSize.y()));
3732*35238bceSAndroid Build Coastguard Worker const int srcWidth = rnd.getInt(1, unionSize.x());
3733*35238bceSAndroid Build Coastguard Worker const int srcHeight = rnd.getInt(1, unionSize.y());
3734*35238bceSAndroid Build Coastguard Worker const int srcX = rnd.getInt(0, unionSize.x() - srcWidth);
3735*35238bceSAndroid Build Coastguard Worker const int srcY = rnd.getInt(0, unionSize.y() - srcHeight);
3736*35238bceSAndroid Build Coastguard Worker
3737*35238bceSAndroid Build Coastguard Worker args.src.x() = srcX;
3738*35238bceSAndroid Build Coastguard Worker args.src.y() = srcY;
3739*35238bceSAndroid Build Coastguard Worker args.src.z() = srcX + srcWidth;
3740*35238bceSAndroid Build Coastguard Worker args.src.w() = srcY + srcHeight;
3741*35238bceSAndroid Build Coastguard Worker
3742*35238bceSAndroid Build Coastguard Worker args.dst = args.src;
3743*35238bceSAndroid Build Coastguard Worker }
3744*35238bceSAndroid Build Coastguard Worker else
3745*35238bceSAndroid Build Coastguard Worker {
3746*35238bceSAndroid Build Coastguard Worker const int srcWidth = rnd.getInt(1, srcSize.x());
3747*35238bceSAndroid Build Coastguard Worker const int srcHeight = rnd.getInt(1, srcSize.y());
3748*35238bceSAndroid Build Coastguard Worker const int srcX = rnd.getInt(0, srcSize.x() - srcWidth);
3749*35238bceSAndroid Build Coastguard Worker const int srcY = rnd.getInt(0, srcSize.y() - srcHeight);
3750*35238bceSAndroid Build Coastguard Worker const int dstWidth = rnd.getInt(1, dstSize.x());
3751*35238bceSAndroid Build Coastguard Worker const int dstHeight = rnd.getInt(1, dstSize.y());
3752*35238bceSAndroid Build Coastguard Worker const int dstX =
3753*35238bceSAndroid Build Coastguard Worker rnd.getInt(-(dstWidth / 2), dstSize.x() - (dstWidth + 1) / 2); // allow dst go out of bounds
3754*35238bceSAndroid Build Coastguard Worker const int dstY = rnd.getInt(-(dstHeight / 2), dstSize.y() - (dstHeight + 1) / 2);
3755*35238bceSAndroid Build Coastguard Worker
3756*35238bceSAndroid Build Coastguard Worker args.src.x() = srcX;
3757*35238bceSAndroid Build Coastguard Worker args.src.y() = srcY;
3758*35238bceSAndroid Build Coastguard Worker args.src.z() = srcX + srcWidth;
3759*35238bceSAndroid Build Coastguard Worker args.src.w() = srcY + srcHeight;
3760*35238bceSAndroid Build Coastguard Worker args.dst.x() = dstX;
3761*35238bceSAndroid Build Coastguard Worker args.dst.y() = dstY;
3762*35238bceSAndroid Build Coastguard Worker args.dst.z() = dstX + dstWidth;
3763*35238bceSAndroid Build Coastguard Worker args.dst.w() = dstY + dstHeight;
3764*35238bceSAndroid Build Coastguard Worker }
3765*35238bceSAndroid Build Coastguard Worker
3766*35238bceSAndroid Build Coastguard Worker args.bboxMin.x() = rnd.getFloat(-1.1f, 1.1f);
3767*35238bceSAndroid Build Coastguard Worker args.bboxMin.y() = rnd.getFloat(-1.1f, 1.1f);
3768*35238bceSAndroid Build Coastguard Worker args.bboxMin.z() = rnd.getFloat(-1.1f, 1.1f);
3769*35238bceSAndroid Build Coastguard Worker args.bboxMin.w() = rnd.getFloat(0.9f, 1.1f);
3770*35238bceSAndroid Build Coastguard Worker
3771*35238bceSAndroid Build Coastguard Worker args.bboxMax.x() = rnd.getFloat(-1.1f, 1.1f);
3772*35238bceSAndroid Build Coastguard Worker args.bboxMax.y() = rnd.getFloat(-1.1f, 1.1f);
3773*35238bceSAndroid Build Coastguard Worker args.bboxMax.z() = rnd.getFloat(-1.1f, 1.1f);
3774*35238bceSAndroid Build Coastguard Worker args.bboxMax.w() = rnd.getFloat(0.9f, 1.1f);
3775*35238bceSAndroid Build Coastguard Worker
3776*35238bceSAndroid Build Coastguard Worker if (args.bboxMin.x() / args.bboxMin.w() > args.bboxMax.x() / args.bboxMax.w())
3777*35238bceSAndroid Build Coastguard Worker std::swap(args.bboxMin.x(), args.bboxMax.x());
3778*35238bceSAndroid Build Coastguard Worker if (args.bboxMin.y() / args.bboxMin.w() > args.bboxMax.y() / args.bboxMax.w())
3779*35238bceSAndroid Build Coastguard Worker std::swap(args.bboxMin.y(), args.bboxMax.y());
3780*35238bceSAndroid Build Coastguard Worker if (args.bboxMin.z() / args.bboxMin.w() > args.bboxMax.z() / args.bboxMax.w())
3781*35238bceSAndroid Build Coastguard Worker std::swap(args.bboxMin.z(), args.bboxMax.z());
3782*35238bceSAndroid Build Coastguard Worker
3783*35238bceSAndroid Build Coastguard Worker args.linear = rnd.getBool();
3784*35238bceSAndroid Build Coastguard Worker
3785*35238bceSAndroid Build Coastguard Worker m_iterations.push_back(args);
3786*35238bceSAndroid Build Coastguard Worker }
3787*35238bceSAndroid Build Coastguard Worker }
3788*35238bceSAndroid Build Coastguard Worker }
3789*35238bceSAndroid Build Coastguard Worker
deinit(void)3790*35238bceSAndroid Build Coastguard Worker void BlitFboCase::deinit(void)
3791*35238bceSAndroid Build Coastguard Worker {
3792*35238bceSAndroid Build Coastguard Worker m_srcFbo.clear();
3793*35238bceSAndroid Build Coastguard Worker m_srcRbo.clear();
3794*35238bceSAndroid Build Coastguard Worker m_dstFbo.clear();
3795*35238bceSAndroid Build Coastguard Worker m_dstRbo.clear();
3796*35238bceSAndroid Build Coastguard Worker m_program.clear();
3797*35238bceSAndroid Build Coastguard Worker m_vbo.clear();
3798*35238bceSAndroid Build Coastguard Worker
3799*35238bceSAndroid Build Coastguard Worker if (m_vao)
3800*35238bceSAndroid Build Coastguard Worker {
3801*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
3802*35238bceSAndroid Build Coastguard Worker m_vao = 0;
3803*35238bceSAndroid Build Coastguard Worker }
3804*35238bceSAndroid Build Coastguard Worker }
3805*35238bceSAndroid Build Coastguard Worker
iterate(void)3806*35238bceSAndroid Build Coastguard Worker BlitFboCase::IterateResult BlitFboCase::iterate(void)
3807*35238bceSAndroid Build Coastguard Worker {
3808*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration" + de::toString(m_iteration),
3809*35238bceSAndroid Build Coastguard Worker "Iteration " + de::toString(m_iteration + 1) + " / " +
3810*35238bceSAndroid Build Coastguard Worker de::toString((int)m_iterations.size()));
3811*35238bceSAndroid Build Coastguard Worker const BlitArgs &blitCfg = m_iterations[m_iteration];
3812*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3813*35238bceSAndroid Build Coastguard Worker
3814*35238bceSAndroid Build Coastguard Worker if (m_iteration == 0)
3815*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3816*35238bceSAndroid Build Coastguard Worker
3817*35238bceSAndroid Build Coastguard Worker // fill source with test pattern. Default fb must be filled for each iteration because contents might not survive the swap
3818*35238bceSAndroid Build Coastguard Worker if (m_src == TARGET_DEFAULT || m_iteration == 0)
3819*35238bceSAndroid Build Coastguard Worker fillSourceWithPattern();
3820*35238bceSAndroid Build Coastguard Worker
3821*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Set bounding box:\n"
3822*35238bceSAndroid Build Coastguard Worker << "\tmin:" << blitCfg.bboxMin << "\n"
3823*35238bceSAndroid Build Coastguard Worker << "\tmax:" << blitCfg.bboxMax << "\n"
3824*35238bceSAndroid Build Coastguard Worker << "Blit:\n"
3825*35238bceSAndroid Build Coastguard Worker << "\tsrc: " << blitCfg.src << "\n"
3826*35238bceSAndroid Build Coastguard Worker << "\tdst: " << blitCfg.dst << "\n"
3827*35238bceSAndroid Build Coastguard Worker << "\tfilter: " << ((blitCfg.linear) ? ("linear") : ("nearest")) << tcu::TestLog::EndMessage;
3828*35238bceSAndroid Build Coastguard Worker
3829*35238bceSAndroid Build Coastguard Worker auto boundingBoxFunc = getBoundingBoxFunction(m_context);
3830*35238bceSAndroid Build Coastguard Worker
3831*35238bceSAndroid Build Coastguard Worker boundingBoxFunc(blitCfg.bboxMin.x(), blitCfg.bboxMin.y(), blitCfg.bboxMin.z(), blitCfg.bboxMin.w(),
3832*35238bceSAndroid Build Coastguard Worker blitCfg.bboxMax.x(), blitCfg.bboxMax.y(), blitCfg.bboxMax.z(), blitCfg.bboxMax.w());
3833*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER,
3834*35238bceSAndroid Build Coastguard Worker (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
3835*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3836*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
3837*35238bceSAndroid Build Coastguard Worker
3838*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER,
3839*35238bceSAndroid Build Coastguard Worker (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
3840*35238bceSAndroid Build Coastguard Worker gl.blitFramebuffer(blitCfg.src.x(), blitCfg.src.y(), blitCfg.src.z(), blitCfg.src.w(), blitCfg.dst.x(),
3841*35238bceSAndroid Build Coastguard Worker blitCfg.dst.y(), blitCfg.dst.z(), blitCfg.dst.w(), GL_COLOR_BUFFER_BIT,
3842*35238bceSAndroid Build Coastguard Worker ((blitCfg.linear) ? (GL_LINEAR) : (GL_NEAREST)));
3843*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "blit");
3844*35238bceSAndroid Build Coastguard Worker
3845*35238bceSAndroid Build Coastguard Worker if (!verifyImage(blitCfg))
3846*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected blit result");
3847*35238bceSAndroid Build Coastguard Worker
3848*35238bceSAndroid Build Coastguard Worker return (++m_iteration == (int)m_iterations.size()) ? (STOP) : (CONTINUE);
3849*35238bceSAndroid Build Coastguard Worker }
3850*35238bceSAndroid Build Coastguard Worker
verifyImage(const BlitArgs & args)3851*35238bceSAndroid Build Coastguard Worker bool BlitFboCase::verifyImage(const BlitArgs &args)
3852*35238bceSAndroid Build Coastguard Worker {
3853*35238bceSAndroid Build Coastguard Worker const int colorThreshold = 4; //!< this test case is not about how color is preserved, allow almost anything
3854*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 dstSize =
3855*35238bceSAndroid Build Coastguard Worker (m_dst == TARGET_DEFAULT) ?
3856*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
3857*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(FBO_SIZE, FBO_SIZE));
3858*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3859*35238bceSAndroid Build Coastguard Worker tcu::Surface viewport(dstSize.x(), dstSize.y());
3860*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(dstSize.x(), dstSize.y());
3861*35238bceSAndroid Build Coastguard Worker bool anyError = false;
3862*35238bceSAndroid Build Coastguard Worker
3863*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying blit result" << tcu::TestLog::EndMessage;
3864*35238bceSAndroid Build Coastguard Worker
3865*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER,
3866*35238bceSAndroid Build Coastguard Worker (m_dst == TARGET_FBO) ? (**m_dstFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
3867*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());
3868*35238bceSAndroid Build Coastguard Worker
3869*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 0, 0, 255));
3870*35238bceSAndroid Build Coastguard Worker
3871*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < dstSize.y(); ++y)
3872*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < dstSize.x(); ++x)
3873*35238bceSAndroid Build Coastguard Worker {
3874*35238bceSAndroid Build Coastguard Worker const tcu::RGBA color = viewport.getPixel(x, y);
3875*35238bceSAndroid Build Coastguard Worker const bool inside = (x >= args.dst.x() && x < args.dst.z() && y >= args.dst.y() && y < args.dst.w());
3876*35238bceSAndroid Build Coastguard Worker const bool error = (inside) ?
3877*35238bceSAndroid Build Coastguard Worker (color.getGreen() < 255 - colorThreshold || color.getBlue() > colorThreshold) :
3878*35238bceSAndroid Build Coastguard Worker (color.getRed() > colorThreshold || color.getGreen() > colorThreshold ||
3879*35238bceSAndroid Build Coastguard Worker color.getBlue() > colorThreshold);
3880*35238bceSAndroid Build Coastguard Worker
3881*35238bceSAndroid Build Coastguard Worker if (error)
3882*35238bceSAndroid Build Coastguard Worker {
3883*35238bceSAndroid Build Coastguard Worker anyError = true;
3884*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
3885*35238bceSAndroid Build Coastguard Worker }
3886*35238bceSAndroid Build Coastguard Worker }
3887*35238bceSAndroid Build Coastguard Worker
3888*35238bceSAndroid Build Coastguard Worker if (anyError)
3889*35238bceSAndroid Build Coastguard Worker {
3890*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
3891*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
3892*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
3893*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
3894*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
3895*35238bceSAndroid Build Coastguard Worker return false;
3896*35238bceSAndroid Build Coastguard Worker }
3897*35238bceSAndroid Build Coastguard Worker else
3898*35238bceSAndroid Build Coastguard Worker {
3899*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result image ok." << tcu::TestLog::EndMessage
3900*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
3901*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
3902*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
3903*35238bceSAndroid Build Coastguard Worker return true;
3904*35238bceSAndroid Build Coastguard Worker }
3905*35238bceSAndroid Build Coastguard Worker }
3906*35238bceSAndroid Build Coastguard Worker
fillSourceWithPattern(void)3907*35238bceSAndroid Build Coastguard Worker void BlitFboCase::fillSourceWithPattern(void)
3908*35238bceSAndroid Build Coastguard Worker {
3909*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3910*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 srcSize =
3911*35238bceSAndroid Build Coastguard Worker (m_src == TARGET_DEFAULT) ?
3912*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight())) :
3913*35238bceSAndroid Build Coastguard Worker (tcu::IVec2(FBO_SIZE, FBO_SIZE));
3914*35238bceSAndroid Build Coastguard Worker const int posLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
3915*35238bceSAndroid Build Coastguard Worker
3916*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER,
3917*35238bceSAndroid Build Coastguard Worker (m_src == TARGET_FBO) ? (**m_srcFbo) : (m_context.getRenderContext().getDefaultFramebuffer()));
3918*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, srcSize.x(), srcSize.y());
3919*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
3920*35238bceSAndroid Build Coastguard Worker
3921*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 1.0f, 1.0f);
3922*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
3923*35238bceSAndroid Build Coastguard Worker
3924*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
3925*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 4 * (int)sizeof(float), NULL);
3926*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
3927*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
3928*35238bceSAndroid Build Coastguard Worker }
3929*35238bceSAndroid Build Coastguard Worker
3930*35238bceSAndroid Build Coastguard Worker class DepthDrawCase : public TestCase
3931*35238bceSAndroid Build Coastguard Worker {
3932*35238bceSAndroid Build Coastguard Worker public:
3933*35238bceSAndroid Build Coastguard Worker enum DepthType
3934*35238bceSAndroid Build Coastguard Worker {
3935*35238bceSAndroid Build Coastguard Worker DEPTH_BUILTIN = 0,
3936*35238bceSAndroid Build Coastguard Worker DEPTH_USER_DEFINED,
3937*35238bceSAndroid Build Coastguard Worker
3938*35238bceSAndroid Build Coastguard Worker DEPTH_LAST
3939*35238bceSAndroid Build Coastguard Worker };
3940*35238bceSAndroid Build Coastguard Worker enum BBoxState
3941*35238bceSAndroid Build Coastguard Worker {
3942*35238bceSAndroid Build Coastguard Worker STATE_GLOBAL = 0,
3943*35238bceSAndroid Build Coastguard Worker STATE_PER_PRIMITIVE,
3944*35238bceSAndroid Build Coastguard Worker
3945*35238bceSAndroid Build Coastguard Worker STATE_LAST
3946*35238bceSAndroid Build Coastguard Worker };
3947*35238bceSAndroid Build Coastguard Worker enum BBoxSize
3948*35238bceSAndroid Build Coastguard Worker {
3949*35238bceSAndroid Build Coastguard Worker BBOX_EQUAL = 0,
3950*35238bceSAndroid Build Coastguard Worker BBOX_LARGER,
3951*35238bceSAndroid Build Coastguard Worker
3952*35238bceSAndroid Build Coastguard Worker BBOX_LAST
3953*35238bceSAndroid Build Coastguard Worker };
3954*35238bceSAndroid Build Coastguard Worker
3955*35238bceSAndroid Build Coastguard Worker DepthDrawCase(Context &context, const char *name, const char *description, DepthType depthType, BBoxState state,
3956*35238bceSAndroid Build Coastguard Worker BBoxSize bboxSize);
3957*35238bceSAndroid Build Coastguard Worker ~DepthDrawCase(void);
3958*35238bceSAndroid Build Coastguard Worker
3959*35238bceSAndroid Build Coastguard Worker private:
3960*35238bceSAndroid Build Coastguard Worker void init(void);
3961*35238bceSAndroid Build Coastguard Worker void deinit(void);
3962*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
3963*35238bceSAndroid Build Coastguard Worker
3964*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
3965*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
3966*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
3967*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
3968*35238bceSAndroid Build Coastguard Worker void generateAttributeData(std::vector<tcu::Vec4> &data) const;
3969*35238bceSAndroid Build Coastguard Worker bool verifyImage(const tcu::Surface &viewport) const;
3970*35238bceSAndroid Build Coastguard Worker
3971*35238bceSAndroid Build Coastguard Worker enum
3972*35238bceSAndroid Build Coastguard Worker {
3973*35238bceSAndroid Build Coastguard Worker RENDER_AREA_SIZE = 256,
3974*35238bceSAndroid Build Coastguard Worker };
3975*35238bceSAndroid Build Coastguard Worker
3976*35238bceSAndroid Build Coastguard Worker struct LayerInfo
3977*35238bceSAndroid Build Coastguard Worker {
3978*35238bceSAndroid Build Coastguard Worker float zOffset;
3979*35238bceSAndroid Build Coastguard Worker float zScale;
3980*35238bceSAndroid Build Coastguard Worker tcu::Vec4 color1;
3981*35238bceSAndroid Build Coastguard Worker tcu::Vec4 color2;
3982*35238bceSAndroid Build Coastguard Worker };
3983*35238bceSAndroid Build Coastguard Worker
3984*35238bceSAndroid Build Coastguard Worker const int m_numLayers;
3985*35238bceSAndroid Build Coastguard Worker const int m_gridSize;
3986*35238bceSAndroid Build Coastguard Worker
3987*35238bceSAndroid Build Coastguard Worker const DepthType m_depthType;
3988*35238bceSAndroid Build Coastguard Worker const BBoxState m_state;
3989*35238bceSAndroid Build Coastguard Worker const BBoxSize m_bboxSize;
3990*35238bceSAndroid Build Coastguard Worker
3991*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_program;
3992*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Buffer> m_vbo;
3993*35238bceSAndroid Build Coastguard Worker glw::GLuint m_vao;
3994*35238bceSAndroid Build Coastguard Worker std::vector<LayerInfo> m_layers;
3995*35238bceSAndroid Build Coastguard Worker };
3996*35238bceSAndroid Build Coastguard Worker
DepthDrawCase(Context & context,const char * name,const char * description,DepthType depthType,BBoxState state,BBoxSize bboxSize)3997*35238bceSAndroid Build Coastguard Worker DepthDrawCase::DepthDrawCase(Context &context, const char *name, const char *description, DepthType depthType,
3998*35238bceSAndroid Build Coastguard Worker BBoxState state, BBoxSize bboxSize)
3999*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
4000*35238bceSAndroid Build Coastguard Worker , m_numLayers(14)
4001*35238bceSAndroid Build Coastguard Worker , m_gridSize(24)
4002*35238bceSAndroid Build Coastguard Worker , m_depthType(depthType)
4003*35238bceSAndroid Build Coastguard Worker , m_state(state)
4004*35238bceSAndroid Build Coastguard Worker , m_bboxSize(bboxSize)
4005*35238bceSAndroid Build Coastguard Worker , m_vao(0)
4006*35238bceSAndroid Build Coastguard Worker {
4007*35238bceSAndroid Build Coastguard Worker DE_ASSERT(depthType < DEPTH_LAST);
4008*35238bceSAndroid Build Coastguard Worker DE_ASSERT(state < STATE_LAST);
4009*35238bceSAndroid Build Coastguard Worker DE_ASSERT(bboxSize < BBOX_LAST);
4010*35238bceSAndroid Build Coastguard Worker }
4011*35238bceSAndroid Build Coastguard Worker
~DepthDrawCase(void)4012*35238bceSAndroid Build Coastguard Worker DepthDrawCase::~DepthDrawCase(void)
4013*35238bceSAndroid Build Coastguard Worker {
4014*35238bceSAndroid Build Coastguard Worker deinit();
4015*35238bceSAndroid Build Coastguard Worker }
4016*35238bceSAndroid Build Coastguard Worker
init(void)4017*35238bceSAndroid Build Coastguard Worker void DepthDrawCase::init(void)
4018*35238bceSAndroid Build Coastguard Worker {
4019*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4020*35238bceSAndroid Build Coastguard Worker const bool hasES32OrGL45 = supportsES32OrGL45(m_context);
4021*35238bceSAndroid Build Coastguard Worker
4022*35238bceSAndroid Build Coastguard Worker // requirements
4023*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
4024*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
4025*35238bceSAndroid Build Coastguard Worker if (m_state == STATE_PER_PRIMITIVE && !hasES32OrGL45 &&
4026*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
4027*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
4028*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getDepthBits() == 0)
4029*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires depth buffer");
4030*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_AREA_SIZE ||
4031*35238bceSAndroid Build Coastguard Worker m_context.getRenderTarget().getHeight() < RENDER_AREA_SIZE)
4032*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_AREA_SIZE) + "x" +
4033*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_AREA_SIZE) + " viewport");
4034*35238bceSAndroid Build Coastguard Worker
4035*35238bceSAndroid Build Coastguard Worker // log
4036*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
4037*35238bceSAndroid Build Coastguard Worker << "Rendering multiple triangle grids with with different z coordinates.\n"
4038*35238bceSAndroid Build Coastguard Worker << "Topmost grid is green-yellow, other grids are blue-red.\n"
4039*35238bceSAndroid Build Coastguard Worker << "Expecting only the green-yellow grid to be visible.\n"
4040*35238bceSAndroid Build Coastguard Worker << "Setting primitive bounding box "
4041*35238bceSAndroid Build Coastguard Worker << ((m_bboxSize == BBOX_EQUAL) ? ("to exactly cover") : ("to cover"))
4042*35238bceSAndroid Build Coastguard Worker << ((m_state == STATE_GLOBAL) ? (" each grid") : (" each triangle"))
4043*35238bceSAndroid Build Coastguard Worker << ((m_bboxSize == BBOX_EQUAL) ? (".") : (" and include some padding.")) << "\n"
4044*35238bceSAndroid Build Coastguard Worker << "Set bounding box using "
4045*35238bceSAndroid Build Coastguard Worker << ((m_state == STATE_GLOBAL) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") :
4046*35238bceSAndroid Build Coastguard Worker ("gl_BoundingBoxEXT output"))
4047*35238bceSAndroid Build Coastguard Worker << "\n"
4048*35238bceSAndroid Build Coastguard Worker << ((m_depthType == DEPTH_USER_DEFINED) ? ("Fragment depth is set in the fragment shader") :
4049*35238bceSAndroid Build Coastguard Worker (""))
4050*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
4051*35238bceSAndroid Build Coastguard Worker
4052*35238bceSAndroid Build Coastguard Worker // resources
4053*35238bceSAndroid Build Coastguard Worker
4054*35238bceSAndroid Build Coastguard Worker {
4055*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
4056*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()));
4057*35238bceSAndroid Build Coastguard Worker sources << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()));
4058*35238bceSAndroid Build Coastguard Worker
4059*35238bceSAndroid Build Coastguard Worker if (m_state == STATE_PER_PRIMITIVE)
4060*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(
4061*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationControlSource().c_str()))
4062*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
4063*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationEvaluationSource().c_str()));
4064*35238bceSAndroid Build Coastguard Worker
4065*35238bceSAndroid Build Coastguard Worker m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources));
4066*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "build program");
4067*35238bceSAndroid Build Coastguard Worker
4068*35238bceSAndroid Build Coastguard Worker {
4069*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "ShaderProgram", "Shader program");
4070*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
4071*35238bceSAndroid Build Coastguard Worker }
4072*35238bceSAndroid Build Coastguard Worker
4073*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
4074*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
4075*35238bceSAndroid Build Coastguard Worker }
4076*35238bceSAndroid Build Coastguard Worker
4077*35238bceSAndroid Build Coastguard Worker // Generate VAO for desktop OpenGL
4078*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
4079*35238bceSAndroid Build Coastguard Worker {
4080*35238bceSAndroid Build Coastguard Worker gl.genVertexArrays(1, &m_vao);
4081*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(m_vao);
4082*35238bceSAndroid Build Coastguard Worker }
4083*35238bceSAndroid Build Coastguard Worker
4084*35238bceSAndroid Build Coastguard Worker {
4085*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> data;
4086*35238bceSAndroid Build Coastguard Worker
4087*35238bceSAndroid Build Coastguard Worker generateAttributeData(data);
4088*35238bceSAndroid Build Coastguard Worker
4089*35238bceSAndroid Build Coastguard Worker m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
4090*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
4091*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (int)(sizeof(tcu::Vec4) * data.size()), &data[0], GL_STATIC_DRAW);
4092*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "buf upload");
4093*35238bceSAndroid Build Coastguard Worker }
4094*35238bceSAndroid Build Coastguard Worker
4095*35238bceSAndroid Build Coastguard Worker // gen layers
4096*35238bceSAndroid Build Coastguard Worker {
4097*35238bceSAndroid Build Coastguard Worker de::Random rnd(0x12345);
4098*35238bceSAndroid Build Coastguard Worker
4099*35238bceSAndroid Build Coastguard Worker m_layers.resize(m_numLayers);
4100*35238bceSAndroid Build Coastguard Worker for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
4101*35238bceSAndroid Build Coastguard Worker {
4102*35238bceSAndroid Build Coastguard Worker m_layers[layerNdx].zOffset = ((float)layerNdx / (float)m_numLayers) * 2.0f - 1.0f;
4103*35238bceSAndroid Build Coastguard Worker m_layers[layerNdx].zScale = (2.0f / (float)m_numLayers);
4104*35238bceSAndroid Build Coastguard Worker m_layers[layerNdx].color1 =
4105*35238bceSAndroid Build Coastguard Worker (layerNdx == 0) ? (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
4106*35238bceSAndroid Build Coastguard Worker m_layers[layerNdx].color2 =
4107*35238bceSAndroid Build Coastguard Worker (layerNdx == 0) ? (tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f)) : (tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
4108*35238bceSAndroid Build Coastguard Worker }
4109*35238bceSAndroid Build Coastguard Worker rnd.shuffle(m_layers.begin(), m_layers.end());
4110*35238bceSAndroid Build Coastguard Worker }
4111*35238bceSAndroid Build Coastguard Worker }
4112*35238bceSAndroid Build Coastguard Worker
deinit(void)4113*35238bceSAndroid Build Coastguard Worker void DepthDrawCase::deinit(void)
4114*35238bceSAndroid Build Coastguard Worker {
4115*35238bceSAndroid Build Coastguard Worker m_program.clear();
4116*35238bceSAndroid Build Coastguard Worker m_vbo.clear();
4117*35238bceSAndroid Build Coastguard Worker
4118*35238bceSAndroid Build Coastguard Worker if (m_vao)
4119*35238bceSAndroid Build Coastguard Worker {
4120*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
4121*35238bceSAndroid Build Coastguard Worker m_vao = 0;
4122*35238bceSAndroid Build Coastguard Worker }
4123*35238bceSAndroid Build Coastguard Worker }
4124*35238bceSAndroid Build Coastguard Worker
iterate(void)4125*35238bceSAndroid Build Coastguard Worker DepthDrawCase::IterateResult DepthDrawCase::iterate(void)
4126*35238bceSAndroid Build Coastguard Worker {
4127*35238bceSAndroid Build Coastguard Worker const bool hasTessellation = (m_state == STATE_PER_PRIMITIVE);
4128*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4129*35238bceSAndroid Build Coastguard Worker const glw::GLint posLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
4130*35238bceSAndroid Build Coastguard Worker const glw::GLint colLocation = gl.getAttribLocation(m_program->getProgram(), "a_colorMix");
4131*35238bceSAndroid Build Coastguard Worker const glw::GLint depthBiasLocation = gl.getUniformLocation(m_program->getProgram(), "u_depthBias");
4132*35238bceSAndroid Build Coastguard Worker const glw::GLint depthScaleLocation = gl.getUniformLocation(m_program->getProgram(), "u_depthScale");
4133*35238bceSAndroid Build Coastguard Worker const glw::GLint color1Location = gl.getUniformLocation(m_program->getProgram(), "u_color1");
4134*35238bceSAndroid Build Coastguard Worker const glw::GLint color2Location = gl.getUniformLocation(m_program->getProgram(), "u_color2");
4135*35238bceSAndroid Build Coastguard Worker
4136*35238bceSAndroid Build Coastguard Worker tcu::Surface viewport(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
4137*35238bceSAndroid Build Coastguard Worker de::Random rnd(0x213237);
4138*35238bceSAndroid Build Coastguard Worker
4139*35238bceSAndroid Build Coastguard Worker TCU_CHECK(posLocation != -1);
4140*35238bceSAndroid Build Coastguard Worker TCU_CHECK(colLocation != -1);
4141*35238bceSAndroid Build Coastguard Worker TCU_CHECK(depthBiasLocation != -1);
4142*35238bceSAndroid Build Coastguard Worker TCU_CHECK(depthScaleLocation != -1);
4143*35238bceSAndroid Build Coastguard Worker TCU_CHECK(color1Location != -1);
4144*35238bceSAndroid Build Coastguard Worker TCU_CHECK(color2Location != -1);
4145*35238bceSAndroid Build Coastguard Worker
4146*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, RENDER_AREA_SIZE, RENDER_AREA_SIZE);
4147*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
4148*35238bceSAndroid Build Coastguard Worker gl.clearDepthf(1.0f);
4149*35238bceSAndroid Build Coastguard Worker gl.depthFunc(GL_LESS);
4150*35238bceSAndroid Build Coastguard Worker gl.enable(GL_DEPTH_TEST);
4151*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4152*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup viewport");
4153*35238bceSAndroid Build Coastguard Worker
4154*35238bceSAndroid Build Coastguard Worker auto boundingBoxFunc = getBoundingBoxFunction(m_context);
4155*35238bceSAndroid Build Coastguard Worker
4156*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
4157*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)),
4158*35238bceSAndroid Build Coastguard Worker glu::BufferOffsetAsPointer(0 * sizeof(float)));
4159*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(colLocation, 4, GL_FLOAT, GL_FALSE, (int)(8 * sizeof(float)),
4160*35238bceSAndroid Build Coastguard Worker glu::BufferOffsetAsPointer(4 * sizeof(float)));
4161*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
4162*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(colLocation);
4163*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
4164*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup va");
4165*35238bceSAndroid Build Coastguard Worker
4166*35238bceSAndroid Build Coastguard Worker if (hasTessellation)
4167*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 3);
4168*35238bceSAndroid Build Coastguard Worker
4169*35238bceSAndroid Build Coastguard Worker for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
4170*35238bceSAndroid Build Coastguard Worker {
4171*35238bceSAndroid Build Coastguard Worker gl.uniform1f(depthBiasLocation, m_layers[layerNdx].zOffset);
4172*35238bceSAndroid Build Coastguard Worker gl.uniform1f(depthScaleLocation, m_layers[layerNdx].zScale);
4173*35238bceSAndroid Build Coastguard Worker gl.uniform4fv(color1Location, 1, m_layers[layerNdx].color1.getPtr());
4174*35238bceSAndroid Build Coastguard Worker gl.uniform4fv(color2Location, 1, m_layers[layerNdx].color2.getPtr());
4175*35238bceSAndroid Build Coastguard Worker
4176*35238bceSAndroid Build Coastguard Worker if (m_state == STATE_GLOBAL)
4177*35238bceSAndroid Build Coastguard Worker {
4178*35238bceSAndroid Build Coastguard Worker const float negPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);
4179*35238bceSAndroid Build Coastguard Worker const float posPadding = (m_bboxSize == BBOX_EQUAL) ? (0.0f) : (rnd.getFloat() * 0.3f);
4180*35238bceSAndroid Build Coastguard Worker
4181*35238bceSAndroid Build Coastguard Worker boundingBoxFunc(-1.0f, -1.0f, m_layers[layerNdx].zOffset - negPadding, 1.0f, 1.0f, 1.0f,
4182*35238bceSAndroid Build Coastguard Worker (m_layers[layerNdx].zOffset + m_layers[layerNdx].zScale + posPadding), 1.0f);
4183*35238bceSAndroid Build Coastguard Worker }
4184*35238bceSAndroid Build Coastguard Worker
4185*35238bceSAndroid Build Coastguard Worker gl.drawArrays((hasTessellation) ? (GL_PATCHES) : (GL_TRIANGLES), 0, m_gridSize * m_gridSize * 6);
4186*35238bceSAndroid Build Coastguard Worker }
4187*35238bceSAndroid Build Coastguard Worker
4188*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, viewport.getAccess());
4189*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "render and read");
4190*35238bceSAndroid Build Coastguard Worker
4191*35238bceSAndroid Build Coastguard Worker if (verifyImage(viewport))
4192*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4193*35238bceSAndroid Build Coastguard Worker else
4194*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
4195*35238bceSAndroid Build Coastguard Worker
4196*35238bceSAndroid Build Coastguard Worker return STOP;
4197*35238bceSAndroid Build Coastguard Worker }
4198*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const4199*35238bceSAndroid Build Coastguard Worker std::string DepthDrawCase::genVertexSource(void) const
4200*35238bceSAndroid Build Coastguard Worker {
4201*35238bceSAndroid Build Coastguard Worker const bool hasTessellation = (m_state == STATE_PER_PRIMITIVE);
4202*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
4203*35238bceSAndroid Build Coastguard Worker
4204*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
4205*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
4206*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_colorMix;\n"
4207*35238bceSAndroid Build Coastguard Worker "out highp vec4 vtx_colorMix;\n";
4208*35238bceSAndroid Build Coastguard Worker
4209*35238bceSAndroid Build Coastguard Worker if (!hasTessellation && m_depthType == DEPTH_USER_DEFINED)
4210*35238bceSAndroid Build Coastguard Worker buf << "out highp float v_fragDepth;\n";
4211*35238bceSAndroid Build Coastguard Worker
4212*35238bceSAndroid Build Coastguard Worker if (!hasTessellation)
4213*35238bceSAndroid Build Coastguard Worker buf << "uniform highp float u_depthBias;\n"
4214*35238bceSAndroid Build Coastguard Worker "uniform highp float u_depthScale;\n";
4215*35238bceSAndroid Build Coastguard Worker
4216*35238bceSAndroid Build Coastguard Worker buf << "\n"
4217*35238bceSAndroid Build Coastguard Worker "void main()\n"
4218*35238bceSAndroid Build Coastguard Worker "{\n";
4219*35238bceSAndroid Build Coastguard Worker
4220*35238bceSAndroid Build Coastguard Worker if (hasTessellation)
4221*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = a_position;\n";
4222*35238bceSAndroid Build Coastguard Worker else if (m_depthType == DEPTH_USER_DEFINED)
4223*35238bceSAndroid Build Coastguard Worker buf << " highp float unusedZ = a_position.z;\n"
4224*35238bceSAndroid Build Coastguard Worker " highp float writtenZ = a_position.w;\n"
4225*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(a_position.xy, unusedZ, 1.0);\n"
4226*35238bceSAndroid Build Coastguard Worker " v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
4227*35238bceSAndroid Build Coastguard Worker else
4228*35238bceSAndroid Build Coastguard Worker buf << " highp float writtenZ = a_position.w;\n"
4229*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(a_position.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";
4230*35238bceSAndroid Build Coastguard Worker
4231*35238bceSAndroid Build Coastguard Worker buf << " vtx_colorMix = a_colorMix;\n"
4232*35238bceSAndroid Build Coastguard Worker "}\n";
4233*35238bceSAndroid Build Coastguard Worker
4234*35238bceSAndroid Build Coastguard Worker return buf.str();
4235*35238bceSAndroid Build Coastguard Worker }
4236*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const4237*35238bceSAndroid Build Coastguard Worker std::string DepthDrawCase::genFragmentSource(void) const
4238*35238bceSAndroid Build Coastguard Worker {
4239*35238bceSAndroid Build Coastguard Worker const bool hasTessellation = (m_state == STATE_PER_PRIMITIVE);
4240*35238bceSAndroid Build Coastguard Worker const char *const colorMixName = (hasTessellation) ? ("tess_eval_colorMix") : ("vtx_colorMix");
4241*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
4242*35238bceSAndroid Build Coastguard Worker
4243*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
4244*35238bceSAndroid Build Coastguard Worker "in mediump vec4 "
4245*35238bceSAndroid Build Coastguard Worker << colorMixName << ";\n";
4246*35238bceSAndroid Build Coastguard Worker
4247*35238bceSAndroid Build Coastguard Worker if (m_depthType == DEPTH_USER_DEFINED)
4248*35238bceSAndroid Build Coastguard Worker buf << "in mediump float v_fragDepth;\n";
4249*35238bceSAndroid Build Coastguard Worker
4250*35238bceSAndroid Build Coastguard Worker buf << "layout(location = 0) out mediump vec4 o_color;\n"
4251*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_color1;\n"
4252*35238bceSAndroid Build Coastguard Worker "uniform highp vec4 u_color2;\n"
4253*35238bceSAndroid Build Coastguard Worker "\n"
4254*35238bceSAndroid Build Coastguard Worker "void main()\n"
4255*35238bceSAndroid Build Coastguard Worker "{\n"
4256*35238bceSAndroid Build Coastguard Worker " o_color = mix(u_color1, u_color2, "
4257*35238bceSAndroid Build Coastguard Worker << colorMixName << ");\n";
4258*35238bceSAndroid Build Coastguard Worker
4259*35238bceSAndroid Build Coastguard Worker if (m_depthType == DEPTH_USER_DEFINED)
4260*35238bceSAndroid Build Coastguard Worker buf << " gl_FragDepth = v_fragDepth * 0.5 + 0.5;\n";
4261*35238bceSAndroid Build Coastguard Worker
4262*35238bceSAndroid Build Coastguard Worker buf << "}\n";
4263*35238bceSAndroid Build Coastguard Worker
4264*35238bceSAndroid Build Coastguard Worker return buf.str();
4265*35238bceSAndroid Build Coastguard Worker }
4266*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const4267*35238bceSAndroid Build Coastguard Worker std::string DepthDrawCase::genTessellationControlSource(void) const
4268*35238bceSAndroid Build Coastguard Worker {
4269*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
4270*35238bceSAndroid Build Coastguard Worker
4271*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
4272*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
4273*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
4274*35238bceSAndroid Build Coastguard Worker "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n"
4275*35238bceSAndroid Build Coastguard Worker "layout(vertices=3) out;\n"
4276*35238bceSAndroid Build Coastguard Worker "\n"
4277*35238bceSAndroid Build Coastguard Worker "uniform highp float u_depthBias;\n"
4278*35238bceSAndroid Build Coastguard Worker "uniform highp float u_depthScale;\n"
4279*35238bceSAndroid Build Coastguard Worker "\n"
4280*35238bceSAndroid Build Coastguard Worker "in highp vec4 vtx_colorMix[];\n"
4281*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_ctrl_colorMix[];\n"
4282*35238bceSAndroid Build Coastguard Worker "\n"
4283*35238bceSAndroid Build Coastguard Worker "void main()\n"
4284*35238bceSAndroid Build Coastguard Worker "{\n"
4285*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
4286*35238bceSAndroid Build Coastguard Worker " tess_ctrl_colorMix[gl_InvocationID] = vtx_colorMix[0];\n"
4287*35238bceSAndroid Build Coastguard Worker "\n"
4288*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 2.8;\n"
4289*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 2.8;\n"
4290*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 2.8;\n"
4291*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 2.8;\n"
4292*35238bceSAndroid Build Coastguard Worker "\n"
4293*35238bceSAndroid Build Coastguard Worker " // real Z stored in w component\n"
4294*35238bceSAndroid Build Coastguard Worker " highp vec4 minBound = vec4(min(min(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale "
4295*35238bceSAndroid Build Coastguard Worker "+ u_depthBias),\n"
4296*35238bceSAndroid Build Coastguard Worker " vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale "
4297*35238bceSAndroid Build Coastguard Worker "+ u_depthBias)),\n"
4298*35238bceSAndroid Build Coastguard Worker " vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + "
4299*35238bceSAndroid Build Coastguard Worker "u_depthBias)), 1.0);\n"
4300*35238bceSAndroid Build Coastguard Worker " highp vec4 maxBound = vec4(max(max(vec3(gl_in[0].gl_Position.xy, gl_in[0].gl_Position.w * u_depthScale "
4301*35238bceSAndroid Build Coastguard Worker "+ u_depthBias),\n"
4302*35238bceSAndroid Build Coastguard Worker " vec3(gl_in[1].gl_Position.xy, gl_in[1].gl_Position.w * u_depthScale "
4303*35238bceSAndroid Build Coastguard Worker "+ u_depthBias)),\n"
4304*35238bceSAndroid Build Coastguard Worker " vec3(gl_in[2].gl_Position.xy, gl_in[2].gl_Position.w * u_depthScale + "
4305*35238bceSAndroid Build Coastguard Worker "u_depthBias)), 1.0);\n";
4306*35238bceSAndroid Build Coastguard Worker
4307*35238bceSAndroid Build Coastguard Worker if (m_bboxSize == BBOX_EQUAL)
4308*35238bceSAndroid Build Coastguard Worker buf << " ${PRIM_GL_BOUNDING_BOX}[0] = minBound;\n"
4309*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = maxBound;\n";
4310*35238bceSAndroid Build Coastguard Worker else
4311*35238bceSAndroid Build Coastguard Worker buf << " highp float nedPadding = mod(gl_in[0].gl_Position.z, 0.3);\n"
4312*35238bceSAndroid Build Coastguard Worker " highp float posPadding = mod(gl_in[1].gl_Position.z, 0.3);\n"
4313*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[0] = minBound - vec4(0.0, 0.0, nedPadding, 0.0);\n"
4314*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = maxBound + vec4(0.0, 0.0, posPadding, 0.0);\n";
4315*35238bceSAndroid Build Coastguard Worker
4316*35238bceSAndroid Build Coastguard Worker buf << "}\n";
4317*35238bceSAndroid Build Coastguard Worker
4318*35238bceSAndroid Build Coastguard Worker return buf.str();
4319*35238bceSAndroid Build Coastguard Worker }
4320*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const4321*35238bceSAndroid Build Coastguard Worker std::string DepthDrawCase::genTessellationEvaluationSource(void) const
4322*35238bceSAndroid Build Coastguard Worker {
4323*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
4324*35238bceSAndroid Build Coastguard Worker
4325*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
4326*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
4327*35238bceSAndroid Build Coastguard Worker "${GPU_SHADER5_REQUIRE}\n"
4328*35238bceSAndroid Build Coastguard Worker "layout(triangles) in;\n"
4329*35238bceSAndroid Build Coastguard Worker "\n"
4330*35238bceSAndroid Build Coastguard Worker "in highp vec4 tess_ctrl_colorMix[];\n"
4331*35238bceSAndroid Build Coastguard Worker "out highp vec4 tess_eval_colorMix;\n";
4332*35238bceSAndroid Build Coastguard Worker
4333*35238bceSAndroid Build Coastguard Worker if (m_depthType == DEPTH_USER_DEFINED)
4334*35238bceSAndroid Build Coastguard Worker buf << "out highp float v_fragDepth;\n";
4335*35238bceSAndroid Build Coastguard Worker
4336*35238bceSAndroid Build Coastguard Worker buf << "uniform highp float u_depthBias;\n"
4337*35238bceSAndroid Build Coastguard Worker "uniform highp float u_depthScale;\n"
4338*35238bceSAndroid Build Coastguard Worker "\n"
4339*35238bceSAndroid Build Coastguard Worker "precise gl_Position;\n"
4340*35238bceSAndroid Build Coastguard Worker "\n"
4341*35238bceSAndroid Build Coastguard Worker "void main()\n"
4342*35238bceSAndroid Build Coastguard Worker "{\n"
4343*35238bceSAndroid Build Coastguard Worker " highp vec4 tessellatedPos = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * "
4344*35238bceSAndroid Build Coastguard Worker "gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n";
4345*35238bceSAndroid Build Coastguard Worker
4346*35238bceSAndroid Build Coastguard Worker if (m_depthType == DEPTH_USER_DEFINED)
4347*35238bceSAndroid Build Coastguard Worker buf << " highp float unusedZ = tessellatedPos.z;\n"
4348*35238bceSAndroid Build Coastguard Worker " highp float writtenZ = tessellatedPos.w;\n"
4349*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(tessellatedPos.xy, unusedZ, 1.0);\n"
4350*35238bceSAndroid Build Coastguard Worker " v_fragDepth = writtenZ * u_depthScale + u_depthBias;\n";
4351*35238bceSAndroid Build Coastguard Worker else
4352*35238bceSAndroid Build Coastguard Worker buf << " highp float writtenZ = tessellatedPos.w;\n"
4353*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(tessellatedPos.xy, writtenZ * u_depthScale + u_depthBias, 1.0);\n";
4354*35238bceSAndroid Build Coastguard Worker
4355*35238bceSAndroid Build Coastguard Worker buf << " tess_eval_colorMix = tess_ctrl_colorMix[0];\n"
4356*35238bceSAndroid Build Coastguard Worker "}\n";
4357*35238bceSAndroid Build Coastguard Worker
4358*35238bceSAndroid Build Coastguard Worker return buf.str();
4359*35238bceSAndroid Build Coastguard Worker }
4360*35238bceSAndroid Build Coastguard Worker
generateAttributeData(std::vector<tcu::Vec4> & data) const4361*35238bceSAndroid Build Coastguard Worker void DepthDrawCase::generateAttributeData(std::vector<tcu::Vec4> &data) const
4362*35238bceSAndroid Build Coastguard Worker {
4363*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 color1(0.0f, 0.0f, 0.0f, 0.0f); // mix weights
4364*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 color2(1.0f, 1.0f, 1.0f, 1.0f);
4365*35238bceSAndroid Build Coastguard Worker std::vector<int> cellOrder(m_gridSize * m_gridSize);
4366*35238bceSAndroid Build Coastguard Worker de::Random rnd(0xAB54321);
4367*35238bceSAndroid Build Coastguard Worker
4368*35238bceSAndroid Build Coastguard Worker // generate grid with cells in random order
4369*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
4370*35238bceSAndroid Build Coastguard Worker cellOrder[ndx] = ndx;
4371*35238bceSAndroid Build Coastguard Worker rnd.shuffle(cellOrder.begin(), cellOrder.end());
4372*35238bceSAndroid Build Coastguard Worker
4373*35238bceSAndroid Build Coastguard Worker data.resize(m_gridSize * m_gridSize * 6 * 2);
4374*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
4375*35238bceSAndroid Build Coastguard Worker {
4376*35238bceSAndroid Build Coastguard Worker const int cellNdx = cellOrder[ndx];
4377*35238bceSAndroid Build Coastguard Worker const int cellX = cellNdx % m_gridSize;
4378*35238bceSAndroid Build Coastguard Worker const int cellY = cellNdx / m_gridSize;
4379*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &cellColor = ((cellX + cellY) % 2 == 0) ? (color1) : (color2);
4380*35238bceSAndroid Build Coastguard Worker
4381*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 0] = tcu::Vec4(float(cellX + 0) / float(m_gridSize) * 2.0f - 1.0f,
4382*35238bceSAndroid Build Coastguard Worker float(cellY + 0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4383*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 1] = cellColor;
4384*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 2] = tcu::Vec4(float(cellX + 1) / float(m_gridSize) * 2.0f - 1.0f,
4385*35238bceSAndroid Build Coastguard Worker float(cellY + 1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4386*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 3] = cellColor;
4387*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 4] = tcu::Vec4(float(cellX + 0) / float(m_gridSize) * 2.0f - 1.0f,
4388*35238bceSAndroid Build Coastguard Worker float(cellY + 1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4389*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 5] = cellColor;
4390*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 6] = tcu::Vec4(float(cellX + 0) / float(m_gridSize) * 2.0f - 1.0f,
4391*35238bceSAndroid Build Coastguard Worker float(cellY + 0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4392*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 7] = cellColor;
4393*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 8] = tcu::Vec4(float(cellX + 1) / float(m_gridSize) * 2.0f - 1.0f,
4394*35238bceSAndroid Build Coastguard Worker float(cellY + 0) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4395*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 9] = cellColor;
4396*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 10] = tcu::Vec4(float(cellX + 1) / float(m_gridSize) * 2.0f - 1.0f,
4397*35238bceSAndroid Build Coastguard Worker float(cellY + 1) / float(m_gridSize) * 2.0f - 1.0f, 0.0f, 0.0f);
4398*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 11] = cellColor;
4399*35238bceSAndroid Build Coastguard Worker
4400*35238bceSAndroid Build Coastguard Worker // Fill Z with random values (fake Z)
4401*35238bceSAndroid Build Coastguard Worker for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
4402*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 2 * vtxNdx].z() = rnd.getFloat(0.0f, 1.0);
4403*35238bceSAndroid Build Coastguard Worker
4404*35238bceSAndroid Build Coastguard Worker // Fill W with other random values (written Z)
4405*35238bceSAndroid Build Coastguard Worker for (int vtxNdx = 0; vtxNdx < 6; ++vtxNdx)
4406*35238bceSAndroid Build Coastguard Worker data[ndx * 6 * 2 + 2 * vtxNdx].w() = rnd.getFloat(0.0f, 1.0);
4407*35238bceSAndroid Build Coastguard Worker }
4408*35238bceSAndroid Build Coastguard Worker }
4409*35238bceSAndroid Build Coastguard Worker
verifyImage(const tcu::Surface & viewport) const4410*35238bceSAndroid Build Coastguard Worker bool DepthDrawCase::verifyImage(const tcu::Surface &viewport) const
4411*35238bceSAndroid Build Coastguard Worker {
4412*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(viewport.getWidth(), viewport.getHeight());
4413*35238bceSAndroid Build Coastguard Worker bool anyError = false;
4414*35238bceSAndroid Build Coastguard Worker
4415*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::IVec4(0, 0, 0, 255));
4416*35238bceSAndroid Build Coastguard Worker
4417*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < viewport.getHeight(); ++y)
4418*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < viewport.getWidth(); ++x)
4419*35238bceSAndroid Build Coastguard Worker {
4420*35238bceSAndroid Build Coastguard Worker const tcu::RGBA pixel = viewport.getPixel(x, y);
4421*35238bceSAndroid Build Coastguard Worker bool error = false;
4422*35238bceSAndroid Build Coastguard Worker
4423*35238bceSAndroid Build Coastguard Worker // expect green, yellow or a combination of these
4424*35238bceSAndroid Build Coastguard Worker if (pixel.getGreen() != 255 || pixel.getBlue() != 0)
4425*35238bceSAndroid Build Coastguard Worker error = true;
4426*35238bceSAndroid Build Coastguard Worker
4427*35238bceSAndroid Build Coastguard Worker if (error)
4428*35238bceSAndroid Build Coastguard Worker {
4429*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
4430*35238bceSAndroid Build Coastguard Worker anyError = true;
4431*35238bceSAndroid Build Coastguard Worker }
4432*35238bceSAndroid Build Coastguard Worker }
4433*35238bceSAndroid Build Coastguard Worker
4434*35238bceSAndroid Build Coastguard Worker if (anyError)
4435*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
4436*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
4437*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
4438*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
4439*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
4440*35238bceSAndroid Build Coastguard Worker else
4441*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result image ok." << tcu::TestLog::EndMessage
4442*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
4443*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Viewport", "Viewport contents", viewport.getAccess())
4444*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
4445*35238bceSAndroid Build Coastguard Worker
4446*35238bceSAndroid Build Coastguard Worker return !anyError;
4447*35238bceSAndroid Build Coastguard Worker }
4448*35238bceSAndroid Build Coastguard Worker
4449*35238bceSAndroid Build Coastguard Worker class ClearCase : public TestCase
4450*35238bceSAndroid Build Coastguard Worker {
4451*35238bceSAndroid Build Coastguard Worker public:
4452*35238bceSAndroid Build Coastguard Worker enum
4453*35238bceSAndroid Build Coastguard Worker {
4454*35238bceSAndroid Build Coastguard Worker SCISSOR_CLEAR_BIT = 1 << 0,
4455*35238bceSAndroid Build Coastguard Worker DRAW_TRIANGLE_BIT = 1 << 1,
4456*35238bceSAndroid Build Coastguard Worker PER_PRIMITIVE_BBOX_BIT = 1 << 2,
4457*35238bceSAndroid Build Coastguard Worker FULLSCREEN_SCISSOR_BIT = 1 << 3,
4458*35238bceSAndroid Build Coastguard Worker };
4459*35238bceSAndroid Build Coastguard Worker
4460*35238bceSAndroid Build Coastguard Worker ClearCase(Context &context, const char *name, const char *description, uint32_t flags);
4461*35238bceSAndroid Build Coastguard Worker ~ClearCase(void);
4462*35238bceSAndroid Build Coastguard Worker
4463*35238bceSAndroid Build Coastguard Worker private:
4464*35238bceSAndroid Build Coastguard Worker struct DrawObject
4465*35238bceSAndroid Build Coastguard Worker {
4466*35238bceSAndroid Build Coastguard Worker int firstNdx;
4467*35238bceSAndroid Build Coastguard Worker int numVertices;
4468*35238bceSAndroid Build Coastguard Worker };
4469*35238bceSAndroid Build Coastguard Worker
4470*35238bceSAndroid Build Coastguard Worker void init(void);
4471*35238bceSAndroid Build Coastguard Worker void deinit(void);
4472*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
4473*35238bceSAndroid Build Coastguard Worker
4474*35238bceSAndroid Build Coastguard Worker void createVbo(void);
4475*35238bceSAndroid Build Coastguard Worker void createProgram(void);
4476*35238bceSAndroid Build Coastguard Worker void renderTo(tcu::Surface &dst, bool useBBox);
4477*35238bceSAndroid Build Coastguard Worker bool verifyImagesEqual(const tcu::PixelBufferAccess &withoutBBox, const tcu::PixelBufferAccess &withBBox);
4478*35238bceSAndroid Build Coastguard Worker bool verifyImageResultValid(const tcu::PixelBufferAccess &result);
4479*35238bceSAndroid Build Coastguard Worker
4480*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
4481*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
4482*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(bool setBBox) const;
4483*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
4484*35238bceSAndroid Build Coastguard Worker
4485*35238bceSAndroid Build Coastguard Worker const bool m_scissoredClear;
4486*35238bceSAndroid Build Coastguard Worker const bool m_fullscreenScissor;
4487*35238bceSAndroid Build Coastguard Worker const bool m_drawTriangles;
4488*35238bceSAndroid Build Coastguard Worker const bool m_useGlobalState;
4489*35238bceSAndroid Build Coastguard Worker
4490*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Buffer> m_vbo;
4491*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_perPrimitiveProgram;
4492*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_basicProgram;
4493*35238bceSAndroid Build Coastguard Worker std::vector<DrawObject> m_drawObjects;
4494*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> m_objectVertices;
4495*35238bceSAndroid Build Coastguard Worker };
4496*35238bceSAndroid Build Coastguard Worker
ClearCase(Context & context,const char * name,const char * description,uint32_t flags)4497*35238bceSAndroid Build Coastguard Worker ClearCase::ClearCase(Context &context, const char *name, const char *description, uint32_t flags)
4498*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
4499*35238bceSAndroid Build Coastguard Worker , m_scissoredClear((flags & SCISSOR_CLEAR_BIT) != 0)
4500*35238bceSAndroid Build Coastguard Worker , m_fullscreenScissor((flags & FULLSCREEN_SCISSOR_BIT) != 0)
4501*35238bceSAndroid Build Coastguard Worker , m_drawTriangles((flags & DRAW_TRIANGLE_BIT) != 0)
4502*35238bceSAndroid Build Coastguard Worker , m_useGlobalState((flags & PER_PRIMITIVE_BBOX_BIT) == 0)
4503*35238bceSAndroid Build Coastguard Worker {
4504*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState || m_drawTriangles); // per-triangle bbox requires triangles
4505*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_fullscreenScissor || m_scissoredClear); // fullscreenScissor requires scissoredClear
4506*35238bceSAndroid Build Coastguard Worker }
4507*35238bceSAndroid Build Coastguard Worker
~ClearCase(void)4508*35238bceSAndroid Build Coastguard Worker ClearCase::~ClearCase(void)
4509*35238bceSAndroid Build Coastguard Worker {
4510*35238bceSAndroid Build Coastguard Worker deinit();
4511*35238bceSAndroid Build Coastguard Worker }
4512*35238bceSAndroid Build Coastguard Worker
init(void)4513*35238bceSAndroid Build Coastguard Worker void ClearCase::init(void)
4514*35238bceSAndroid Build Coastguard Worker {
4515*35238bceSAndroid Build Coastguard Worker const bool hasES32OrGL45 = supportsES32OrGL45(m_context);
4516*35238bceSAndroid Build Coastguard Worker
4517*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
4518*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
4519*35238bceSAndroid Build Coastguard Worker if (m_drawTriangles && !hasES32OrGL45 &&
4520*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
4521*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
4522*35238bceSAndroid Build Coastguard Worker
4523*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Doing multiple" << ((m_scissoredClear) ? (" scissored") : (""))
4524*35238bceSAndroid Build Coastguard Worker << " color buffer clears"
4525*35238bceSAndroid Build Coastguard Worker << ((m_drawTriangles) ? (" and drawing some geometry between them") : ("")) << ".\n"
4526*35238bceSAndroid Build Coastguard Worker << ((m_scissoredClear && m_fullscreenScissor) ?
4527*35238bceSAndroid Build Coastguard Worker ("Setting scissor area to cover entire viewport.\n") :
4528*35238bceSAndroid Build Coastguard Worker (""))
4529*35238bceSAndroid Build Coastguard Worker << "Rendering with and without setting the bounding box.\n"
4530*35238bceSAndroid Build Coastguard Worker << "Expecting bounding box to have no effect on clears (i.e. results are constant).\n"
4531*35238bceSAndroid Build Coastguard Worker << "Set bounding box using "
4532*35238bceSAndroid Build Coastguard Worker << ((m_useGlobalState) ? ("PRIMITIVE_BOUNDING_BOX_EXT state") : ("gl_BoundingBoxEXT output"))
4533*35238bceSAndroid Build Coastguard Worker << ".\n"
4534*35238bceSAndroid Build Coastguard Worker << "Clear color is green with yellowish shades.\n"
4535*35238bceSAndroid Build Coastguard Worker << ((m_drawTriangles) ? ("Primitive color is yellow with greenish shades.\n") : (""))
4536*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
4537*35238bceSAndroid Build Coastguard Worker
4538*35238bceSAndroid Build Coastguard Worker if (m_drawTriangles)
4539*35238bceSAndroid Build Coastguard Worker {
4540*35238bceSAndroid Build Coastguard Worker createVbo();
4541*35238bceSAndroid Build Coastguard Worker createProgram();
4542*35238bceSAndroid Build Coastguard Worker }
4543*35238bceSAndroid Build Coastguard Worker }
4544*35238bceSAndroid Build Coastguard Worker
deinit(void)4545*35238bceSAndroid Build Coastguard Worker void ClearCase::deinit(void)
4546*35238bceSAndroid Build Coastguard Worker {
4547*35238bceSAndroid Build Coastguard Worker m_vbo.clear();
4548*35238bceSAndroid Build Coastguard Worker m_perPrimitiveProgram.clear();
4549*35238bceSAndroid Build Coastguard Worker m_basicProgram.clear();
4550*35238bceSAndroid Build Coastguard Worker m_drawObjects = std::vector<DrawObject>();
4551*35238bceSAndroid Build Coastguard Worker m_objectVertices = std::vector<tcu::Vec4>();
4552*35238bceSAndroid Build Coastguard Worker }
4553*35238bceSAndroid Build Coastguard Worker
iterate(void)4554*35238bceSAndroid Build Coastguard Worker ClearCase::IterateResult ClearCase::iterate(void)
4555*35238bceSAndroid Build Coastguard Worker {
4556*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 renderTargetSize(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
4557*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithoutBBox(renderTargetSize.x(), renderTargetSize.y());
4558*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithBBox(renderTargetSize.x(), renderTargetSize.y());
4559*35238bceSAndroid Build Coastguard Worker
4560*35238bceSAndroid Build Coastguard Worker // render with and without bbox set
4561*35238bceSAndroid Build Coastguard Worker for (int passNdx = 0; passNdx < 2; ++passNdx)
4562*35238bceSAndroid Build Coastguard Worker {
4563*35238bceSAndroid Build Coastguard Worker const bool useBBox = (passNdx == 1);
4564*35238bceSAndroid Build Coastguard Worker tcu::Surface &destination = (useBBox) ? (resultWithBBox) : (resultWithoutBBox);
4565*35238bceSAndroid Build Coastguard Worker
4566*35238bceSAndroid Build Coastguard Worker renderTo(destination, useBBox);
4567*35238bceSAndroid Build Coastguard Worker }
4568*35238bceSAndroid Build Coastguard Worker
4569*35238bceSAndroid Build Coastguard Worker // Verify images are equal and that the image does not contain (trivially detectable) garbage
4570*35238bceSAndroid Build Coastguard Worker
4571*35238bceSAndroid Build Coastguard Worker if (!verifyImagesEqual(resultWithoutBBox.getAccess(), resultWithBBox.getAccess()))
4572*35238bceSAndroid Build Coastguard Worker {
4573*35238bceSAndroid Build Coastguard Worker // verifyImagesEqual will print out the image and error mask
4574*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
4575*35238bceSAndroid Build Coastguard Worker }
4576*35238bceSAndroid Build Coastguard Worker else if (!verifyImageResultValid(resultWithBBox.getAccess()))
4577*35238bceSAndroid Build Coastguard Worker {
4578*35238bceSAndroid Build Coastguard Worker // verifyImageResultValid will print out the image and error mask
4579*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
4580*35238bceSAndroid Build Coastguard Worker }
4581*35238bceSAndroid Build Coastguard Worker else
4582*35238bceSAndroid Build Coastguard Worker {
4583*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image comparison passed." << tcu::TestLog::EndMessage
4584*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
4585*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Result", resultWithBBox.getAccess())
4586*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
4587*35238bceSAndroid Build Coastguard Worker
4588*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4589*35238bceSAndroid Build Coastguard Worker }
4590*35238bceSAndroid Build Coastguard Worker
4591*35238bceSAndroid Build Coastguard Worker return STOP;
4592*35238bceSAndroid Build Coastguard Worker }
4593*35238bceSAndroid Build Coastguard Worker
createVbo(void)4594*35238bceSAndroid Build Coastguard Worker void ClearCase::createVbo(void)
4595*35238bceSAndroid Build Coastguard Worker {
4596*35238bceSAndroid Build Coastguard Worker const int numObjects = 16;
4597*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4598*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()));
4599*35238bceSAndroid Build Coastguard Worker
4600*35238bceSAndroid Build Coastguard Worker m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
4601*35238bceSAndroid Build Coastguard Worker
4602*35238bceSAndroid Build Coastguard Worker for (int objectNdx = 0; objectNdx < numObjects; ++objectNdx)
4603*35238bceSAndroid Build Coastguard Worker {
4604*35238bceSAndroid Build Coastguard Worker const int numTriangles = rnd.getInt(1, 4);
4605*35238bceSAndroid Build Coastguard Worker const float minX = rnd.getFloat(-1.2f, 0.8f);
4606*35238bceSAndroid Build Coastguard Worker const float minY = rnd.getFloat(-1.2f, 0.8f);
4607*35238bceSAndroid Build Coastguard Worker const float maxX = minX + rnd.getFloat(0.2f, 1.0f);
4608*35238bceSAndroid Build Coastguard Worker const float maxY = minY + rnd.getFloat(0.2f, 1.0f);
4609*35238bceSAndroid Build Coastguard Worker
4610*35238bceSAndroid Build Coastguard Worker DrawObject drawObject;
4611*35238bceSAndroid Build Coastguard Worker drawObject.firstNdx = (int)m_objectVertices.size();
4612*35238bceSAndroid Build Coastguard Worker drawObject.numVertices = numTriangles * 3;
4613*35238bceSAndroid Build Coastguard Worker
4614*35238bceSAndroid Build Coastguard Worker m_drawObjects.push_back(drawObject);
4615*35238bceSAndroid Build Coastguard Worker
4616*35238bceSAndroid Build Coastguard Worker for (int triangleNdx = 0; triangleNdx < numTriangles; ++triangleNdx)
4617*35238bceSAndroid Build Coastguard Worker for (int vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
4618*35238bceSAndroid Build Coastguard Worker {
4619*35238bceSAndroid Build Coastguard Worker const float posX = rnd.getFloat(minX, maxX);
4620*35238bceSAndroid Build Coastguard Worker const float posY = rnd.getFloat(minY, maxY);
4621*35238bceSAndroid Build Coastguard Worker const float posZ = rnd.getFloat(-0.7f, 0.7f);
4622*35238bceSAndroid Build Coastguard Worker const float posW = rnd.getFloat(0.9f, 1.1f);
4623*35238bceSAndroid Build Coastguard Worker
4624*35238bceSAndroid Build Coastguard Worker m_objectVertices.push_back(tcu::Vec4(posX, posY, posZ, posW));
4625*35238bceSAndroid Build Coastguard Worker }
4626*35238bceSAndroid Build Coastguard Worker }
4627*35238bceSAndroid Build Coastguard Worker
4628*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
4629*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (int)(m_objectVertices.size() * sizeof(tcu::Vec4)), &m_objectVertices[0],
4630*35238bceSAndroid Build Coastguard Worker GL_STATIC_DRAW);
4631*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "buffer upload");
4632*35238bceSAndroid Build Coastguard Worker }
4633*35238bceSAndroid Build Coastguard Worker
createProgram(void)4634*35238bceSAndroid Build Coastguard Worker void ClearCase::createProgram(void)
4635*35238bceSAndroid Build Coastguard Worker {
4636*35238bceSAndroid Build Coastguard Worker m_basicProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(
4637*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
4638*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
4639*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
4640*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(
4641*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationControlSource(false).c_str()))
4642*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
4643*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationEvaluationSource().c_str()))));
4644*35238bceSAndroid Build Coastguard Worker
4645*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Section("Program", "Shader program") << *m_basicProgram
4646*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndSection;
4647*35238bceSAndroid Build Coastguard Worker
4648*35238bceSAndroid Build Coastguard Worker if (!m_basicProgram->isOk())
4649*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("shader build failed");
4650*35238bceSAndroid Build Coastguard Worker
4651*35238bceSAndroid Build Coastguard Worker if (!m_useGlobalState)
4652*35238bceSAndroid Build Coastguard Worker {
4653*35238bceSAndroid Build Coastguard Worker m_perPrimitiveProgram = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(
4654*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
4655*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
4656*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
4657*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(
4658*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationControlSource(true).c_str()))
4659*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
4660*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationEvaluationSource().c_str()))));
4661*35238bceSAndroid Build Coastguard Worker
4662*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Section("PerPrimitiveProgram", "Shader program that sets the bounding box")
4663*35238bceSAndroid Build Coastguard Worker << *m_perPrimitiveProgram << tcu::TestLog::EndSection;
4664*35238bceSAndroid Build Coastguard Worker
4665*35238bceSAndroid Build Coastguard Worker if (!m_perPrimitiveProgram->isOk())
4666*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("shader build failed");
4667*35238bceSAndroid Build Coastguard Worker }
4668*35238bceSAndroid Build Coastguard Worker }
4669*35238bceSAndroid Build Coastguard Worker
renderTo(tcu::Surface & dst,bool useBBox)4670*35238bceSAndroid Build Coastguard Worker void ClearCase::renderTo(tcu::Surface &dst, bool useBBox)
4671*35238bceSAndroid Build Coastguard Worker {
4672*35238bceSAndroid Build Coastguard Worker const int numOps = 45;
4673*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 yellow(1.0f, 1.0f, 0.0f, 1.0f);
4674*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
4675*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 renderTargetSize(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
4676*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4677*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()));
4678*35238bceSAndroid Build Coastguard Worker glu::VertexArray vao(m_context.getRenderContext());
4679*35238bceSAndroid Build Coastguard Worker
4680*35238bceSAndroid Build Coastguard Worker // always do the initial clear
4681*35238bceSAndroid Build Coastguard Worker gl.disable(GL_SCISSOR_TEST);
4682*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, renderTargetSize.x(), renderTargetSize.y());
4683*35238bceSAndroid Build Coastguard Worker gl.clearColor(yellow.x(), yellow.y(), yellow.z(), yellow.w());
4684*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
4685*35238bceSAndroid Build Coastguard Worker gl.finish();
4686*35238bceSAndroid Build Coastguard Worker
4687*35238bceSAndroid Build Coastguard Worker // prepare draw
4688*35238bceSAndroid Build Coastguard Worker if (m_scissoredClear)
4689*35238bceSAndroid Build Coastguard Worker gl.enable(GL_SCISSOR_TEST);
4690*35238bceSAndroid Build Coastguard Worker
4691*35238bceSAndroid Build Coastguard Worker if (m_drawTriangles)
4692*35238bceSAndroid Build Coastguard Worker {
4693*35238bceSAndroid Build Coastguard Worker const uint32_t programHandle =
4694*35238bceSAndroid Build Coastguard Worker (m_useGlobalState || !useBBox) ? (m_basicProgram->getProgram()) : (m_perPrimitiveProgram->getProgram());
4695*35238bceSAndroid Build Coastguard Worker const int positionAttribLoc = gl.getAttribLocation(programHandle, "a_position");
4696*35238bceSAndroid Build Coastguard Worker
4697*35238bceSAndroid Build Coastguard Worker TCU_CHECK(positionAttribLoc != -1);
4698*35238bceSAndroid Build Coastguard Worker
4699*35238bceSAndroid Build Coastguard Worker gl.useProgram(programHandle);
4700*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
4701*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(positionAttribLoc);
4702*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(positionAttribLoc, 4, GL_FLOAT, GL_FALSE, (int)sizeof(tcu::Vec4), DE_NULL);
4703*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 3);
4704*35238bceSAndroid Build Coastguard Worker }
4705*35238bceSAndroid Build Coastguard Worker
4706*35238bceSAndroid Build Coastguard Worker // do random scissor/clearldraw operations
4707*35238bceSAndroid Build Coastguard Worker for (int opNdx = 0; opNdx < numOps; ++opNdx)
4708*35238bceSAndroid Build Coastguard Worker {
4709*35238bceSAndroid Build Coastguard Worker const int drawObjNdx = (m_drawTriangles) ? (rnd.getInt(0, (int)m_drawObjects.size() - 1)) : (0);
4710*35238bceSAndroid Build Coastguard Worker const int objectVertexStartNdx = (m_drawTriangles) ? (m_drawObjects[drawObjNdx].firstNdx) : (0);
4711*35238bceSAndroid Build Coastguard Worker const int objectVertexLength = (m_drawTriangles) ? (m_drawObjects[drawObjNdx].numVertices) : (0);
4712*35238bceSAndroid Build Coastguard Worker tcu::Vec4 bboxMin;
4713*35238bceSAndroid Build Coastguard Worker tcu::Vec4 bboxMax;
4714*35238bceSAndroid Build Coastguard Worker
4715*35238bceSAndroid Build Coastguard Worker if (m_drawTriangles)
4716*35238bceSAndroid Build Coastguard Worker {
4717*35238bceSAndroid Build Coastguard Worker bboxMin = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
4718*35238bceSAndroid Build Coastguard Worker bboxMax = tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f);
4719*35238bceSAndroid Build Coastguard Worker
4720*35238bceSAndroid Build Coastguard Worker // calc bbox
4721*35238bceSAndroid Build Coastguard Worker for (int vertexNdx = objectVertexStartNdx; vertexNdx < objectVertexStartNdx + objectVertexLength;
4722*35238bceSAndroid Build Coastguard Worker ++vertexNdx)
4723*35238bceSAndroid Build Coastguard Worker for (int componentNdx = 0; componentNdx < 4; ++componentNdx)
4724*35238bceSAndroid Build Coastguard Worker {
4725*35238bceSAndroid Build Coastguard Worker bboxMin[componentNdx] = de::min(bboxMin[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
4726*35238bceSAndroid Build Coastguard Worker bboxMax[componentNdx] = de::max(bboxMax[componentNdx], m_objectVertices[vertexNdx][componentNdx]);
4727*35238bceSAndroid Build Coastguard Worker }
4728*35238bceSAndroid Build Coastguard Worker }
4729*35238bceSAndroid Build Coastguard Worker else
4730*35238bceSAndroid Build Coastguard Worker {
4731*35238bceSAndroid Build Coastguard Worker // no geometry, just random something
4732*35238bceSAndroid Build Coastguard Worker bboxMin.x() = rnd.getFloat(-1.2f, 1.0f);
4733*35238bceSAndroid Build Coastguard Worker bboxMin.y() = rnd.getFloat(-1.2f, 1.0f);
4734*35238bceSAndroid Build Coastguard Worker bboxMin.z() = rnd.getFloat(-1.2f, 1.0f);
4735*35238bceSAndroid Build Coastguard Worker bboxMin.w() = 1.0f;
4736*35238bceSAndroid Build Coastguard Worker bboxMax.x() = bboxMin.x() + rnd.getFloat(0.2f, 1.0f);
4737*35238bceSAndroid Build Coastguard Worker bboxMax.y() = bboxMin.y() + rnd.getFloat(0.2f, 1.0f);
4738*35238bceSAndroid Build Coastguard Worker bboxMax.z() = bboxMin.z() + rnd.getFloat(0.2f, 1.0f);
4739*35238bceSAndroid Build Coastguard Worker bboxMax.w() = 1.0f;
4740*35238bceSAndroid Build Coastguard Worker }
4741*35238bceSAndroid Build Coastguard Worker
4742*35238bceSAndroid Build Coastguard Worker if (m_scissoredClear)
4743*35238bceSAndroid Build Coastguard Worker {
4744*35238bceSAndroid Build Coastguard Worker const int scissorX = (m_fullscreenScissor) ? (0) : rnd.getInt(0, renderTargetSize.x() - 1);
4745*35238bceSAndroid Build Coastguard Worker const int scissorY = (m_fullscreenScissor) ? (0) : rnd.getInt(0, renderTargetSize.y() - 1);
4746*35238bceSAndroid Build Coastguard Worker const int scissorW =
4747*35238bceSAndroid Build Coastguard Worker (m_fullscreenScissor) ? (renderTargetSize.x()) : rnd.getInt(0, renderTargetSize.x() - scissorX);
4748*35238bceSAndroid Build Coastguard Worker const int scissorH =
4749*35238bceSAndroid Build Coastguard Worker (m_fullscreenScissor) ? (renderTargetSize.y()) : rnd.getInt(0, renderTargetSize.y() - scissorY);
4750*35238bceSAndroid Build Coastguard Worker
4751*35238bceSAndroid Build Coastguard Worker gl.scissor(scissorX, scissorY, scissorW, scissorH);
4752*35238bceSAndroid Build Coastguard Worker }
4753*35238bceSAndroid Build Coastguard Worker
4754*35238bceSAndroid Build Coastguard Worker {
4755*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 color = tcu::mix(green, yellow, rnd.getFloat() * 0.4f); // greenish
4756*35238bceSAndroid Build Coastguard Worker gl.clearColor(color.x(), color.y(), color.z(), color.w());
4757*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
4758*35238bceSAndroid Build Coastguard Worker }
4759*35238bceSAndroid Build Coastguard Worker
4760*35238bceSAndroid Build Coastguard Worker if (useBBox)
4761*35238bceSAndroid Build Coastguard Worker {
4762*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_useGlobalState || m_drawTriangles); // !m_useGlobalState -> m_drawTriangles
4763*35238bceSAndroid Build Coastguard Worker
4764*35238bceSAndroid Build Coastguard Worker auto boundingBoxFunc = getBoundingBoxFunction(m_context);
4765*35238bceSAndroid Build Coastguard Worker if (m_useGlobalState)
4766*35238bceSAndroid Build Coastguard Worker boundingBoxFunc(bboxMin.x(), bboxMin.y(), bboxMin.z(), bboxMin.w(), bboxMax.x(), bboxMax.y(),
4767*35238bceSAndroid Build Coastguard Worker bboxMax.z(), bboxMax.w());
4768*35238bceSAndroid Build Coastguard Worker }
4769*35238bceSAndroid Build Coastguard Worker
4770*35238bceSAndroid Build Coastguard Worker if (m_drawTriangles)
4771*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, objectVertexStartNdx, objectVertexLength);
4772*35238bceSAndroid Build Coastguard Worker }
4773*35238bceSAndroid Build Coastguard Worker
4774*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post draw");
4775*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
4776*35238bceSAndroid Build Coastguard Worker }
4777*35238bceSAndroid Build Coastguard Worker
verifyImagesEqual(const tcu::PixelBufferAccess & withoutBBox,const tcu::PixelBufferAccess & withBBox)4778*35238bceSAndroid Build Coastguard Worker bool ClearCase::verifyImagesEqual(const tcu::PixelBufferAccess &withoutBBox, const tcu::PixelBufferAccess &withBBox)
4779*35238bceSAndroid Build Coastguard Worker {
4780*35238bceSAndroid Build Coastguard Worker DE_ASSERT(withoutBBox.getWidth() == withBBox.getWidth());
4781*35238bceSAndroid Build Coastguard Worker DE_ASSERT(withoutBBox.getHeight() == withBBox.getHeight());
4782*35238bceSAndroid Build Coastguard Worker
4783*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(withoutBBox.getWidth(), withoutBBox.getHeight());
4784*35238bceSAndroid Build Coastguard Worker bool anyError = false;
4785*35238bceSAndroid Build Coastguard Worker
4786*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
4787*35238bceSAndroid Build Coastguard Worker
4788*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < withoutBBox.getHeight(); ++y)
4789*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < withoutBBox.getWidth(); ++x)
4790*35238bceSAndroid Build Coastguard Worker {
4791*35238bceSAndroid Build Coastguard Worker if (withoutBBox.getPixelInt(x, y) != withBBox.getPixelInt(x, y))
4792*35238bceSAndroid Build Coastguard Worker {
4793*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
4794*35238bceSAndroid Build Coastguard Worker anyError = true;
4795*35238bceSAndroid Build Coastguard Worker }
4796*35238bceSAndroid Build Coastguard Worker }
4797*35238bceSAndroid Build Coastguard Worker
4798*35238bceSAndroid Build Coastguard Worker if (anyError)
4799*35238bceSAndroid Build Coastguard Worker {
4800*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image comparison failed." << tcu::TestLog::EndMessage
4801*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image comparison")
4802*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("WithoutBBox", "Result with bounding box not set", withoutBBox)
4803*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("WithBBox", "Result with bounding box set", withBBox)
4804*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
4805*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
4806*35238bceSAndroid Build Coastguard Worker }
4807*35238bceSAndroid Build Coastguard Worker
4808*35238bceSAndroid Build Coastguard Worker return !anyError;
4809*35238bceSAndroid Build Coastguard Worker }
4810*35238bceSAndroid Build Coastguard Worker
verifyImageResultValid(const tcu::PixelBufferAccess & result)4811*35238bceSAndroid Build Coastguard Worker bool ClearCase::verifyImageResultValid(const tcu::PixelBufferAccess &result)
4812*35238bceSAndroid Build Coastguard Worker {
4813*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(result.getWidth(), result.getHeight());
4814*35238bceSAndroid Build Coastguard Worker bool anyError = false;
4815*35238bceSAndroid Build Coastguard Worker
4816*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
4817*35238bceSAndroid Build Coastguard Worker
4818*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < result.getHeight(); ++y)
4819*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < result.getWidth(); ++x)
4820*35238bceSAndroid Build Coastguard Worker {
4821*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 pixel = result.getPixelInt(x, y);
4822*35238bceSAndroid Build Coastguard Worker
4823*35238bceSAndroid Build Coastguard Worker // allow green, yellow and any shade between
4824*35238bceSAndroid Build Coastguard Worker if (pixel[1] != 255 || pixel[2] != 0)
4825*35238bceSAndroid Build Coastguard Worker {
4826*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
4827*35238bceSAndroid Build Coastguard Worker anyError = true;
4828*35238bceSAndroid Build Coastguard Worker }
4829*35238bceSAndroid Build Coastguard Worker }
4830*35238bceSAndroid Build Coastguard Worker
4831*35238bceSAndroid Build Coastguard Worker if (anyError)
4832*35238bceSAndroid Build Coastguard Worker {
4833*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
4834*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
4835*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ResultImage", "Result image", result)
4836*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
4837*35238bceSAndroid Build Coastguard Worker }
4838*35238bceSAndroid Build Coastguard Worker
4839*35238bceSAndroid Build Coastguard Worker return !anyError;
4840*35238bceSAndroid Build Coastguard Worker }
4841*35238bceSAndroid Build Coastguard Worker
4842*35238bceSAndroid Build Coastguard Worker static const char *const s_yellowishPosOnlyVertexSource =
4843*35238bceSAndroid Build Coastguard Worker "${GLSL_VERSION_DECL}\n"
4844*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
4845*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_vertex_color;\n"
4846*35238bceSAndroid Build Coastguard Worker "void main()\n"
4847*35238bceSAndroid Build Coastguard Worker "{\n"
4848*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
4849*35238bceSAndroid Build Coastguard Worker " // yellowish shade\n"
4850*35238bceSAndroid Build Coastguard Worker " highp float redComponent = 0.5 + float(gl_VertexID % 5) / 8.0;\n"
4851*35238bceSAndroid Build Coastguard Worker " v_vertex_color = vec4(redComponent, 1.0, 0.0, 1.0);\n"
4852*35238bceSAndroid Build Coastguard Worker "}\n";
4853*35238bceSAndroid Build Coastguard Worker
4854*35238bceSAndroid Build Coastguard Worker static const char *const s_basicColorFragmentSource = "${GLSL_VERSION_DECL}\n"
4855*35238bceSAndroid Build Coastguard Worker "in mediump vec4 v_color;\n"
4856*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
4857*35238bceSAndroid Build Coastguard Worker "void main()\n"
4858*35238bceSAndroid Build Coastguard Worker "{\n"
4859*35238bceSAndroid Build Coastguard Worker " o_color = v_color;\n"
4860*35238bceSAndroid Build Coastguard Worker "}\n";
4861*35238bceSAndroid Build Coastguard Worker
4862*35238bceSAndroid Build Coastguard Worker static const char *const s_basicColorTessEvalSource = "${GLSL_VERSION_DECL}\n"
4863*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
4864*35238bceSAndroid Build Coastguard Worker "${GPU_SHADER5_REQUIRE}\n"
4865*35238bceSAndroid Build Coastguard Worker "layout(triangles) in;\n"
4866*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_tess_eval_color[];\n"
4867*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_color;\n"
4868*35238bceSAndroid Build Coastguard Worker "precise gl_Position;\n"
4869*35238bceSAndroid Build Coastguard Worker "void main()\n"
4870*35238bceSAndroid Build Coastguard Worker "{\n"
4871*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n"
4872*35238bceSAndroid Build Coastguard Worker " + gl_TessCoord.y * gl_in[1].gl_Position\n"
4873*35238bceSAndroid Build Coastguard Worker " + gl_TessCoord.z * gl_in[2].gl_Position;\n"
4874*35238bceSAndroid Build Coastguard Worker " v_color = gl_TessCoord.x * v_tess_eval_color[0]\n"
4875*35238bceSAndroid Build Coastguard Worker " + gl_TessCoord.y * v_tess_eval_color[1]\n"
4876*35238bceSAndroid Build Coastguard Worker " + gl_TessCoord.z * v_tess_eval_color[2];\n"
4877*35238bceSAndroid Build Coastguard Worker "}\n";
4878*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const4879*35238bceSAndroid Build Coastguard Worker std::string ClearCase::genVertexSource(void) const
4880*35238bceSAndroid Build Coastguard Worker {
4881*35238bceSAndroid Build Coastguard Worker return s_yellowishPosOnlyVertexSource;
4882*35238bceSAndroid Build Coastguard Worker }
4883*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const4884*35238bceSAndroid Build Coastguard Worker std::string ClearCase::genFragmentSource(void) const
4885*35238bceSAndroid Build Coastguard Worker {
4886*35238bceSAndroid Build Coastguard Worker return s_basicColorFragmentSource;
4887*35238bceSAndroid Build Coastguard Worker }
4888*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(bool setBBox) const4889*35238bceSAndroid Build Coastguard Worker std::string ClearCase::genTessellationControlSource(bool setBBox) const
4890*35238bceSAndroid Build Coastguard Worker {
4891*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
4892*35238bceSAndroid Build Coastguard Worker
4893*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
4894*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
4895*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n";
4896*35238bceSAndroid Build Coastguard Worker
4897*35238bceSAndroid Build Coastguard Worker if (setBBox)
4898*35238bceSAndroid Build Coastguard Worker buf << "${PRIMITIVE_BOUNDING_BOX_REQUIRE}\n";
4899*35238bceSAndroid Build Coastguard Worker
4900*35238bceSAndroid Build Coastguard Worker buf << "layout(vertices=3) out;\n"
4901*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_vertex_color[];\n"
4902*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_tess_eval_color[];\n"
4903*35238bceSAndroid Build Coastguard Worker "void main()\n"
4904*35238bceSAndroid Build Coastguard Worker "{\n"
4905*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
4906*35238bceSAndroid Build Coastguard Worker " v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
4907*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 2.8;\n"
4908*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 2.8;\n"
4909*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 2.8;\n"
4910*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 2.8;\n";
4911*35238bceSAndroid Build Coastguard Worker
4912*35238bceSAndroid Build Coastguard Worker if (setBBox)
4913*35238bceSAndroid Build Coastguard Worker {
4914*35238bceSAndroid Build Coastguard Worker buf << "\n"
4915*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[0] = min(min(gl_in[0].gl_Position,\n"
4916*35238bceSAndroid Build Coastguard Worker " gl_in[1].gl_Position),\n"
4917*35238bceSAndroid Build Coastguard Worker " gl_in[2].gl_Position);\n"
4918*35238bceSAndroid Build Coastguard Worker " ${PRIM_GL_BOUNDING_BOX}[1] = max(max(gl_in[0].gl_Position,\n"
4919*35238bceSAndroid Build Coastguard Worker " gl_in[1].gl_Position),\n"
4920*35238bceSAndroid Build Coastguard Worker " gl_in[2].gl_Position);\n";
4921*35238bceSAndroid Build Coastguard Worker }
4922*35238bceSAndroid Build Coastguard Worker
4923*35238bceSAndroid Build Coastguard Worker buf << "}\n";
4924*35238bceSAndroid Build Coastguard Worker return buf.str();
4925*35238bceSAndroid Build Coastguard Worker }
4926*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const4927*35238bceSAndroid Build Coastguard Worker std::string ClearCase::genTessellationEvaluationSource(void) const
4928*35238bceSAndroid Build Coastguard Worker {
4929*35238bceSAndroid Build Coastguard Worker return s_basicColorTessEvalSource;
4930*35238bceSAndroid Build Coastguard Worker }
4931*35238bceSAndroid Build Coastguard Worker
4932*35238bceSAndroid Build Coastguard Worker class ViewportCallOrderCase : public TestCase
4933*35238bceSAndroid Build Coastguard Worker {
4934*35238bceSAndroid Build Coastguard Worker public:
4935*35238bceSAndroid Build Coastguard Worker enum CallOrder
4936*35238bceSAndroid Build Coastguard Worker {
4937*35238bceSAndroid Build Coastguard Worker VIEWPORT_FIRST = 0,
4938*35238bceSAndroid Build Coastguard Worker BBOX_FIRST,
4939*35238bceSAndroid Build Coastguard Worker
4940*35238bceSAndroid Build Coastguard Worker ORDER_LAST
4941*35238bceSAndroid Build Coastguard Worker };
4942*35238bceSAndroid Build Coastguard Worker
4943*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase(Context &context, const char *name, const char *description, CallOrder callOrder);
4944*35238bceSAndroid Build Coastguard Worker ~ViewportCallOrderCase(void);
4945*35238bceSAndroid Build Coastguard Worker
4946*35238bceSAndroid Build Coastguard Worker private:
4947*35238bceSAndroid Build Coastguard Worker void init(void);
4948*35238bceSAndroid Build Coastguard Worker void deinit(void);
4949*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
4950*35238bceSAndroid Build Coastguard Worker
4951*35238bceSAndroid Build Coastguard Worker void genVbo(void);
4952*35238bceSAndroid Build Coastguard Worker void genProgram(void);
4953*35238bceSAndroid Build Coastguard Worker bool verifyImage(const tcu::PixelBufferAccess &result);
4954*35238bceSAndroid Build Coastguard Worker
4955*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
4956*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
4957*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
4958*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
4959*35238bceSAndroid Build Coastguard Worker
4960*35238bceSAndroid Build Coastguard Worker const CallOrder m_callOrder;
4961*35238bceSAndroid Build Coastguard Worker
4962*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Buffer> m_vbo;
4963*35238bceSAndroid Build Coastguard Worker glw::GLuint m_vao;
4964*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::ShaderProgram> m_program;
4965*35238bceSAndroid Build Coastguard Worker int m_numVertices;
4966*35238bceSAndroid Build Coastguard Worker };
4967*35238bceSAndroid Build Coastguard Worker
ViewportCallOrderCase(Context & context,const char * name,const char * description,CallOrder callOrder)4968*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase::ViewportCallOrderCase(Context &context, const char *name, const char *description,
4969*35238bceSAndroid Build Coastguard Worker CallOrder callOrder)
4970*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
4971*35238bceSAndroid Build Coastguard Worker , m_callOrder(callOrder)
4972*35238bceSAndroid Build Coastguard Worker , m_vao(0)
4973*35238bceSAndroid Build Coastguard Worker , m_numVertices(-1)
4974*35238bceSAndroid Build Coastguard Worker {
4975*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_callOrder < ORDER_LAST);
4976*35238bceSAndroid Build Coastguard Worker }
4977*35238bceSAndroid Build Coastguard Worker
~ViewportCallOrderCase(void)4978*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase::~ViewportCallOrderCase(void)
4979*35238bceSAndroid Build Coastguard Worker {
4980*35238bceSAndroid Build Coastguard Worker deinit();
4981*35238bceSAndroid Build Coastguard Worker }
4982*35238bceSAndroid Build Coastguard Worker
init(void)4983*35238bceSAndroid Build Coastguard Worker void ViewportCallOrderCase::init(void)
4984*35238bceSAndroid Build Coastguard Worker {
4985*35238bceSAndroid Build Coastguard Worker const bool hasES32OrGL45 = supportsES32OrGL45(m_context);
4986*35238bceSAndroid Build Coastguard Worker
4987*35238bceSAndroid Build Coastguard Worker if (!boundingBoxSupported(m_context))
4988*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
4989*35238bceSAndroid Build Coastguard Worker
4990*35238bceSAndroid Build Coastguard Worker if (!hasES32OrGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
4991*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
4992*35238bceSAndroid Build Coastguard Worker
4993*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
4994*35238bceSAndroid Build Coastguard Worker << "Testing call order of state setting functions have no effect on the rendering.\n"
4995*35238bceSAndroid Build Coastguard Worker << "Setting viewport and bounding box in the following order:\n"
4996*35238bceSAndroid Build Coastguard Worker << ((m_callOrder == VIEWPORT_FIRST) ?
4997*35238bceSAndroid Build Coastguard Worker ("\tFirst viewport with glViewport function.\n") :
4998*35238bceSAndroid Build Coastguard Worker ("\tFirst bounding box with glPrimitiveBoundingBoxEXT function.\n"))
4999*35238bceSAndroid Build Coastguard Worker << ((m_callOrder == VIEWPORT_FIRST) ?
5000*35238bceSAndroid Build Coastguard Worker ("\tThen bounding box with glPrimitiveBoundingBoxEXT function.\n") :
5001*35238bceSAndroid Build Coastguard Worker ("\tThen viewport with glViewport function.\n"))
5002*35238bceSAndroid Build Coastguard Worker << "Verifying rendering result." << tcu::TestLog::EndMessage;
5003*35238bceSAndroid Build Coastguard Worker
5004*35238bceSAndroid Build Coastguard Worker // resources
5005*35238bceSAndroid Build Coastguard Worker genVbo();
5006*35238bceSAndroid Build Coastguard Worker genProgram();
5007*35238bceSAndroid Build Coastguard Worker }
5008*35238bceSAndroid Build Coastguard Worker
deinit(void)5009*35238bceSAndroid Build Coastguard Worker void ViewportCallOrderCase::deinit(void)
5010*35238bceSAndroid Build Coastguard Worker {
5011*35238bceSAndroid Build Coastguard Worker m_vbo.clear();
5012*35238bceSAndroid Build Coastguard Worker m_program.clear();
5013*35238bceSAndroid Build Coastguard Worker
5014*35238bceSAndroid Build Coastguard Worker if (m_vao)
5015*35238bceSAndroid Build Coastguard Worker {
5016*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
5017*35238bceSAndroid Build Coastguard Worker m_vao = 0;
5018*35238bceSAndroid Build Coastguard Worker }
5019*35238bceSAndroid Build Coastguard Worker }
5020*35238bceSAndroid Build Coastguard Worker
iterate(void)5021*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase::IterateResult ViewportCallOrderCase::iterate(void)
5022*35238bceSAndroid Build Coastguard Worker {
5023*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5024*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize =
5025*35238bceSAndroid Build Coastguard Worker tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
5026*35238bceSAndroid Build Coastguard Worker const glw::GLint posLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
5027*35238bceSAndroid Build Coastguard Worker tcu::Surface resultSurface(viewportSize.x(), viewportSize.y());
5028*35238bceSAndroid Build Coastguard Worker
5029*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5030*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
5031*35238bceSAndroid Build Coastguard Worker
5032*35238bceSAndroid Build Coastguard Worker // set state
5033*35238bceSAndroid Build Coastguard Worker for (int orderNdx = 0; orderNdx < 2; ++orderNdx)
5034*35238bceSAndroid Build Coastguard Worker {
5035*35238bceSAndroid Build Coastguard Worker if ((orderNdx == 0 && m_callOrder == VIEWPORT_FIRST) || (orderNdx == 1 && m_callOrder == BBOX_FIRST))
5036*35238bceSAndroid Build Coastguard Worker {
5037*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
5038*35238bceSAndroid Build Coastguard Worker << "Setting viewport to cover the left half of the render target.\n"
5039*35238bceSAndroid Build Coastguard Worker << "\t(0, 0, " << (viewportSize.x() / 2) << ", " << viewportSize.y() << ")"
5040*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
5041*35238bceSAndroid Build Coastguard Worker
5042*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, viewportSize.x() / 2, viewportSize.y());
5043*35238bceSAndroid Build Coastguard Worker }
5044*35238bceSAndroid Build Coastguard Worker else
5045*35238bceSAndroid Build Coastguard Worker {
5046*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
5047*35238bceSAndroid Build Coastguard Worker << "Setting bounding box to cover the right half of the clip space.\n"
5048*35238bceSAndroid Build Coastguard Worker << "\t(0.0, -1.0, -1.0, 1.0) .. (1.0, 1.0, 1.0f, 1.0)" << tcu::TestLog::EndMessage;
5049*35238bceSAndroid Build Coastguard Worker
5050*35238bceSAndroid Build Coastguard Worker auto boundingBoxFunc = getBoundingBoxFunction(m_context);
5051*35238bceSAndroid Build Coastguard Worker
5052*35238bceSAndroid Build Coastguard Worker boundingBoxFunc(0.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
5053*35238bceSAndroid Build Coastguard Worker }
5054*35238bceSAndroid Build Coastguard Worker }
5055*35238bceSAndroid Build Coastguard Worker
5056*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering mesh covering the right half of the clip space."
5057*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
5058*35238bceSAndroid Build Coastguard Worker
5059*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
5060*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, sizeof(float[4]), (const float *)DE_NULL);
5061*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
5062*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
5063*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 3);
5064*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, m_numVertices);
5065*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw");
5066*35238bceSAndroid Build Coastguard Worker
5067*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying image" << tcu::TestLog::EndMessage;
5068*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
5069*35238bceSAndroid Build Coastguard Worker
5070*35238bceSAndroid Build Coastguard Worker if (!verifyImage(resultSurface.getAccess()))
5071*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
5072*35238bceSAndroid Build Coastguard Worker else
5073*35238bceSAndroid Build Coastguard Worker {
5074*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result ok." << tcu::TestLog::EndMessage
5075*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
5076*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Result", resultSurface.getAccess())
5077*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
5078*35238bceSAndroid Build Coastguard Worker
5079*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5080*35238bceSAndroid Build Coastguard Worker }
5081*35238bceSAndroid Build Coastguard Worker return STOP;
5082*35238bceSAndroid Build Coastguard Worker }
5083*35238bceSAndroid Build Coastguard Worker
genVbo(void)5084*35238bceSAndroid Build Coastguard Worker void ViewportCallOrderCase::genVbo(void)
5085*35238bceSAndroid Build Coastguard Worker {
5086*35238bceSAndroid Build Coastguard Worker const int gridSize = 6;
5087*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5088*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> data(gridSize * gridSize * 2 * 3);
5089*35238bceSAndroid Build Coastguard Worker std::vector<int> cellOrder(gridSize * gridSize * 2);
5090*35238bceSAndroid Build Coastguard Worker de::Random rnd(0x55443322);
5091*35238bceSAndroid Build Coastguard Worker
5092*35238bceSAndroid Build Coastguard Worker // generate grid with triangles in random order
5093*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
5094*35238bceSAndroid Build Coastguard Worker cellOrder[ndx] = ndx;
5095*35238bceSAndroid Build Coastguard Worker rnd.shuffle(cellOrder.begin(), cellOrder.end());
5096*35238bceSAndroid Build Coastguard Worker
5097*35238bceSAndroid Build Coastguard Worker // generate grid filling the right half of the clip space: (x: 0.0, y: -1.0) .. (x: 1.0, y: 1.0)
5098*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)cellOrder.size(); ++ndx)
5099*35238bceSAndroid Build Coastguard Worker {
5100*35238bceSAndroid Build Coastguard Worker const int cellNdx = cellOrder[ndx];
5101*35238bceSAndroid Build Coastguard Worker const bool cellSide = ((cellNdx % 2) == 0);
5102*35238bceSAndroid Build Coastguard Worker const int cellX = (cellNdx / 2) % gridSize;
5103*35238bceSAndroid Build Coastguard Worker const int cellY = (cellNdx / 2) / gridSize;
5104*35238bceSAndroid Build Coastguard Worker
5105*35238bceSAndroid Build Coastguard Worker if (cellSide)
5106*35238bceSAndroid Build Coastguard Worker {
5107*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 0] = tcu::Vec4(float(cellX + 0) / float(gridSize),
5108*35238bceSAndroid Build Coastguard Worker (float(cellY + 0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5109*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 1] = tcu::Vec4(float(cellX + 1) / float(gridSize),
5110*35238bceSAndroid Build Coastguard Worker (float(cellY + 1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5111*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 2] = tcu::Vec4(float(cellX + 0) / float(gridSize),
5112*35238bceSAndroid Build Coastguard Worker (float(cellY + 1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5113*35238bceSAndroid Build Coastguard Worker }
5114*35238bceSAndroid Build Coastguard Worker else
5115*35238bceSAndroid Build Coastguard Worker {
5116*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 0] = tcu::Vec4(float(cellX + 0) / float(gridSize),
5117*35238bceSAndroid Build Coastguard Worker (float(cellY + 0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5118*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 1] = tcu::Vec4(float(cellX + 1) / float(gridSize),
5119*35238bceSAndroid Build Coastguard Worker (float(cellY + 0) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5120*35238bceSAndroid Build Coastguard Worker data[ndx * 3 + 2] = tcu::Vec4(float(cellX + 1) / float(gridSize),
5121*35238bceSAndroid Build Coastguard Worker (float(cellY + 1) / float(gridSize)) * 2.0f - 1.0f, 0.0f, 1.0f);
5122*35238bceSAndroid Build Coastguard Worker }
5123*35238bceSAndroid Build Coastguard Worker }
5124*35238bceSAndroid Build Coastguard Worker
5125*35238bceSAndroid Build Coastguard Worker // Generate VAO for desktop OpenGL
5126*35238bceSAndroid Build Coastguard Worker if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
5127*35238bceSAndroid Build Coastguard Worker {
5128*35238bceSAndroid Build Coastguard Worker gl.genVertexArrays(1, &m_vao);
5129*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(m_vao);
5130*35238bceSAndroid Build Coastguard Worker }
5131*35238bceSAndroid Build Coastguard Worker
5132*35238bceSAndroid Build Coastguard Worker m_vbo = de::MovePtr<glu::Buffer>(new glu::Buffer(m_context.getRenderContext()));
5133*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, **m_vbo);
5134*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (int)(data.size() * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
5135*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "create vbo");
5136*35238bceSAndroid Build Coastguard Worker
5137*35238bceSAndroid Build Coastguard Worker m_numVertices = (int)data.size();
5138*35238bceSAndroid Build Coastguard Worker }
5139*35238bceSAndroid Build Coastguard Worker
genProgram(void)5140*35238bceSAndroid Build Coastguard Worker void ViewportCallOrderCase::genProgram(void)
5141*35238bceSAndroid Build Coastguard Worker {
5142*35238bceSAndroid Build Coastguard Worker m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(
5143*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
5144*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(specializeShader(m_context, genVertexSource().c_str()))
5145*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(specializeShader(m_context, genFragmentSource().c_str()))
5146*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(
5147*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationControlSource().c_str()))
5148*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
5149*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, genTessellationEvaluationSource().c_str()))));
5150*35238bceSAndroid Build Coastguard Worker
5151*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Section("Program", "Shader program") << *m_program << tcu::TestLog::EndSection;
5152*35238bceSAndroid Build Coastguard Worker
5153*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
5154*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("shader build failed");
5155*35238bceSAndroid Build Coastguard Worker }
5156*35238bceSAndroid Build Coastguard Worker
verifyImage(const tcu::PixelBufferAccess & result)5157*35238bceSAndroid Build Coastguard Worker bool ViewportCallOrderCase::verifyImage(const tcu::PixelBufferAccess &result)
5158*35238bceSAndroid Build Coastguard Worker {
5159*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 insideBorder(deCeilFloatToInt32(0.25f * (float)result.getWidth()) + 1,
5160*35238bceSAndroid Build Coastguard Worker deFloorFloatToInt32(0.5f * (float)result.getWidth()) - 1);
5161*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 outsideBorder(deFloorFloatToInt32(0.25f * (float)result.getWidth()) - 1,
5162*35238bceSAndroid Build Coastguard Worker deCeilFloatToInt32(0.5f * (float)result.getWidth()) + 1);
5163*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(result.getWidth(), result.getHeight());
5164*35238bceSAndroid Build Coastguard Worker bool anyError = false;
5165*35238bceSAndroid Build Coastguard Worker
5166*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
5167*35238bceSAndroid Build Coastguard Worker
5168*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < result.getHeight(); ++y)
5169*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < result.getWidth(); ++x)
5170*35238bceSAndroid Build Coastguard Worker {
5171*35238bceSAndroid Build Coastguard Worker /*
5172*35238bceSAndroid Build Coastguard Worker Test stores the xmin,xmax values in the insideBorder and outsideBorder vectors.
5173*35238bceSAndroid Build Coastguard Worker Thus the "y" in the vector is xmax.
5174*35238bceSAndroid Build Coastguard Worker */
5175*35238bceSAndroid Build Coastguard Worker
5176*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 pixel = result.getPixelInt(x, y);
5177*35238bceSAndroid Build Coastguard Worker const bool insideMeshArea = x >= insideBorder.x() && x <= insideBorder.y();
5178*35238bceSAndroid Build Coastguard Worker const bool outsideMeshArea = x <= outsideBorder.x() && x >= outsideBorder.y();
5179*35238bceSAndroid Build Coastguard Worker
5180*35238bceSAndroid Build Coastguard Worker // inside mesh, allow green, yellow and any shade between
5181*35238bceSAndroid Build Coastguard Worker // outside mesh, allow background (black) only
5182*35238bceSAndroid Build Coastguard Worker // in the border area, allow anything
5183*35238bceSAndroid Build Coastguard Worker if ((insideMeshArea && (pixel[1] != 255 || pixel[2] != 0)) ||
5184*35238bceSAndroid Build Coastguard Worker (outsideMeshArea && (pixel[0] != 0 || pixel[1] != 0 || pixel[2] != 0)))
5185*35238bceSAndroid Build Coastguard Worker {
5186*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
5187*35238bceSAndroid Build Coastguard Worker anyError = true;
5188*35238bceSAndroid Build Coastguard Worker }
5189*35238bceSAndroid Build Coastguard Worker }
5190*35238bceSAndroid Build Coastguard Worker
5191*35238bceSAndroid Build Coastguard Worker if (anyError)
5192*35238bceSAndroid Build Coastguard Worker {
5193*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage
5194*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("Images", "Image verification")
5195*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ResultImage", "Result image", result)
5196*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
5197*35238bceSAndroid Build Coastguard Worker }
5198*35238bceSAndroid Build Coastguard Worker
5199*35238bceSAndroid Build Coastguard Worker return !anyError;
5200*35238bceSAndroid Build Coastguard Worker }
5201*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const5202*35238bceSAndroid Build Coastguard Worker std::string ViewportCallOrderCase::genVertexSource(void) const
5203*35238bceSAndroid Build Coastguard Worker {
5204*35238bceSAndroid Build Coastguard Worker return s_yellowishPosOnlyVertexSource;
5205*35238bceSAndroid Build Coastguard Worker }
5206*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const5207*35238bceSAndroid Build Coastguard Worker std::string ViewportCallOrderCase::genFragmentSource(void) const
5208*35238bceSAndroid Build Coastguard Worker {
5209*35238bceSAndroid Build Coastguard Worker return s_basicColorFragmentSource;
5210*35238bceSAndroid Build Coastguard Worker }
5211*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const5212*35238bceSAndroid Build Coastguard Worker std::string ViewportCallOrderCase::genTessellationControlSource(void) const
5213*35238bceSAndroid Build Coastguard Worker {
5214*35238bceSAndroid Build Coastguard Worker return "${GLSL_VERSION_DECL}\n"
5215*35238bceSAndroid Build Coastguard Worker "${ARB_ES32_COMPATIBILITY_REQUIRE}\n"
5216*35238bceSAndroid Build Coastguard Worker "${TESSELLATION_SHADER_REQUIRE}\n"
5217*35238bceSAndroid Build Coastguard Worker "layout(vertices=3) out;\n"
5218*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_vertex_color[];\n"
5219*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_tess_eval_color[];\n"
5220*35238bceSAndroid Build Coastguard Worker "void main()\n"
5221*35238bceSAndroid Build Coastguard Worker "{\n"
5222*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
5223*35238bceSAndroid Build Coastguard Worker " v_tess_eval_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
5224*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 2.8;\n"
5225*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 2.8;\n"
5226*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 2.8;\n"
5227*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 2.8;\n"
5228*35238bceSAndroid Build Coastguard Worker "}\n";
5229*35238bceSAndroid Build Coastguard Worker }
5230*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const5231*35238bceSAndroid Build Coastguard Worker std::string ViewportCallOrderCase::genTessellationEvaluationSource(void) const
5232*35238bceSAndroid Build Coastguard Worker {
5233*35238bceSAndroid Build Coastguard Worker return s_basicColorTessEvalSource;
5234*35238bceSAndroid Build Coastguard Worker }
5235*35238bceSAndroid Build Coastguard Worker
5236*35238bceSAndroid Build Coastguard Worker } // namespace
5237*35238bceSAndroid Build Coastguard Worker
PrimitiveBoundingBoxTests(Context & context)5238*35238bceSAndroid Build Coastguard Worker PrimitiveBoundingBoxTests::PrimitiveBoundingBoxTests(Context &context)
5239*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "primitive_bounding_box", "Tests for EXT_primitive_bounding_box")
5240*35238bceSAndroid Build Coastguard Worker {
5241*35238bceSAndroid Build Coastguard Worker }
5242*35238bceSAndroid Build Coastguard Worker
~PrimitiveBoundingBoxTests(void)5243*35238bceSAndroid Build Coastguard Worker PrimitiveBoundingBoxTests::~PrimitiveBoundingBoxTests(void)
5244*35238bceSAndroid Build Coastguard Worker {
5245*35238bceSAndroid Build Coastguard Worker }
5246*35238bceSAndroid Build Coastguard Worker
init(void)5247*35238bceSAndroid Build Coastguard Worker void PrimitiveBoundingBoxTests::init(void)
5248*35238bceSAndroid Build Coastguard Worker {
5249*35238bceSAndroid Build Coastguard Worker static const struct
5250*35238bceSAndroid Build Coastguard Worker {
5251*35238bceSAndroid Build Coastguard Worker const char *name;
5252*35238bceSAndroid Build Coastguard Worker const char *description;
5253*35238bceSAndroid Build Coastguard Worker uint32_t methodFlags;
5254*35238bceSAndroid Build Coastguard Worker } stateSetMethods[] = {
5255*35238bceSAndroid Build Coastguard Worker {
5256*35238bceSAndroid Build Coastguard Worker "global_state",
5257*35238bceSAndroid Build Coastguard Worker "Set bounding box using PRIMITIVE_BOUNDING_BOX_EXT state",
5258*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_SET_BBOX_STATE,
5259*35238bceSAndroid Build Coastguard Worker },
5260*35238bceSAndroid Build Coastguard Worker {
5261*35238bceSAndroid Build Coastguard Worker "tessellation_set_per_draw",
5262*35238bceSAndroid Build Coastguard Worker "Set bounding box using gl_BoundingBoxEXT, use same value for all primitives",
5263*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_SET_BBOX_OUTPUT,
5264*35238bceSAndroid Build Coastguard Worker },
5265*35238bceSAndroid Build Coastguard Worker {
5266*35238bceSAndroid Build Coastguard Worker "tessellation_set_per_primitive",
5267*35238bceSAndroid Build Coastguard Worker "Set bounding box using gl_BoundingBoxEXT, use per-primitive bounding box",
5268*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_SET_BBOX_OUTPUT | BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX,
5269*35238bceSAndroid Build Coastguard Worker },
5270*35238bceSAndroid Build Coastguard Worker };
5271*35238bceSAndroid Build Coastguard Worker static const struct
5272*35238bceSAndroid Build Coastguard Worker {
5273*35238bceSAndroid Build Coastguard Worker const char *name;
5274*35238bceSAndroid Build Coastguard Worker const char *description;
5275*35238bceSAndroid Build Coastguard Worker uint32_t stageFlags;
5276*35238bceSAndroid Build Coastguard Worker } pipelineConfigs[] = {
5277*35238bceSAndroid Build Coastguard Worker {"vertex_fragment", "Render with vertex-fragment program", 0u},
5278*35238bceSAndroid Build Coastguard Worker {"vertex_tessellation_fragment", "Render with vertex-tessellation{ctrl,eval}-fragment program",
5279*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_TESSELLATION},
5280*35238bceSAndroid Build Coastguard Worker {"vertex_geometry_fragment", "Render with vertex-tessellation{ctrl,eval}-geometry-fragment program",
5281*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_GEOMETRY},
5282*35238bceSAndroid Build Coastguard Worker {"vertex_tessellation_geometry_fragment", "Render with vertex-geometry-fragment program",
5283*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_TESSELLATION | BBoxRenderCase::FLAG_GEOMETRY},
5284*35238bceSAndroid Build Coastguard Worker };
5285*35238bceSAndroid Build Coastguard Worker static const struct
5286*35238bceSAndroid Build Coastguard Worker {
5287*35238bceSAndroid Build Coastguard Worker const char *name;
5288*35238bceSAndroid Build Coastguard Worker const char *description;
5289*35238bceSAndroid Build Coastguard Worker uint32_t flags;
5290*35238bceSAndroid Build Coastguard Worker uint32_t invalidFlags;
5291*35238bceSAndroid Build Coastguard Worker uint32_t requiredFlags;
5292*35238bceSAndroid Build Coastguard Worker } usageConfigs[] = {
5293*35238bceSAndroid Build Coastguard Worker {"default_framebuffer_bbox_equal", "Render to default framebuffer, set tight bounding box",
5294*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
5295*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5296*35238bceSAndroid Build Coastguard Worker {"default_framebuffer_bbox_larger", "Render to default framebuffer, set padded bounding box",
5297*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
5298*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5299*35238bceSAndroid Build Coastguard Worker {"default_framebuffer_bbox_smaller", "Render to default framebuffer, set too small bounding box",
5300*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
5301*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5302*35238bceSAndroid Build Coastguard Worker {"fbo_bbox_equal", "Render to texture, set tight bounding box",
5303*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL,
5304*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5305*35238bceSAndroid Build Coastguard Worker {"fbo_bbox_larger", "Render to texture, set padded bounding box",
5306*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_LARGER,
5307*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5308*35238bceSAndroid Build Coastguard Worker {"fbo_bbox_smaller", "Render to texture, set too small bounding box",
5309*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_SMALLER,
5310*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX, 0},
5311*35238bceSAndroid Build Coastguard Worker {"default_framebuffer", "Render to default framebuffer, set tight bounding box",
5312*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_DEFAULT | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL, 0,
5313*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX},
5314*35238bceSAndroid Build Coastguard Worker {"fbo", "Render to texture, set tight bounding box",
5315*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_RENDERTARGET_FBO | BBoxRenderCase::FLAG_BBOXSIZE_EQUAL, 0,
5316*35238bceSAndroid Build Coastguard Worker BBoxRenderCase::FLAG_PER_PRIMITIVE_BBOX},
5317*35238bceSAndroid Build Coastguard Worker };
5318*35238bceSAndroid Build Coastguard Worker enum PrimitiveRenderType
5319*35238bceSAndroid Build Coastguard Worker {
5320*35238bceSAndroid Build Coastguard Worker TYPE_TRIANGLE,
5321*35238bceSAndroid Build Coastguard Worker TYPE_LINE,
5322*35238bceSAndroid Build Coastguard Worker TYPE_POINT,
5323*35238bceSAndroid Build Coastguard Worker };
5324*35238bceSAndroid Build Coastguard Worker const struct
5325*35238bceSAndroid Build Coastguard Worker {
5326*35238bceSAndroid Build Coastguard Worker const char *name;
5327*35238bceSAndroid Build Coastguard Worker const char *description;
5328*35238bceSAndroid Build Coastguard Worker PrimitiveRenderType type;
5329*35238bceSAndroid Build Coastguard Worker uint32_t flags;
5330*35238bceSAndroid Build Coastguard Worker } primitiveTypes[] = {
5331*35238bceSAndroid Build Coastguard Worker {"triangles", "Triangle render tests", TYPE_TRIANGLE, 0},
5332*35238bceSAndroid Build Coastguard Worker {"lines", "Line render tests", TYPE_LINE, 0},
5333*35238bceSAndroid Build Coastguard Worker {"points", "Point render tests", TYPE_POINT, 0},
5334*35238bceSAndroid Build Coastguard Worker {"wide_lines", "Wide line render tests", TYPE_LINE, LineRenderCase::LINEFLAG_WIDE},
5335*35238bceSAndroid Build Coastguard Worker {"wide_points", "Wide point render tests", TYPE_POINT, PointRenderCase::POINTFLAG_WIDE},
5336*35238bceSAndroid Build Coastguard Worker };
5337*35238bceSAndroid Build Coastguard Worker
5338*35238bceSAndroid Build Coastguard Worker // .state_query
5339*35238bceSAndroid Build Coastguard Worker {
5340*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const stateQueryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "State queries");
5341*35238bceSAndroid Build Coastguard Worker addChild(stateQueryGroup);
5342*35238bceSAndroid Build Coastguard Worker
5343*35238bceSAndroid Build Coastguard Worker stateQueryGroup->addChild(new InitialValueCase(m_context, "initial_value", "Initial value case"));
5344*35238bceSAndroid Build Coastguard Worker stateQueryGroup->addChild(new QueryCase(m_context, "getfloat", "getFloatv", QueryCase::QUERY_FLOAT));
5345*35238bceSAndroid Build Coastguard Worker stateQueryGroup->addChild(new QueryCase(m_context, "getboolean", "getBooleanv", QueryCase::QUERY_BOOLEAN));
5346*35238bceSAndroid Build Coastguard Worker stateQueryGroup->addChild(new QueryCase(m_context, "getinteger", "getIntegerv", QueryCase::QUERY_INT));
5347*35238bceSAndroid Build Coastguard Worker stateQueryGroup->addChild(new QueryCase(m_context, "getinteger64", "getInteger64v", QueryCase::QUERY_INT64));
5348*35238bceSAndroid Build Coastguard Worker }
5349*35238bceSAndroid Build Coastguard Worker
5350*35238bceSAndroid Build Coastguard Worker // .triangles
5351*35238bceSAndroid Build Coastguard Worker // .(wide_)lines
5352*35238bceSAndroid Build Coastguard Worker // .(wide_)points
5353*35238bceSAndroid Build Coastguard Worker for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
5354*35238bceSAndroid Build Coastguard Worker {
5355*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const primitiveGroup = new tcu::TestCaseGroup(
5356*35238bceSAndroid Build Coastguard Worker m_testCtx, primitiveTypes[primitiveTypeNdx].name, primitiveTypes[primitiveTypeNdx].description);
5357*35238bceSAndroid Build Coastguard Worker addChild(primitiveGroup);
5358*35238bceSAndroid Build Coastguard Worker
5359*35238bceSAndroid Build Coastguard Worker for (int stateSetMethodNdx = 0; stateSetMethodNdx < DE_LENGTH_OF_ARRAY(stateSetMethods); ++stateSetMethodNdx)
5360*35238bceSAndroid Build Coastguard Worker {
5361*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const methodGroup = new tcu::TestCaseGroup(
5362*35238bceSAndroid Build Coastguard Worker m_testCtx, stateSetMethods[stateSetMethodNdx].name, stateSetMethods[stateSetMethodNdx].description);
5363*35238bceSAndroid Build Coastguard Worker primitiveGroup->addChild(methodGroup);
5364*35238bceSAndroid Build Coastguard Worker
5365*35238bceSAndroid Build Coastguard Worker for (int pipelineConfigNdx = 0; pipelineConfigNdx < DE_LENGTH_OF_ARRAY(pipelineConfigs);
5366*35238bceSAndroid Build Coastguard Worker ++pipelineConfigNdx)
5367*35238bceSAndroid Build Coastguard Worker {
5368*35238bceSAndroid Build Coastguard Worker if ((stateSetMethods[stateSetMethodNdx].methodFlags & BBoxRenderCase::FLAG_SET_BBOX_OUTPUT) != 0 &&
5369*35238bceSAndroid Build Coastguard Worker (pipelineConfigs[pipelineConfigNdx].stageFlags & BBoxRenderCase::FLAG_TESSELLATION) == 0)
5370*35238bceSAndroid Build Coastguard Worker {
5371*35238bceSAndroid Build Coastguard Worker // invalid config combination
5372*35238bceSAndroid Build Coastguard Worker }
5373*35238bceSAndroid Build Coastguard Worker else
5374*35238bceSAndroid Build Coastguard Worker {
5375*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const pipelineGroup =
5376*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, pipelineConfigs[pipelineConfigNdx].name,
5377*35238bceSAndroid Build Coastguard Worker pipelineConfigs[pipelineConfigNdx].description);
5378*35238bceSAndroid Build Coastguard Worker methodGroup->addChild(pipelineGroup);
5379*35238bceSAndroid Build Coastguard Worker
5380*35238bceSAndroid Build Coastguard Worker for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageConfigs); ++usageNdx)
5381*35238bceSAndroid Build Coastguard Worker {
5382*35238bceSAndroid Build Coastguard Worker const uint32_t flags =
5383*35238bceSAndroid Build Coastguard Worker primitiveTypes[primitiveTypeNdx].flags | stateSetMethods[stateSetMethodNdx].methodFlags |
5384*35238bceSAndroid Build Coastguard Worker pipelineConfigs[pipelineConfigNdx].stageFlags | usageConfigs[usageNdx].flags;
5385*35238bceSAndroid Build Coastguard Worker
5386*35238bceSAndroid Build Coastguard Worker if (usageConfigs[usageNdx].invalidFlags && (flags & usageConfigs[usageNdx].invalidFlags) != 0)
5387*35238bceSAndroid Build Coastguard Worker continue;
5388*35238bceSAndroid Build Coastguard Worker if (usageConfigs[usageNdx].requiredFlags && (flags & usageConfigs[usageNdx].requiredFlags) == 0)
5389*35238bceSAndroid Build Coastguard Worker continue;
5390*35238bceSAndroid Build Coastguard Worker
5391*35238bceSAndroid Build Coastguard Worker switch (primitiveTypes[primitiveTypeNdx].type)
5392*35238bceSAndroid Build Coastguard Worker {
5393*35238bceSAndroid Build Coastguard Worker case TYPE_TRIANGLE:
5394*35238bceSAndroid Build Coastguard Worker pipelineGroup->addChild(new GridRenderCase(m_context, usageConfigs[usageNdx].name,
5395*35238bceSAndroid Build Coastguard Worker usageConfigs[usageNdx].description, flags));
5396*35238bceSAndroid Build Coastguard Worker break;
5397*35238bceSAndroid Build Coastguard Worker case TYPE_LINE:
5398*35238bceSAndroid Build Coastguard Worker pipelineGroup->addChild(new LineRenderCase(m_context, usageConfigs[usageNdx].name,
5399*35238bceSAndroid Build Coastguard Worker usageConfigs[usageNdx].description, flags));
5400*35238bceSAndroid Build Coastguard Worker break;
5401*35238bceSAndroid Build Coastguard Worker case TYPE_POINT:
5402*35238bceSAndroid Build Coastguard Worker pipelineGroup->addChild(new PointRenderCase(m_context, usageConfigs[usageNdx].name,
5403*35238bceSAndroid Build Coastguard Worker usageConfigs[usageNdx].description, flags));
5404*35238bceSAndroid Build Coastguard Worker break;
5405*35238bceSAndroid Build Coastguard Worker default:
5406*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
5407*35238bceSAndroid Build Coastguard Worker }
5408*35238bceSAndroid Build Coastguard Worker }
5409*35238bceSAndroid Build Coastguard Worker }
5410*35238bceSAndroid Build Coastguard Worker }
5411*35238bceSAndroid Build Coastguard Worker }
5412*35238bceSAndroid Build Coastguard Worker }
5413*35238bceSAndroid Build Coastguard Worker
5414*35238bceSAndroid Build Coastguard Worker // .depth
5415*35238bceSAndroid Build Coastguard Worker {
5416*35238bceSAndroid Build Coastguard Worker static const struct
5417*35238bceSAndroid Build Coastguard Worker {
5418*35238bceSAndroid Build Coastguard Worker const char *name;
5419*35238bceSAndroid Build Coastguard Worker const char *description;
5420*35238bceSAndroid Build Coastguard Worker DepthDrawCase::DepthType depthMethod;
5421*35238bceSAndroid Build Coastguard Worker } depthMethods[] = {
5422*35238bceSAndroid Build Coastguard Worker {"builtin_depth", "Fragment depth not modified in fragment shader", DepthDrawCase::DEPTH_BUILTIN},
5423*35238bceSAndroid Build Coastguard Worker {"user_defined_depth", "Fragment depth is defined in the fragment shader",
5424*35238bceSAndroid Build Coastguard Worker DepthDrawCase::DEPTH_USER_DEFINED},
5425*35238bceSAndroid Build Coastguard Worker };
5426*35238bceSAndroid Build Coastguard Worker static const struct
5427*35238bceSAndroid Build Coastguard Worker {
5428*35238bceSAndroid Build Coastguard Worker const char *name;
5429*35238bceSAndroid Build Coastguard Worker const char *description;
5430*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBoxState bboxState;
5431*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBoxSize bboxSize;
5432*35238bceSAndroid Build Coastguard Worker } depthCases[] = {
5433*35238bceSAndroid Build Coastguard Worker {
5434*35238bceSAndroid Build Coastguard Worker "global_state_bbox_equal",
5435*35238bceSAndroid Build Coastguard Worker "Test tight bounding box with global bbox state",
5436*35238bceSAndroid Build Coastguard Worker DepthDrawCase::STATE_GLOBAL,
5437*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBOX_EQUAL,
5438*35238bceSAndroid Build Coastguard Worker },
5439*35238bceSAndroid Build Coastguard Worker {
5440*35238bceSAndroid Build Coastguard Worker "global_state_bbox_larger",
5441*35238bceSAndroid Build Coastguard Worker "Test padded bounding box with global bbox state",
5442*35238bceSAndroid Build Coastguard Worker DepthDrawCase::STATE_GLOBAL,
5443*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBOX_LARGER,
5444*35238bceSAndroid Build Coastguard Worker },
5445*35238bceSAndroid Build Coastguard Worker {
5446*35238bceSAndroid Build Coastguard Worker "per_primitive_bbox_equal",
5447*35238bceSAndroid Build Coastguard Worker "Test tight bounding box with tessellation output bbox",
5448*35238bceSAndroid Build Coastguard Worker DepthDrawCase::STATE_PER_PRIMITIVE,
5449*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBOX_EQUAL,
5450*35238bceSAndroid Build Coastguard Worker },
5451*35238bceSAndroid Build Coastguard Worker {
5452*35238bceSAndroid Build Coastguard Worker "per_primitive_bbox_larger",
5453*35238bceSAndroid Build Coastguard Worker "Test padded bounding box with tessellation output bbox",
5454*35238bceSAndroid Build Coastguard Worker DepthDrawCase::STATE_PER_PRIMITIVE,
5455*35238bceSAndroid Build Coastguard Worker DepthDrawCase::BBOX_LARGER,
5456*35238bceSAndroid Build Coastguard Worker },
5457*35238bceSAndroid Build Coastguard Worker };
5458*35238bceSAndroid Build Coastguard Worker
5459*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const depthGroup =
5460*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "depth", "Test bounding box depth component");
5461*35238bceSAndroid Build Coastguard Worker addChild(depthGroup);
5462*35238bceSAndroid Build Coastguard Worker
5463*35238bceSAndroid Build Coastguard Worker // .builtin_depth
5464*35238bceSAndroid Build Coastguard Worker // .user_defined_depth
5465*35238bceSAndroid Build Coastguard Worker for (int depthNdx = 0; depthNdx < DE_LENGTH_OF_ARRAY(depthMethods); ++depthNdx)
5466*35238bceSAndroid Build Coastguard Worker {
5467*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const group =
5468*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, depthMethods[depthNdx].name, depthMethods[depthNdx].description);
5469*35238bceSAndroid Build Coastguard Worker depthGroup->addChild(group);
5470*35238bceSAndroid Build Coastguard Worker
5471*35238bceSAndroid Build Coastguard Worker for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(depthCases); ++caseNdx)
5472*35238bceSAndroid Build Coastguard Worker group->addChild(new DepthDrawCase(m_context, depthCases[caseNdx].name, depthCases[caseNdx].description,
5473*35238bceSAndroid Build Coastguard Worker depthMethods[depthNdx].depthMethod, depthCases[caseNdx].bboxState,
5474*35238bceSAndroid Build Coastguard Worker depthCases[caseNdx].bboxSize));
5475*35238bceSAndroid Build Coastguard Worker }
5476*35238bceSAndroid Build Coastguard Worker }
5477*35238bceSAndroid Build Coastguard Worker
5478*35238bceSAndroid Build Coastguard Worker // .blit_fbo
5479*35238bceSAndroid Build Coastguard Worker {
5480*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const blitFboGroup =
5481*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "blit_fbo", "Test bounding box does not affect blitting");
5482*35238bceSAndroid Build Coastguard Worker addChild(blitFboGroup);
5483*35238bceSAndroid Build Coastguard Worker
5484*35238bceSAndroid Build Coastguard Worker blitFboGroup->addChild(new BlitFboCase(m_context, "blit_default_to_fbo", "Blit from default fb to fbo",
5485*35238bceSAndroid Build Coastguard Worker BlitFboCase::TARGET_DEFAULT, BlitFboCase::TARGET_FBO));
5486*35238bceSAndroid Build Coastguard Worker blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_default", "Blit from fbo to default fb",
5487*35238bceSAndroid Build Coastguard Worker BlitFboCase::TARGET_FBO, BlitFboCase::TARGET_DEFAULT));
5488*35238bceSAndroid Build Coastguard Worker blitFboGroup->addChild(new BlitFboCase(m_context, "blit_fbo_to_fbo", "Blit from fbo to fbo",
5489*35238bceSAndroid Build Coastguard Worker BlitFboCase::TARGET_FBO, BlitFboCase::TARGET_FBO));
5490*35238bceSAndroid Build Coastguard Worker }
5491*35238bceSAndroid Build Coastguard Worker
5492*35238bceSAndroid Build Coastguard Worker // .clear
5493*35238bceSAndroid Build Coastguard Worker {
5494*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const clearGroup =
5495*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "clear", "Test bounding box does not clears");
5496*35238bceSAndroid Build Coastguard Worker addChild(clearGroup);
5497*35238bceSAndroid Build Coastguard Worker
5498*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "full_clear", "Do full clears", 0));
5499*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles",
5500*35238bceSAndroid Build Coastguard Worker "Do full clears and render some geometry", ClearCase::DRAW_TRIANGLE_BIT));
5501*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "full_clear_with_triangles_per_primitive_bbox",
5502*35238bceSAndroid Build Coastguard Worker "Do full clears and render some geometry",
5503*35238bceSAndroid Build Coastguard Worker ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
5504*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(
5505*35238bceSAndroid Build Coastguard Worker new ClearCase(m_context, "scissored_clear", "Do scissored clears", ClearCase::SCISSOR_CLEAR_BIT));
5506*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles",
5507*35238bceSAndroid Build Coastguard Worker "Do scissored clears and render some geometry",
5508*35238bceSAndroid Build Coastguard Worker ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT));
5509*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "scissored_clear_with_triangles_per_primitive_bbox",
5510*35238bceSAndroid Build Coastguard Worker "Do scissored clears and render some geometry",
5511*35238bceSAndroid Build Coastguard Worker ClearCase::SCISSOR_CLEAR_BIT | ClearCase::DRAW_TRIANGLE_BIT |
5512*35238bceSAndroid Build Coastguard Worker ClearCase::PER_PRIMITIVE_BBOX_BIT));
5513*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear", "Do full clears with enabled scissor",
5514*35238bceSAndroid Build Coastguard Worker ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT));
5515*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles",
5516*35238bceSAndroid Build Coastguard Worker "Do full clears with enabled scissor and render some geometry",
5517*35238bceSAndroid Build Coastguard Worker ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT |
5518*35238bceSAndroid Build Coastguard Worker ClearCase::DRAW_TRIANGLE_BIT));
5519*35238bceSAndroid Build Coastguard Worker clearGroup->addChild(new ClearCase(m_context, "scissored_full_clear_with_triangles_per_primitive_bbox",
5520*35238bceSAndroid Build Coastguard Worker "Do full clears with enabled scissor and render some geometry",
5521*35238bceSAndroid Build Coastguard Worker ClearCase::FULLSCREEN_SCISSOR_BIT | ClearCase::SCISSOR_CLEAR_BIT |
5522*35238bceSAndroid Build Coastguard Worker ClearCase::DRAW_TRIANGLE_BIT | ClearCase::PER_PRIMITIVE_BBOX_BIT));
5523*35238bceSAndroid Build Coastguard Worker }
5524*35238bceSAndroid Build Coastguard Worker
5525*35238bceSAndroid Build Coastguard Worker // .call_order (Khronos bug #13262)
5526*35238bceSAndroid Build Coastguard Worker {
5527*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const callOrderGroup =
5528*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "call_order", "Test viewport and bounding box calls have no effect");
5529*35238bceSAndroid Build Coastguard Worker addChild(callOrderGroup);
5530*35238bceSAndroid Build Coastguard Worker
5531*35238bceSAndroid Build Coastguard Worker callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "viewport_first_bbox_second",
5532*35238bceSAndroid Build Coastguard Worker "Set up viewport first and bbox after",
5533*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase::VIEWPORT_FIRST));
5534*35238bceSAndroid Build Coastguard Worker callOrderGroup->addChild(new ViewportCallOrderCase(m_context, "bbox_first_viewport_second",
5535*35238bceSAndroid Build Coastguard Worker "Set up bbox first and viewport after",
5536*35238bceSAndroid Build Coastguard Worker ViewportCallOrderCase::BBOX_FIRST));
5537*35238bceSAndroid Build Coastguard Worker }
5538*35238bceSAndroid Build Coastguard Worker }
5539*35238bceSAndroid Build Coastguard Worker
5540*35238bceSAndroid Build Coastguard Worker } // namespace Functional
5541*35238bceSAndroid Build Coastguard Worker } // namespace gles31
5542*35238bceSAndroid Build Coastguard Worker } // namespace deqp
5543