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 2014 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 Tessellation and geometry shader interaction stress tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31sTessellationGeometryInteractionTests.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 "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
39*35238bceSAndroid Build Coastguard Worker
40*35238bceSAndroid Build Coastguard Worker #include <sstream>
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker namespace deqp
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker namespace gles31
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace Stress
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker
51*35238bceSAndroid Build Coastguard Worker class AllowedRenderFailureException : public std::runtime_error
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker public:
AllowedRenderFailureException(const char * message)54*35238bceSAndroid Build Coastguard Worker AllowedRenderFailureException(const char *message) : std::runtime_error(message)
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker }
57*35238bceSAndroid Build Coastguard Worker };
58*35238bceSAndroid Build Coastguard Worker
59*35238bceSAndroid Build Coastguard Worker class GridRenderCase : public TestCase
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker public:
62*35238bceSAndroid Build Coastguard Worker enum Flags
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_MAX_SPEC = 0x0001,
65*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_MAX_IMPLEMENTATION = 0x0002,
66*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_MAX_SPEC = 0x0004,
67*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_MAX_IMPLEMENTATION = 0x0008,
68*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC = 0x0010,
69*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION = 0x0020,
70*35238bceSAndroid Build Coastguard Worker };
71*35238bceSAndroid Build Coastguard Worker
72*35238bceSAndroid Build Coastguard Worker GridRenderCase(Context &context, const char *name, const char *description, int flags);
73*35238bceSAndroid Build Coastguard Worker ~GridRenderCase(void);
74*35238bceSAndroid Build Coastguard Worker
75*35238bceSAndroid Build Coastguard Worker private:
76*35238bceSAndroid Build Coastguard Worker void init(void);
77*35238bceSAndroid Build Coastguard Worker void deinit(void);
78*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
79*35238bceSAndroid Build Coastguard Worker
80*35238bceSAndroid Build Coastguard Worker void renderTo(std::vector<tcu::Surface> &dst);
81*35238bceSAndroid Build Coastguard Worker bool verifyResultLayer(int layerNdx, const tcu::Surface &dst);
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker const char *getVertexSource(void);
84*35238bceSAndroid Build Coastguard Worker const char *getFragmentSource(void);
85*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(int tessLevel);
86*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(int tessLevel);
87*35238bceSAndroid Build Coastguard Worker std::string getGeometryShaderSource(int numPrimitives, int numInstances);
88*35238bceSAndroid Build Coastguard Worker
89*35238bceSAndroid Build Coastguard Worker enum
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 256
92*35238bceSAndroid Build Coastguard Worker };
93*35238bceSAndroid Build Coastguard Worker
94*35238bceSAndroid Build Coastguard Worker std::string m_description;
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker const int m_flags;
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
99*35238bceSAndroid Build Coastguard Worker int m_numLayers;
100*35238bceSAndroid Build Coastguard Worker };
101*35238bceSAndroid Build Coastguard Worker
GridRenderCase(Context & context,const char * name,const char * description,int flags)102*35238bceSAndroid Build Coastguard Worker GridRenderCase::GridRenderCase(Context &context, const char *name, const char *description, int flags)
103*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
104*35238bceSAndroid Build Coastguard Worker , m_description(description)
105*35238bceSAndroid Build Coastguard Worker , m_flags(flags)
106*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
107*35238bceSAndroid Build Coastguard Worker , m_numLayers(1)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_TESSELLATION_MAX_SPEC) == 0) || ((m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) == 0));
110*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_GEOMETRY_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) == 0));
111*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) == 0) ||
112*35238bceSAndroid Build Coastguard Worker ((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) == 0));
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker
~GridRenderCase(void)115*35238bceSAndroid Build Coastguard Worker GridRenderCase::~GridRenderCase(void)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker deinit();
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker
init(void)120*35238bceSAndroid Build Coastguard Worker void GridRenderCase::init(void)
121*35238bceSAndroid Build Coastguard Worker {
122*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
123*35238bceSAndroid Build Coastguard Worker
124*35238bceSAndroid Build Coastguard Worker // Requirements
125*35238bceSAndroid Build Coastguard Worker
126*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
127*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
128*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
129*35238bceSAndroid Build Coastguard Worker
130*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
131*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" +
132*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_SIZE) + " or larger render target.");
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker // Log
135*35238bceSAndroid Build Coastguard Worker
136*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
137*35238bceSAndroid Build Coastguard Worker << "Testing tessellation and geometry shaders that output a large number of primitives.\n"
138*35238bceSAndroid Build Coastguard Worker << m_description << tcu::TestLog::EndMessage;
139*35238bceSAndroid Build Coastguard Worker
140*35238bceSAndroid Build Coastguard Worker // Gen program
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
143*35238bceSAndroid Build Coastguard Worker int tessGenLevel = -1;
144*35238bceSAndroid Build Coastguard Worker
145*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource());
146*35238bceSAndroid Build Coastguard Worker
147*35238bceSAndroid Build Coastguard Worker // Tessellation limits
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_TESS_GEN_LEVEL, &tessGenLevel);
152*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query tessellation limits");
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_TESSELLATION_MAX_SPEC)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker tessGenLevel = 64;
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker else
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker tessGenLevel = 5;
161*35238bceSAndroid Build Coastguard Worker }
162*35238bceSAndroid Build Coastguard Worker
163*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation level: " << tessGenLevel << ", mode = quad.\n"
164*35238bceSAndroid Build Coastguard Worker << "\tEach input patch produces " << (tessGenLevel * tessGenLevel) << " ("
165*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2) << " triangles)\n"
166*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
167*35238bceSAndroid Build Coastguard Worker
168*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(getTessellationControlSource(tessGenLevel))
169*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource(tessGenLevel));
170*35238bceSAndroid Build Coastguard Worker }
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker // Geometry limits
173*35238bceSAndroid Build Coastguard Worker {
174*35238bceSAndroid Build Coastguard Worker int geometryOutputComponents = -1;
175*35238bceSAndroid Build Coastguard Worker int geometryOutputVertices = -1;
176*35238bceSAndroid Build Coastguard Worker int geometryTotalOutputComponents = -1;
177*35238bceSAndroid Build Coastguard Worker int geometryShaderInvocations = -1;
178*35238bceSAndroid Build Coastguard Worker bool logGeometryLimits = false;
179*35238bceSAndroid Build Coastguard Worker bool logInvocationLimits = false;
180*35238bceSAndroid Build Coastguard Worker
181*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
184*35238bceSAndroid Build Coastguard Worker << "Using implementation maximum geometry shader output limits."
185*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
186*35238bceSAndroid Build Coastguard Worker
187*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &geometryOutputComponents);
188*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &geometryOutputVertices);
189*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &geometryTotalOutputComponents);
190*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry limits");
191*35238bceSAndroid Build Coastguard Worker
192*35238bceSAndroid Build Coastguard Worker logGeometryLimits = true;
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_MAX_SPEC)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
197*35238bceSAndroid Build Coastguard Worker << "Using geometry shader extension minimum maximum output limits."
198*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker geometryOutputComponents = 128;
201*35238bceSAndroid Build Coastguard Worker geometryOutputVertices = 256;
202*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents = 1024;
203*35238bceSAndroid Build Coastguard Worker logGeometryLimits = true;
204*35238bceSAndroid Build Coastguard Worker }
205*35238bceSAndroid Build Coastguard Worker else
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker geometryOutputComponents = 128;
208*35238bceSAndroid Build Coastguard Worker geometryOutputVertices = 16;
209*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents = 1024;
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &geometryShaderInvocations);
215*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry invocation limits");
216*35238bceSAndroid Build Coastguard Worker
217*35238bceSAndroid Build Coastguard Worker logInvocationLimits = true;
218*35238bceSAndroid Build Coastguard Worker }
219*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC)
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker geometryShaderInvocations = 32;
222*35238bceSAndroid Build Coastguard Worker logInvocationLimits = true;
223*35238bceSAndroid Build Coastguard Worker }
224*35238bceSAndroid Build Coastguard Worker else
225*35238bceSAndroid Build Coastguard Worker {
226*35238bceSAndroid Build Coastguard Worker geometryShaderInvocations = 4;
227*35238bceSAndroid Build Coastguard Worker }
228*35238bceSAndroid Build Coastguard Worker
229*35238bceSAndroid Build Coastguard Worker if (logGeometryLimits || logInvocationLimits)
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder msg(&m_testCtx.getLog());
232*35238bceSAndroid Build Coastguard Worker
233*35238bceSAndroid Build Coastguard Worker msg << "Geometry shader, targeting following limits:\n";
234*35238bceSAndroid Build Coastguard Worker
235*35238bceSAndroid Build Coastguard Worker if (logGeometryLimits)
236*35238bceSAndroid Build Coastguard Worker msg << "\tGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = " << geometryOutputComponents << "\n"
237*35238bceSAndroid Build Coastguard Worker << "\tGL_MAX_GEOMETRY_OUTPUT_VERTICES = " << geometryOutputVertices << "\n"
238*35238bceSAndroid Build Coastguard Worker << "\tGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << geometryTotalOutputComponents << "\n";
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker if (logInvocationLimits)
241*35238bceSAndroid Build Coastguard Worker msg << "\tGL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << geometryShaderInvocations;
242*35238bceSAndroid Build Coastguard Worker
243*35238bceSAndroid Build Coastguard Worker msg << tcu::TestLog::EndMessage;
244*35238bceSAndroid Build Coastguard Worker }
245*35238bceSAndroid Build Coastguard Worker
246*35238bceSAndroid Build Coastguard Worker {
247*35238bceSAndroid Build Coastguard Worker const int numComponentsPerVertex = 8; // vec4 pos, vec4 color
248*35238bceSAndroid Build Coastguard Worker
249*35238bceSAndroid Build Coastguard Worker // If FLAG_GEOMETRY_SEPARATE_PRIMITIVES is not set, geometry shader fills a rectangle area in slices.
250*35238bceSAndroid Build Coastguard Worker // Each slice is a triangle strip and is generated by a single shader invocation.
251*35238bceSAndroid Build Coastguard Worker // One slice with 4 segment ends (nodes) and 3 segments:
252*35238bceSAndroid Build Coastguard Worker // .__.__.__.
253*35238bceSAndroid Build Coastguard Worker // |\ |\ |\ |
254*35238bceSAndroid Build Coastguard Worker // |_\|_\|_\|
255*35238bceSAndroid Build Coastguard Worker
256*35238bceSAndroid Build Coastguard Worker const int numSliceNodesComponentLimit =
257*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents / (2 * numComponentsPerVertex); // each node 2 vertices
258*35238bceSAndroid Build Coastguard Worker const int numSliceNodesOutputLimit = geometryOutputVertices / 2; // each node 2 vertices
259*35238bceSAndroid Build Coastguard Worker const int numSliceNodes = de::min(numSliceNodesComponentLimit, numSliceNodesOutputLimit);
260*35238bceSAndroid Build Coastguard Worker
261*35238bceSAndroid Build Coastguard Worker const int numVerticesPerInvocation = numSliceNodes * 2;
262*35238bceSAndroid Build Coastguard Worker const int numPrimitivesPerInvocation = (numSliceNodes - 1) * 2;
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker const int geometryVerticesPerPrimitive = numVerticesPerInvocation * geometryShaderInvocations;
265*35238bceSAndroid Build Coastguard Worker const int geometryPrimitivesOutPerPrimitive = numPrimitivesPerInvocation * geometryShaderInvocations;
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Geometry shader:\n"
268*35238bceSAndroid Build Coastguard Worker << "\tTotal output vertex count per invocation: " << (numVerticesPerInvocation)
269*35238bceSAndroid Build Coastguard Worker << "\n"
270*35238bceSAndroid Build Coastguard Worker << "\tTotal output primitive count per invocation: " << (numPrimitivesPerInvocation)
271*35238bceSAndroid Build Coastguard Worker << "\n"
272*35238bceSAndroid Build Coastguard Worker << "\tNumber of invocations per primitive: " << geometryShaderInvocations << "\n"
273*35238bceSAndroid Build Coastguard Worker << "\tTotal output vertex count per input primitive: "
274*35238bceSAndroid Build Coastguard Worker << (geometryVerticesPerPrimitive) << "\n"
275*35238bceSAndroid Build Coastguard Worker << "\tTotal output primitive count per input primitive: "
276*35238bceSAndroid Build Coastguard Worker << (geometryPrimitivesOutPerPrimitive) << "\n"
277*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker sources << glu::GeometrySource(
280*35238bceSAndroid Build Coastguard Worker getGeometryShaderSource(numPrimitivesPerInvocation, geometryShaderInvocations));
281*35238bceSAndroid Build Coastguard Worker
282*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program:\n"
283*35238bceSAndroid Build Coastguard Worker << "\tTotal program output vertices count per input patch: "
284*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2 * geometryVerticesPerPrimitive) << "\n"
285*35238bceSAndroid Build Coastguard Worker << "\tTotal program output primitive count per input patch: "
286*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2 * geometryPrimitivesOutPerPrimitive) << "\n"
287*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
288*35238bceSAndroid Build Coastguard Worker }
289*35238bceSAndroid Build Coastguard Worker }
290*35238bceSAndroid Build Coastguard Worker
291*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources);
292*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
293*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
294*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
295*35238bceSAndroid Build Coastguard Worker }
296*35238bceSAndroid Build Coastguard Worker }
297*35238bceSAndroid Build Coastguard Worker
deinit(void)298*35238bceSAndroid Build Coastguard Worker void GridRenderCase::deinit(void)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker delete m_program;
301*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
302*35238bceSAndroid Build Coastguard Worker }
303*35238bceSAndroid Build Coastguard Worker
iterate(void)304*35238bceSAndroid Build Coastguard Worker GridRenderCase::IterateResult GridRenderCase::iterate(void)
305*35238bceSAndroid Build Coastguard Worker {
306*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Surface> renderedLayers(m_numLayers);
307*35238bceSAndroid Build Coastguard Worker bool allLayersOk = true;
308*35238bceSAndroid Build Coastguard Worker
309*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numLayers; ++ndx)
310*35238bceSAndroid Build Coastguard Worker renderedLayers[ndx].setSize(RENDER_SIZE, RENDER_SIZE);
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
313*35238bceSAndroid Build Coastguard Worker << "Rendering single point at the origin. Expecting yellow and green colored grid-like image. "
314*35238bceSAndroid Build Coastguard Worker "(High-frequency grid may appear unicolored)."
315*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
316*35238bceSAndroid Build Coastguard Worker
317*35238bceSAndroid Build Coastguard Worker try
318*35238bceSAndroid Build Coastguard Worker {
319*35238bceSAndroid Build Coastguard Worker renderTo(renderedLayers);
320*35238bceSAndroid Build Coastguard Worker }
321*35238bceSAndroid Build Coastguard Worker catch (const AllowedRenderFailureException &ex)
322*35238bceSAndroid Build Coastguard Worker {
323*35238bceSAndroid Build Coastguard Worker // Got accepted failure
324*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Could not render, reason: " << ex.what() << "\n"
325*35238bceSAndroid Build Coastguard Worker << "Failure is allowed." << tcu::TestLog::EndMessage;
326*35238bceSAndroid Build Coastguard Worker
327*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
328*35238bceSAndroid Build Coastguard Worker return STOP;
329*35238bceSAndroid Build Coastguard Worker }
330*35238bceSAndroid Build Coastguard Worker
331*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numLayers; ++ndx)
332*35238bceSAndroid Build Coastguard Worker allLayersOk &= verifyResultLayer(ndx, renderedLayers[ndx]);
333*35238bceSAndroid Build Coastguard Worker
334*35238bceSAndroid Build Coastguard Worker if (allLayersOk)
335*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
336*35238bceSAndroid Build Coastguard Worker else
337*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
338*35238bceSAndroid Build Coastguard Worker return STOP;
339*35238bceSAndroid Build Coastguard Worker }
340*35238bceSAndroid Build Coastguard Worker
renderTo(std::vector<tcu::Surface> & dst)341*35238bceSAndroid Build Coastguard Worker void GridRenderCase::renderTo(std::vector<tcu::Surface> &dst)
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
344*35238bceSAndroid Build Coastguard Worker const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
345*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
346*35238bceSAndroid Build Coastguard Worker
347*35238bceSAndroid Build Coastguard Worker if (positionLocation == -1)
348*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("Attribute a_position location was -1");
349*35238bceSAndroid Build Coastguard Worker
350*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, dst.front().getWidth(), dst.front().getHeight());
351*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
352*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
353*35238bceSAndroid Build Coastguard Worker
354*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
355*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao");
356*35238bceSAndroid Build Coastguard Worker
357*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
358*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 1);
361*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
362*35238bceSAndroid Build Coastguard Worker
363*35238bceSAndroid Build Coastguard Worker gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f);
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker // clear viewport
366*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
367*35238bceSAndroid Build Coastguard Worker
368*35238bceSAndroid Build Coastguard Worker // draw
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker glw::GLenum glerror;
371*35238bceSAndroid Build Coastguard Worker
372*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 1);
373*35238bceSAndroid Build Coastguard Worker
374*35238bceSAndroid Build Coastguard Worker // allow always OOM
375*35238bceSAndroid Build Coastguard Worker glerror = gl.getError();
376*35238bceSAndroid Build Coastguard Worker if (glerror == GL_OUT_OF_MEMORY)
377*35238bceSAndroid Build Coastguard Worker throw AllowedRenderFailureException("got GL_OUT_OF_MEMORY while drawing");
378*35238bceSAndroid Build Coastguard Worker
379*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(glerror, "draw patches");
380*35238bceSAndroid Build Coastguard Worker }
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker // Read layers
383*35238bceSAndroid Build Coastguard Worker
384*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.front().getAccess());
385*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker
verifyResultLayer(int layerNdx,const tcu::Surface & image)388*35238bceSAndroid Build Coastguard Worker bool GridRenderCase::verifyResultLayer(int layerNdx, const tcu::Surface &image)
389*35238bceSAndroid Build Coastguard Worker {
390*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(image.getWidth(), image.getHeight());
391*35238bceSAndroid Build Coastguard Worker bool foundError = false;
392*35238bceSAndroid Build Coastguard Worker
393*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output layer " << layerNdx << tcu::TestLog::EndMessage;
396*35238bceSAndroid Build Coastguard Worker
397*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < image.getHeight(); ++y)
398*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < image.getWidth(); ++x)
399*35238bceSAndroid Build Coastguard Worker {
400*35238bceSAndroid Build Coastguard Worker const int threshold = 8;
401*35238bceSAndroid Build Coastguard Worker const tcu::RGBA color = image.getPixel(x, y);
402*35238bceSAndroid Build Coastguard Worker
403*35238bceSAndroid Build Coastguard Worker // Color must be a linear combination of green and yellow
404*35238bceSAndroid Build Coastguard Worker if (color.getGreen() < 255 - threshold || color.getBlue() > threshold)
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
407*35238bceSAndroid Build Coastguard Worker foundError = true;
408*35238bceSAndroid Build Coastguard Worker }
409*35238bceSAndroid Build Coastguard Worker }
410*35238bceSAndroid Build Coastguard Worker
411*35238bceSAndroid Build Coastguard Worker if (!foundError)
412*35238bceSAndroid Build Coastguard Worker {
413*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image valid." << tcu::TestLog::EndMessage
414*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
415*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
416*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
417*35238bceSAndroid Build Coastguard Worker return true;
418*35238bceSAndroid Build Coastguard Worker }
419*35238bceSAndroid Build Coastguard Worker else
420*35238bceSAndroid Build Coastguard Worker {
421*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed, found invalid pixels."
422*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage
423*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
424*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
425*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
426*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
427*35238bceSAndroid Build Coastguard Worker return false;
428*35238bceSAndroid Build Coastguard Worker }
429*35238bceSAndroid Build Coastguard Worker }
430*35238bceSAndroid Build Coastguard Worker
getVertexSource(void)431*35238bceSAndroid Build Coastguard Worker const char *GridRenderCase::getVertexSource(void)
432*35238bceSAndroid Build Coastguard Worker {
433*35238bceSAndroid Build Coastguard Worker return "#version 310 es\n"
434*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
435*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
436*35238bceSAndroid Build Coastguard Worker "{\n"
437*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
438*35238bceSAndroid Build Coastguard Worker "}\n";
439*35238bceSAndroid Build Coastguard Worker }
440*35238bceSAndroid Build Coastguard Worker
getFragmentSource(void)441*35238bceSAndroid Build Coastguard Worker const char *GridRenderCase::getFragmentSource(void)
442*35238bceSAndroid Build Coastguard Worker {
443*35238bceSAndroid Build Coastguard Worker return "#version 310 es\n"
444*35238bceSAndroid Build Coastguard Worker "flat in mediump vec4 v_color;\n"
445*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
446*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
447*35238bceSAndroid Build Coastguard Worker "{\n"
448*35238bceSAndroid Build Coastguard Worker " fragColor = v_color;\n"
449*35238bceSAndroid Build Coastguard Worker "}\n";
450*35238bceSAndroid Build Coastguard Worker }
451*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(int tessLevel)452*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getTessellationControlSource(int tessLevel)
453*35238bceSAndroid Build Coastguard Worker {
454*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker buf << "#version 310 es\n"
457*35238bceSAndroid Build Coastguard Worker "#extension GL_EXT_tessellation_shader : require\n"
458*35238bceSAndroid Build Coastguard Worker "layout(vertices=1) out;\n"
459*35238bceSAndroid Build Coastguard Worker "\n"
460*35238bceSAndroid Build Coastguard Worker "void main()\n"
461*35238bceSAndroid Build Coastguard Worker "{\n"
462*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
463*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = "
464*35238bceSAndroid Build Coastguard Worker << tessLevel
465*35238bceSAndroid Build Coastguard Worker << ".0;\n"
466*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = "
467*35238bceSAndroid Build Coastguard Worker << tessLevel
468*35238bceSAndroid Build Coastguard Worker << ".0;\n"
469*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = "
470*35238bceSAndroid Build Coastguard Worker << tessLevel
471*35238bceSAndroid Build Coastguard Worker << ".0;\n"
472*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = "
473*35238bceSAndroid Build Coastguard Worker << tessLevel
474*35238bceSAndroid Build Coastguard Worker << ".0;\n"
475*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = "
476*35238bceSAndroid Build Coastguard Worker << tessLevel
477*35238bceSAndroid Build Coastguard Worker << ".0;\n"
478*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = "
479*35238bceSAndroid Build Coastguard Worker << tessLevel
480*35238bceSAndroid Build Coastguard Worker << ".0;\n"
481*35238bceSAndroid Build Coastguard Worker "}\n";
482*35238bceSAndroid Build Coastguard Worker
483*35238bceSAndroid Build Coastguard Worker return buf.str();
484*35238bceSAndroid Build Coastguard Worker }
485*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(int tessLevel)486*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getTessellationEvaluationSource(int tessLevel)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker buf << "#version 310 es\n"
491*35238bceSAndroid Build Coastguard Worker "#extension GL_EXT_tessellation_shader : require\n"
492*35238bceSAndroid Build Coastguard Worker "layout(quads) in;\n"
493*35238bceSAndroid Build Coastguard Worker "\n"
494*35238bceSAndroid Build Coastguard Worker "out mediump ivec2 v_tessellationGridPosition;\n"
495*35238bceSAndroid Build Coastguard Worker "\n"
496*35238bceSAndroid Build Coastguard Worker "// note: No need to use precise gl_Position since position does not depend on order\n"
497*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
498*35238bceSAndroid Build Coastguard Worker "{\n"
499*35238bceSAndroid Build Coastguard Worker " // Fill the whole viewport\n"
500*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(gl_TessCoord.x * 2.0 - 1.0, gl_TessCoord.y * 2.0 - 1.0, 0.0, 1.0);\n"
501*35238bceSAndroid Build Coastguard Worker " // Calculate position in tessellation grid\n"
502*35238bceSAndroid Build Coastguard Worker " v_tessellationGridPosition = ivec2(round(gl_TessCoord.xy * float("
503*35238bceSAndroid Build Coastguard Worker << tessLevel
504*35238bceSAndroid Build Coastguard Worker << ")));\n"
505*35238bceSAndroid Build Coastguard Worker "}\n";
506*35238bceSAndroid Build Coastguard Worker
507*35238bceSAndroid Build Coastguard Worker return buf.str();
508*35238bceSAndroid Build Coastguard Worker }
509*35238bceSAndroid Build Coastguard Worker
getGeometryShaderSource(int numPrimitives,int numInstances)510*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getGeometryShaderSource(int numPrimitives, int numInstances)
511*35238bceSAndroid Build Coastguard Worker {
512*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker buf << "#version 310 es\n"
515*35238bceSAndroid Build Coastguard Worker "#extension GL_EXT_geometry_shader : require\n"
516*35238bceSAndroid Build Coastguard Worker "layout(triangles, invocations="
517*35238bceSAndroid Build Coastguard Worker << numInstances
518*35238bceSAndroid Build Coastguard Worker << ") in;\n"
519*35238bceSAndroid Build Coastguard Worker "layout(triangle_strip, max_vertices="
520*35238bceSAndroid Build Coastguard Worker << (numPrimitives + 2)
521*35238bceSAndroid Build Coastguard Worker << ") out;\n"
522*35238bceSAndroid Build Coastguard Worker "\n"
523*35238bceSAndroid Build Coastguard Worker "in mediump ivec2 v_tessellationGridPosition[];\n"
524*35238bceSAndroid Build Coastguard Worker "flat out highp vec4 v_color;\n"
525*35238bceSAndroid Build Coastguard Worker "\n"
526*35238bceSAndroid Build Coastguard Worker "void main ()\n"
527*35238bceSAndroid Build Coastguard Worker "{\n"
528*35238bceSAndroid Build Coastguard Worker " const float equalThreshold = 0.001;\n"
529*35238bceSAndroid Build Coastguard Worker " const float gapOffset = 0.0001; // subdivision performed by the geometry shader might produce gaps. "
530*35238bceSAndroid Build Coastguard Worker "Fill potential gaps by enlarging the output slice a little.\n"
531*35238bceSAndroid Build Coastguard Worker "\n"
532*35238bceSAndroid Build Coastguard Worker " // Input triangle is generated from an axis-aligned rectangle by splitting it in half\n"
533*35238bceSAndroid Build Coastguard Worker " // Original rectangle can be found by finding the bounding AABB of the triangle\n"
534*35238bceSAndroid Build Coastguard Worker " vec4 aabb = vec4(min(gl_in[0].gl_Position.x, min(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n"
535*35238bceSAndroid Build Coastguard Worker " min(gl_in[0].gl_Position.y, min(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)),\n"
536*35238bceSAndroid Build Coastguard Worker " max(gl_in[0].gl_Position.x, max(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n"
537*35238bceSAndroid Build Coastguard Worker " max(gl_in[0].gl_Position.y, max(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)));\n"
538*35238bceSAndroid Build Coastguard Worker "\n"
539*35238bceSAndroid Build Coastguard Worker " // Location in tessellation grid\n"
540*35238bceSAndroid Build Coastguard Worker " ivec2 gridPosition = ivec2(min(v_tessellationGridPosition[0], min(v_tessellationGridPosition[1], "
541*35238bceSAndroid Build Coastguard Worker "v_tessellationGridPosition[2])));\n"
542*35238bceSAndroid Build Coastguard Worker "\n"
543*35238bceSAndroid Build Coastguard Worker " // Which triangle of the two that split the grid cell\n"
544*35238bceSAndroid Build Coastguard Worker " int numVerticesOnBottomEdge = 0;\n"
545*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < 3; ++ndx)\n"
546*35238bceSAndroid Build Coastguard Worker " if (abs(gl_in[ndx].gl_Position.y - aabb.w) < equalThreshold)\n"
547*35238bceSAndroid Build Coastguard Worker " ++numVerticesOnBottomEdge;\n"
548*35238bceSAndroid Build Coastguard Worker " bool isBottomTriangle = numVerticesOnBottomEdge == 2;\n"
549*35238bceSAndroid Build Coastguard Worker "\n"
550*35238bceSAndroid Build Coastguard Worker " // Fill the input area with slices\n"
551*35238bceSAndroid Build Coastguard Worker " // Upper triangle produces slices only to the upper half of the quad and vice-versa\n"
552*35238bceSAndroid Build Coastguard Worker " float triangleOffset = (isBottomTriangle) ? ((aabb.w + aabb.y) / 2.0) : (aabb.y);\n"
553*35238bceSAndroid Build Coastguard Worker " // Each slice is a invocation\n"
554*35238bceSAndroid Build Coastguard Worker " float sliceHeight = (aabb.w - aabb.y) / float(2 * "
555*35238bceSAndroid Build Coastguard Worker << numInstances
556*35238bceSAndroid Build Coastguard Worker << ");\n"
557*35238bceSAndroid Build Coastguard Worker " float invocationOffset = float(gl_InvocationID) * sliceHeight;\n"
558*35238bceSAndroid Build Coastguard Worker "\n"
559*35238bceSAndroid Build Coastguard Worker " vec4 outputSliceArea;\n"
560*35238bceSAndroid Build Coastguard Worker " outputSliceArea.x = aabb.x - gapOffset;\n"
561*35238bceSAndroid Build Coastguard Worker " outputSliceArea.y = triangleOffset + invocationOffset - gapOffset;\n"
562*35238bceSAndroid Build Coastguard Worker " outputSliceArea.z = aabb.z + gapOffset;\n"
563*35238bceSAndroid Build Coastguard Worker " outputSliceArea.w = triangleOffset + invocationOffset + sliceHeight + gapOffset;\n"
564*35238bceSAndroid Build Coastguard Worker "\n"
565*35238bceSAndroid Build Coastguard Worker " // Draw slice\n"
566*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < "
567*35238bceSAndroid Build Coastguard Worker << ((numPrimitives + 2) / 2)
568*35238bceSAndroid Build Coastguard Worker << "; ++ndx)\n"
569*35238bceSAndroid Build Coastguard Worker " {\n"
570*35238bceSAndroid Build Coastguard Worker " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
571*35238bceSAndroid Build Coastguard Worker " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
572*35238bceSAndroid Build Coastguard Worker " vec4 outputColor = (((gl_InvocationID + ndx) % 2) == 0) ? (green) : (yellow);\n"
573*35238bceSAndroid Build Coastguard Worker " float xpos = mix(outputSliceArea.x, outputSliceArea.z, float(ndx) / float("
574*35238bceSAndroid Build Coastguard Worker << (numPrimitives / 2)
575*35238bceSAndroid Build Coastguard Worker << "));\n"
576*35238bceSAndroid Build Coastguard Worker "\n"
577*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(xpos, outputSliceArea.y, 0.0, 1.0);\n"
578*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
579*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
580*35238bceSAndroid Build Coastguard Worker "\n"
581*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(xpos, outputSliceArea.w, 0.0, 1.0);\n"
582*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
583*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
584*35238bceSAndroid Build Coastguard Worker " }\n"
585*35238bceSAndroid Build Coastguard Worker "}\n";
586*35238bceSAndroid Build Coastguard Worker
587*35238bceSAndroid Build Coastguard Worker return buf.str();
588*35238bceSAndroid Build Coastguard Worker }
589*35238bceSAndroid Build Coastguard Worker
590*35238bceSAndroid Build Coastguard Worker } // namespace
591*35238bceSAndroid Build Coastguard Worker
TessellationGeometryInteractionTests(Context & context)592*35238bceSAndroid Build Coastguard Worker TessellationGeometryInteractionTests::TessellationGeometryInteractionTests(Context &context)
593*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "tessellation_geometry_interaction",
594*35238bceSAndroid Build Coastguard Worker "Tessellation and geometry shader interaction stress tests")
595*35238bceSAndroid Build Coastguard Worker {
596*35238bceSAndroid Build Coastguard Worker }
597*35238bceSAndroid Build Coastguard Worker
~TessellationGeometryInteractionTests(void)598*35238bceSAndroid Build Coastguard Worker TessellationGeometryInteractionTests::~TessellationGeometryInteractionTests(void)
599*35238bceSAndroid Build Coastguard Worker {
600*35238bceSAndroid Build Coastguard Worker }
601*35238bceSAndroid Build Coastguard Worker
init(void)602*35238bceSAndroid Build Coastguard Worker void TessellationGeometryInteractionTests::init(void)
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const multilimitGroup =
605*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "render_multiple_limits", "Various render tests");
606*35238bceSAndroid Build Coastguard Worker
607*35238bceSAndroid Build Coastguard Worker addChild(multilimitGroup);
608*35238bceSAndroid Build Coastguard Worker
609*35238bceSAndroid Build Coastguard Worker // .render_multiple_limits
610*35238bceSAndroid Build Coastguard Worker {
611*35238bceSAndroid Build Coastguard Worker static const struct LimitCaseDef
612*35238bceSAndroid Build Coastguard Worker {
613*35238bceSAndroid Build Coastguard Worker const char *name;
614*35238bceSAndroid Build Coastguard Worker const char *desc;
615*35238bceSAndroid Build Coastguard Worker int flags;
616*35238bceSAndroid Build Coastguard Worker } cases[] = {
617*35238bceSAndroid Build Coastguard Worker // Test multiple limits at the same time
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker {"output_required_max_tessellation_max_geometry",
620*35238bceSAndroid Build Coastguard Worker "Minimum maximum tessellation level and geometry shader output vertices",
621*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC},
622*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_tessellation_max_geometry",
623*35238bceSAndroid Build Coastguard Worker "Maximum tessellation level and geometry shader output vertices supported by the implementation",
624*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION},
625*35238bceSAndroid Build Coastguard Worker {"output_required_max_tessellation_max_invocations",
626*35238bceSAndroid Build Coastguard Worker "Minimum maximum tessellation level and geometry shader invocations",
627*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC},
628*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_tessellation_max_invocations",
629*35238bceSAndroid Build Coastguard Worker "Maximum tessellation level and geometry shader invocations supported by the implementation",
630*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION |
631*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION},
632*35238bceSAndroid Build Coastguard Worker {"output_required_max_geometry_max_invocations",
633*35238bceSAndroid Build Coastguard Worker "Minimum maximum geometry shader output vertices and invocations",
634*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC},
635*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_geometry_max_invocations",
636*35238bceSAndroid Build Coastguard Worker "Maximum geometry shader output vertices and invocations invocations supported by the implementation",
637*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION |
638*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION},
639*35238bceSAndroid Build Coastguard Worker
640*35238bceSAndroid Build Coastguard Worker // Test all limits simultaneously
641*35238bceSAndroid Build Coastguard Worker {"output_max_required", "Output minimum maximum number of vertices",
642*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC |
643*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC},
644*35238bceSAndroid Build Coastguard Worker {"output_max_implementation", "Output maximum number of vertices supported by the implementation",
645*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION |
646*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION},
647*35238bceSAndroid Build Coastguard Worker };
648*35238bceSAndroid Build Coastguard Worker
649*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ++ndx)
650*35238bceSAndroid Build Coastguard Worker multilimitGroup->addChild(
651*35238bceSAndroid Build Coastguard Worker new GridRenderCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].flags));
652*35238bceSAndroid Build Coastguard Worker }
653*35238bceSAndroid Build Coastguard Worker }
654*35238bceSAndroid Build Coastguard Worker
655*35238bceSAndroid Build Coastguard Worker } // namespace Stress
656*35238bceSAndroid Build Coastguard Worker } // namespace gles31
657*35238bceSAndroid Build Coastguard Worker } // namespace deqp
658