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 tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fTessellationGeometryInteractionTests.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 "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker #include <sstream>
45*35238bceSAndroid Build Coastguard Worker #include <algorithm>
46*35238bceSAndroid Build Coastguard Worker #include <iterator>
47*35238bceSAndroid Build Coastguard Worker
48*35238bceSAndroid Build Coastguard Worker namespace deqp
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker namespace gles31
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker namespace Functional
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker
specializeShader(const std::string & shaderSource,const glu::ContextType & contextType)57*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(const std::string &shaderSource, const glu::ContextType &contextType)
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
60*35238bceSAndroid Build Coastguard Worker glu::contextSupports(contextType, glu::ApiType::core(4, 5));
61*35238bceSAndroid Build Coastguard Worker
62*35238bceSAndroid Build Coastguard Worker const bool supportsGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker std::map<std::string, std::string> shaderArgs;
65*35238bceSAndroid Build Coastguard Worker
66*35238bceSAndroid Build Coastguard Worker shaderArgs["VERSION_DECL"] = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(contextType));
67*35238bceSAndroid Build Coastguard Worker shaderArgs["EXTENSION_GEOMETRY_SHADER"] =
68*35238bceSAndroid Build Coastguard Worker (supportsES32orGL45) ? ("") : ("#extension GL_EXT_geometry_shader : require\n");
69*35238bceSAndroid Build Coastguard Worker shaderArgs["EXTENSION_TESSELATION_SHADER"] =
70*35238bceSAndroid Build Coastguard Worker (supportsES32orGL45) ? ("") : ("#extension GL_EXT_tessellation_shader : require\n");
71*35238bceSAndroid Build Coastguard Worker shaderArgs["EXTENSION_TESSELATION_POINT_SIZE"] =
72*35238bceSAndroid Build Coastguard Worker (supportsGL45) ? ("") : ("#extension GL_EXT_tessellation_point_size : require\n");
73*35238bceSAndroid Build Coastguard Worker shaderArgs["EXTENSION_GEOMETRY_POINT_SIZE"] =
74*35238bceSAndroid Build Coastguard Worker (supportsGL45) ? ("") : ("#extension GL_EXT_geometry_point_size : require\n");
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker return tcu::StringTemplate(shaderSource).specialize(shaderArgs);
77*35238bceSAndroid Build Coastguard Worker }
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker static const char *const s_positionVertexShader = "${VERSION_DECL}\n"
80*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
81*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
82*35238bceSAndroid Build Coastguard Worker "{\n"
83*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
84*35238bceSAndroid Build Coastguard Worker "}\n";
85*35238bceSAndroid Build Coastguard Worker static const char *const s_whiteOutputFragmentShader = "${VERSION_DECL}\n"
86*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
87*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
88*35238bceSAndroid Build Coastguard Worker "{\n"
89*35238bceSAndroid Build Coastguard Worker " fragColor = vec4(1.0);\n"
90*35238bceSAndroid Build Coastguard Worker "}\n";
91*35238bceSAndroid Build Coastguard Worker
isBlack(const tcu::RGBA & c)92*35238bceSAndroid Build Coastguard Worker static bool isBlack(const tcu::RGBA &c)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0;
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker class IdentityShaderCase : public TestCase
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker public:
100*35238bceSAndroid Build Coastguard Worker IdentityShaderCase(Context &context, const char *name, const char *description);
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker protected:
103*35238bceSAndroid Build Coastguard Worker std::string getVertexSource(void) const;
104*35238bceSAndroid Build Coastguard Worker std::string getFragmentSource(void) const;
105*35238bceSAndroid Build Coastguard Worker };
106*35238bceSAndroid Build Coastguard Worker
IdentityShaderCase(Context & context,const char * name,const char * description)107*35238bceSAndroid Build Coastguard Worker IdentityShaderCase::IdentityShaderCase(Context &context, const char *name, const char *description)
108*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker }
111*35238bceSAndroid Build Coastguard Worker
getVertexSource(void) const112*35238bceSAndroid Build Coastguard Worker std::string IdentityShaderCase::getVertexSource(void) const
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker std::string source = "${VERSION_DECL}\n"
115*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
116*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_vertex_color;\n"
117*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
118*35238bceSAndroid Build Coastguard Worker "{\n"
119*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
120*35238bceSAndroid Build Coastguard Worker " v_vertex_color = vec4(a_position.x * 0.5 + 0.5, a_position.y * 0.5 + 0.5, 1.0, 0.4);\n"
121*35238bceSAndroid Build Coastguard Worker "}\n";
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
getFragmentSource(void) const126*35238bceSAndroid Build Coastguard Worker std::string IdentityShaderCase::getFragmentSource(void) const
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker std::string source = "${VERSION_DECL}\n"
129*35238bceSAndroid Build Coastguard Worker "in mediump vec4 v_fragment_color;\n"
130*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
131*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
132*35238bceSAndroid Build Coastguard Worker "{\n"
133*35238bceSAndroid Build Coastguard Worker " fragColor = v_fragment_color;\n"
134*35238bceSAndroid Build Coastguard Worker "}\n";
135*35238bceSAndroid Build Coastguard Worker
136*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker
139*35238bceSAndroid Build Coastguard Worker class IdentityGeometryShaderCase : public IdentityShaderCase
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker public:
142*35238bceSAndroid Build Coastguard Worker enum CaseType
143*35238bceSAndroid Build Coastguard Worker {
144*35238bceSAndroid Build Coastguard Worker CASE_TRIANGLES = 0,
145*35238bceSAndroid Build Coastguard Worker CASE_QUADS,
146*35238bceSAndroid Build Coastguard Worker CASE_ISOLINES,
147*35238bceSAndroid Build Coastguard Worker };
148*35238bceSAndroid Build Coastguard Worker
149*35238bceSAndroid Build Coastguard Worker IdentityGeometryShaderCase(Context &context, const char *name, const char *description, CaseType caseType);
150*35238bceSAndroid Build Coastguard Worker ~IdentityGeometryShaderCase(void);
151*35238bceSAndroid Build Coastguard Worker
152*35238bceSAndroid Build Coastguard Worker private:
153*35238bceSAndroid Build Coastguard Worker void init(void);
154*35238bceSAndroid Build Coastguard Worker void deinit(void);
155*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
156*35238bceSAndroid Build Coastguard Worker
157*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(void) const;
158*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(bool geometryActive) const;
159*35238bceSAndroid Build Coastguard Worker std::string getGeometrySource(void) const;
160*35238bceSAndroid Build Coastguard Worker
161*35238bceSAndroid Build Coastguard Worker enum
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 128,
164*35238bceSAndroid Build Coastguard Worker };
165*35238bceSAndroid Build Coastguard Worker
166*35238bceSAndroid Build Coastguard Worker const CaseType m_case;
167*35238bceSAndroid Build Coastguard Worker uint32_t m_patchBuffer;
168*35238bceSAndroid Build Coastguard Worker };
169*35238bceSAndroid Build Coastguard Worker
IdentityGeometryShaderCase(Context & context,const char * name,const char * description,CaseType caseType)170*35238bceSAndroid Build Coastguard Worker IdentityGeometryShaderCase::IdentityGeometryShaderCase(Context &context, const char *name, const char *description,
171*35238bceSAndroid Build Coastguard Worker CaseType caseType)
172*35238bceSAndroid Build Coastguard Worker : IdentityShaderCase(context, name, description)
173*35238bceSAndroid Build Coastguard Worker , m_case(caseType)
174*35238bceSAndroid Build Coastguard Worker , m_patchBuffer(0)
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker
~IdentityGeometryShaderCase(void)178*35238bceSAndroid Build Coastguard Worker IdentityGeometryShaderCase::~IdentityGeometryShaderCase(void)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker deinit();
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker
init(void)183*35238bceSAndroid Build Coastguard Worker void IdentityGeometryShaderCase::init(void)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker // Requirements
186*35238bceSAndroid Build Coastguard Worker const bool supportsES32orGL45 =
187*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
188*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
189*35238bceSAndroid Build Coastguard Worker
190*35238bceSAndroid Build Coastguard Worker if (!supportsES32orGL45 && (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
191*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")))
192*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
193*35238bceSAndroid Build Coastguard Worker
194*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
195*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" +
196*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_SIZE) + " or larger render target.");
197*35238bceSAndroid Build Coastguard Worker
198*35238bceSAndroid Build Coastguard Worker // Log
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
201*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message
202*35238bceSAndroid Build Coastguard Worker << "Testing tessellating shader program output does not change when a passthrough geometry shader is "
203*35238bceSAndroid Build Coastguard Worker "attached.\n"
204*35238bceSAndroid Build Coastguard Worker << "Rendering two images, first with and second without a geometry shader. Expecting similar results.\n"
205*35238bceSAndroid Build Coastguard Worker << "Using additive blending to detect overlap.\n"
206*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
207*35238bceSAndroid Build Coastguard Worker
208*35238bceSAndroid Build Coastguard Worker // Resources
209*35238bceSAndroid Build Coastguard Worker
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 patchBufferData[4] = {
212*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-0.9f, -0.9f, 0.0f, 1.0f),
213*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-0.9f, 0.9f, 0.0f, 1.0f),
214*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.9f, -0.9f, 0.0f, 1.0f),
215*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.9f, 0.9f, 0.0f, 1.0f),
216*35238bceSAndroid Build Coastguard Worker };
217*35238bceSAndroid Build Coastguard Worker
218*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_patchBuffer);
221*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer);
222*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, sizeof(patchBufferData), patchBufferData, GL_STATIC_DRAW);
223*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer");
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker }
226*35238bceSAndroid Build Coastguard Worker
deinit(void)227*35238bceSAndroid Build Coastguard Worker void IdentityGeometryShaderCase::deinit(void)
228*35238bceSAndroid Build Coastguard Worker {
229*35238bceSAndroid Build Coastguard Worker if (m_patchBuffer)
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_patchBuffer);
232*35238bceSAndroid Build Coastguard Worker m_patchBuffer = 0;
233*35238bceSAndroid Build Coastguard Worker }
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker
iterate(void)236*35238bceSAndroid Build Coastguard Worker IdentityGeometryShaderCase::IterateResult IdentityGeometryShaderCase::iterate(void)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker const float innerTessellationLevel = 14.0f;
239*35238bceSAndroid Build Coastguard Worker const float outerTessellationLevel = 14.0f;
240*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
241*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithGeometry(RENDER_SIZE, RENDER_SIZE);
242*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithoutGeometry(RENDER_SIZE, RENDER_SIZE);
243*35238bceSAndroid Build Coastguard Worker
244*35238bceSAndroid Build Coastguard Worker const struct
245*35238bceSAndroid Build Coastguard Worker {
246*35238bceSAndroid Build Coastguard Worker const char *name;
247*35238bceSAndroid Build Coastguard Worker const char *description;
248*35238bceSAndroid Build Coastguard Worker bool containsGeometryShader;
249*35238bceSAndroid Build Coastguard Worker tcu::PixelBufferAccess surfaceAccess;
250*35238bceSAndroid Build Coastguard Worker } renderTargets[] = {
251*35238bceSAndroid Build Coastguard Worker {"RenderWithGeometryShader", "Render with geometry shader", true, resultWithGeometry.getAccess()},
252*35238bceSAndroid Build Coastguard Worker {"RenderWithoutGeometryShader", "Render without geometry shader", false, resultWithoutGeometry.getAccess()},
253*35238bceSAndroid Build Coastguard Worker };
254*35238bceSAndroid Build Coastguard Worker
255*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
256*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
257*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set viewport");
258*35238bceSAndroid Build Coastguard Worker
259*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
260*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_SRC_ALPHA, GL_ONE);
261*35238bceSAndroid Build Coastguard Worker gl.blendEquation(GL_FUNC_ADD);
262*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set blend");
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation level: inner " << innerTessellationLevel << ", outer "
265*35238bceSAndroid Build Coastguard Worker << outerTessellationLevel << tcu::TestLog::EndMessage;
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker // render with and without geometry shader
268*35238bceSAndroid Build Coastguard Worker for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++renderNdx)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), renderTargets[renderNdx].name,
271*35238bceSAndroid Build Coastguard Worker renderTargets[renderNdx].description);
272*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
273*35238bceSAndroid Build Coastguard Worker
274*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource())
275*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(getTessellationControlSource())
276*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(
277*35238bceSAndroid Build Coastguard Worker getTessellationEvaluationSource(renderTargets[renderNdx].containsGeometryShader));
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker if (renderTargets[renderNdx].containsGeometryShader)
280*35238bceSAndroid Build Coastguard Worker sources << glu::GeometrySource(getGeometrySource());
281*35238bceSAndroid Build Coastguard Worker
282*35238bceSAndroid Build Coastguard Worker {
283*35238bceSAndroid Build Coastguard Worker const glu::ShaderProgram program(m_context.getRenderContext(), sources);
284*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
285*35238bceSAndroid Build Coastguard Worker const int posLocation = gl.getAttribLocation(program.getProgram(), "a_position");
286*35238bceSAndroid Build Coastguard Worker const int innerTessellationLoc = gl.getUniformLocation(program.getProgram(), "u_innerTessellationLevel");
287*35238bceSAndroid Build Coastguard Worker const int outerTessellationLoc = gl.getUniformLocation(program.getProgram(), "u_outerTessellationLevel");
288*35238bceSAndroid Build Coastguard Worker
289*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << program;
290*35238bceSAndroid Build Coastguard Worker
291*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
292*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
293*35238bceSAndroid Build Coastguard Worker if (posLocation == -1)
294*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("a_position location was -1");
295*35238bceSAndroid Build Coastguard Worker if (outerTessellationLoc == -1)
296*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("u_outerTessellationLevel location was -1");
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
299*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer);
300*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
301*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
302*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs");
303*35238bceSAndroid Build Coastguard Worker
304*35238bceSAndroid Build Coastguard Worker gl.useProgram(program.getProgram());
305*35238bceSAndroid Build Coastguard Worker gl.uniform1f(outerTessellationLoc, outerTessellationLevel);
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker if (innerTessellationLoc == -1)
308*35238bceSAndroid Build Coastguard Worker gl.uniform1f(innerTessellationLoc, innerTessellationLevel);
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, (m_case == CASE_TRIANGLES) ? (3) : (4));
313*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
314*35238bceSAndroid Build Coastguard Worker
315*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
316*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 4);
319*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches");
320*35238bceSAndroid Build Coastguard Worker
321*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, renderTargets[renderNdx].surfaceAccess);
322*35238bceSAndroid Build Coastguard Worker }
323*35238bceSAndroid Build Coastguard Worker }
324*35238bceSAndroid Build Coastguard Worker
325*35238bceSAndroid Build Coastguard Worker if (tcu::intThresholdPositionDeviationCompare(m_testCtx.getLog(), "ImageCompare", "Image comparison",
326*35238bceSAndroid Build Coastguard Worker resultWithoutGeometry.getAccess(), resultWithGeometry.getAccess(),
327*35238bceSAndroid Build Coastguard Worker tcu::UVec4(8, 8, 8, 255), tcu::IVec3(1, 1, 0), true,
328*35238bceSAndroid Build Coastguard Worker tcu::COMPARE_LOG_RESULT))
329*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
330*35238bceSAndroid Build Coastguard Worker else
331*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
332*35238bceSAndroid Build Coastguard Worker
333*35238bceSAndroid Build Coastguard Worker return STOP;
334*35238bceSAndroid Build Coastguard Worker }
335*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(void) const336*35238bceSAndroid Build Coastguard Worker std::string IdentityGeometryShaderCase::getTessellationControlSource(void) const
337*35238bceSAndroid Build Coastguard Worker {
338*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
341*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
342*35238bceSAndroid Build Coastguard Worker "layout(vertices = 4) out;\n"
343*35238bceSAndroid Build Coastguard Worker "\n"
344*35238bceSAndroid Build Coastguard Worker "uniform highp float u_innerTessellationLevel;\n"
345*35238bceSAndroid Build Coastguard Worker "uniform highp float u_outerTessellationLevel;\n"
346*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_vertex_color[];\n"
347*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_patch_color[];\n"
348*35238bceSAndroid Build Coastguard Worker "\n"
349*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
350*35238bceSAndroid Build Coastguard Worker "{\n"
351*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
352*35238bceSAndroid Build Coastguard Worker " v_patch_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
353*35238bceSAndroid Build Coastguard Worker "\n";
354*35238bceSAndroid Build Coastguard Worker
355*35238bceSAndroid Build Coastguard Worker if (m_case == CASE_TRIANGLES)
356*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n"
357*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n"
358*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = u_outerTessellationLevel;\n"
359*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = u_innerTessellationLevel;\n";
360*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_QUADS)
361*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n"
362*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n"
363*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = u_outerTessellationLevel;\n"
364*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = u_outerTessellationLevel;\n"
365*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = u_innerTessellationLevel;\n"
366*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = u_innerTessellationLevel;\n";
367*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_ISOLINES)
368*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n"
369*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n";
370*35238bceSAndroid Build Coastguard Worker else
371*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
372*35238bceSAndroid Build Coastguard Worker
373*35238bceSAndroid Build Coastguard Worker buf << "}\n";
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
376*35238bceSAndroid Build Coastguard Worker }
377*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(bool geometryActive) const378*35238bceSAndroid Build Coastguard Worker std::string IdentityGeometryShaderCase::getTessellationEvaluationSource(bool geometryActive) const
379*35238bceSAndroid Build Coastguard Worker {
380*35238bceSAndroid Build Coastguard Worker const char *const colorOutputName = ((geometryActive) ? ("v_evaluated_color") : ("v_fragment_color"));
381*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
382*35238bceSAndroid Build Coastguard Worker
383*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
384*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
385*35238bceSAndroid Build Coastguard Worker "layout("
386*35238bceSAndroid Build Coastguard Worker << ((m_case == CASE_TRIANGLES) ? ("triangles") :
387*35238bceSAndroid Build Coastguard Worker (m_case == CASE_QUADS) ? ("quads") :
388*35238bceSAndroid Build Coastguard Worker ("isolines"))
389*35238bceSAndroid Build Coastguard Worker << ") in;\n"
390*35238bceSAndroid Build Coastguard Worker "\n"
391*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_patch_color[];\n"
392*35238bceSAndroid Build Coastguard Worker "out highp vec4 "
393*35238bceSAndroid Build Coastguard Worker << colorOutputName
394*35238bceSAndroid Build Coastguard Worker << ";\n"
395*35238bceSAndroid Build Coastguard Worker "\n"
396*35238bceSAndroid Build Coastguard Worker "// note: No need to use precise gl_Position since we do not require gapless geometry\n"
397*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
398*35238bceSAndroid Build Coastguard Worker "{\n";
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker if (m_case == CASE_TRIANGLES)
401*35238bceSAndroid Build Coastguard Worker buf << " vec3 weights = vec3(pow(gl_TessCoord.x, 1.3), pow(gl_TessCoord.y, 1.3), pow(gl_TessCoord.z, "
402*35238bceSAndroid Build Coastguard Worker "1.3));\n"
403*35238bceSAndroid Build Coastguard Worker " vec3 cweights = gl_TessCoord;\n"
404*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(weights.x * gl_in[0].gl_Position.xyz + weights.y * gl_in[1].gl_Position.xyz + "
405*35238bceSAndroid Build Coastguard Worker "weights.z * gl_in[2].gl_Position.xyz, 1.0);\n"
406*35238bceSAndroid Build Coastguard Worker " "
407*35238bceSAndroid Build Coastguard Worker << colorOutputName
408*35238bceSAndroid Build Coastguard Worker << " = cweights.x * v_patch_color[0] + cweights.y * v_patch_color[1] + cweights.z * v_patch_color[2];\n";
409*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_QUADS || m_case == CASE_ISOLINES)
410*35238bceSAndroid Build Coastguard Worker buf << " vec2 normalizedCoord = (gl_TessCoord.xy * 2.0 - vec2(1.0));\n"
411*35238bceSAndroid Build Coastguard Worker " vec2 normalizedWeights = normalizedCoord * (vec2(1.0) - 0.3 * cos(normalizedCoord.yx * 1.57));\n"
412*35238bceSAndroid Build Coastguard Worker " vec2 weights = normalizedWeights * 0.5 + vec2(0.5);\n"
413*35238bceSAndroid Build Coastguard Worker " vec2 cweights = gl_TessCoord.xy;\n"
414*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(mix(gl_in[0].gl_Position, gl_in[1].gl_Position, weights.y), "
415*35238bceSAndroid Build Coastguard Worker "mix(gl_in[2].gl_Position, gl_in[3].gl_Position, weights.y), weights.x);\n"
416*35238bceSAndroid Build Coastguard Worker " "
417*35238bceSAndroid Build Coastguard Worker << colorOutputName
418*35238bceSAndroid Build Coastguard Worker << " = mix(mix(v_patch_color[0], v_patch_color[1], cweights.y), mix(v_patch_color[2], v_patch_color[3], "
419*35238bceSAndroid Build Coastguard Worker "cweights.y), cweights.x);\n";
420*35238bceSAndroid Build Coastguard Worker else
421*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
422*35238bceSAndroid Build Coastguard Worker
423*35238bceSAndroid Build Coastguard Worker buf << "}\n";
424*35238bceSAndroid Build Coastguard Worker
425*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
426*35238bceSAndroid Build Coastguard Worker }
427*35238bceSAndroid Build Coastguard Worker
getGeometrySource(void) const428*35238bceSAndroid Build Coastguard Worker std::string IdentityGeometryShaderCase::getGeometrySource(void) const
429*35238bceSAndroid Build Coastguard Worker {
430*35238bceSAndroid Build Coastguard Worker const char *const geometryInputPrimitive = (m_case == CASE_ISOLINES) ? ("lines") : ("triangles");
431*35238bceSAndroid Build Coastguard Worker const char *const geometryOutputPrimitive = (m_case == CASE_ISOLINES) ? ("line_strip") : ("triangle_strip");
432*35238bceSAndroid Build Coastguard Worker const int numEmitVertices = (m_case == CASE_ISOLINES) ? (2) : (3);
433*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
434*35238bceSAndroid Build Coastguard Worker
435*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
436*35238bceSAndroid Build Coastguard Worker "${EXTENSION_GEOMETRY_SHADER}"
437*35238bceSAndroid Build Coastguard Worker "layout("
438*35238bceSAndroid Build Coastguard Worker << geometryInputPrimitive
439*35238bceSAndroid Build Coastguard Worker << ") in;\n"
440*35238bceSAndroid Build Coastguard Worker "layout("
441*35238bceSAndroid Build Coastguard Worker << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices
442*35238bceSAndroid Build Coastguard Worker << ") out;\n"
443*35238bceSAndroid Build Coastguard Worker "\n"
444*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_evaluated_color[];\n"
445*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_fragment_color;\n"
446*35238bceSAndroid Build Coastguard Worker "\n"
447*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
448*35238bceSAndroid Build Coastguard Worker "{\n"
449*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < gl_in.length(); ++ndx)\n"
450*35238bceSAndroid Build Coastguard Worker " {\n"
451*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position;\n"
452*35238bceSAndroid Build Coastguard Worker " v_fragment_color = v_evaluated_color[ndx];\n"
453*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
454*35238bceSAndroid Build Coastguard Worker " }\n"
455*35238bceSAndroid Build Coastguard Worker "}\n";
456*35238bceSAndroid Build Coastguard Worker
457*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker
460*35238bceSAndroid Build Coastguard Worker class IdentityTessellationShaderCase : public IdentityShaderCase
461*35238bceSAndroid Build Coastguard Worker {
462*35238bceSAndroid Build Coastguard Worker public:
463*35238bceSAndroid Build Coastguard Worker enum CaseType
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker CASE_TRIANGLES = 0,
466*35238bceSAndroid Build Coastguard Worker CASE_ISOLINES,
467*35238bceSAndroid Build Coastguard Worker };
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker IdentityTessellationShaderCase(Context &context, const char *name, const char *description, CaseType caseType);
470*35238bceSAndroid Build Coastguard Worker ~IdentityTessellationShaderCase(void);
471*35238bceSAndroid Build Coastguard Worker
472*35238bceSAndroid Build Coastguard Worker private:
473*35238bceSAndroid Build Coastguard Worker void init(void);
474*35238bceSAndroid Build Coastguard Worker void deinit(void);
475*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
476*35238bceSAndroid Build Coastguard Worker
477*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(void) const;
478*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(void) const;
479*35238bceSAndroid Build Coastguard Worker std::string getGeometrySource(bool tessellationActive) const;
480*35238bceSAndroid Build Coastguard Worker
481*35238bceSAndroid Build Coastguard Worker enum
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 256,
484*35238bceSAndroid Build Coastguard Worker };
485*35238bceSAndroid Build Coastguard Worker
486*35238bceSAndroid Build Coastguard Worker const CaseType m_case;
487*35238bceSAndroid Build Coastguard Worker uint32_t m_dataBuffer;
488*35238bceSAndroid Build Coastguard Worker };
489*35238bceSAndroid Build Coastguard Worker
IdentityTessellationShaderCase(Context & context,const char * name,const char * description,CaseType caseType)490*35238bceSAndroid Build Coastguard Worker IdentityTessellationShaderCase::IdentityTessellationShaderCase(Context &context, const char *name,
491*35238bceSAndroid Build Coastguard Worker const char *description, CaseType caseType)
492*35238bceSAndroid Build Coastguard Worker : IdentityShaderCase(context, name, description)
493*35238bceSAndroid Build Coastguard Worker , m_case(caseType)
494*35238bceSAndroid Build Coastguard Worker , m_dataBuffer(0)
495*35238bceSAndroid Build Coastguard Worker {
496*35238bceSAndroid Build Coastguard Worker }
497*35238bceSAndroid Build Coastguard Worker
~IdentityTessellationShaderCase(void)498*35238bceSAndroid Build Coastguard Worker IdentityTessellationShaderCase::~IdentityTessellationShaderCase(void)
499*35238bceSAndroid Build Coastguard Worker {
500*35238bceSAndroid Build Coastguard Worker deinit();
501*35238bceSAndroid Build Coastguard Worker }
502*35238bceSAndroid Build Coastguard Worker
init(void)503*35238bceSAndroid Build Coastguard Worker void IdentityTessellationShaderCase::init(void)
504*35238bceSAndroid Build Coastguard Worker {
505*35238bceSAndroid Build Coastguard Worker // Requirements
506*35238bceSAndroid Build Coastguard Worker const bool supportsES32orGL45 =
507*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
508*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
509*35238bceSAndroid Build Coastguard Worker
510*35238bceSAndroid Build Coastguard Worker if (!supportsES32orGL45 && (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
511*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")))
512*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
515*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" +
516*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_SIZE) + " or larger render target.");
517*35238bceSAndroid Build Coastguard Worker
518*35238bceSAndroid Build Coastguard Worker // Log
519*35238bceSAndroid Build Coastguard Worker
520*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
521*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message
522*35238bceSAndroid Build Coastguard Worker << "Testing geometry shading shader program output does not change when a passthrough tessellation shader is "
523*35238bceSAndroid Build Coastguard Worker "attached.\n"
524*35238bceSAndroid Build Coastguard Worker << "Rendering two images, first with and second without a tessellation shader. Expecting similar results.\n"
525*35238bceSAndroid Build Coastguard Worker << "Using additive blending to detect overlap.\n"
526*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker // Resources
529*35238bceSAndroid Build Coastguard Worker
530*35238bceSAndroid Build Coastguard Worker {
531*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 pointData[] = {
532*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-0.4f, 0.4f, 0.0f, 1.0f),
533*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.0f, -0.5f, 0.0f, 1.0f),
534*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.4f, 0.4f, 0.0f, 1.0f),
535*35238bceSAndroid Build Coastguard Worker };
536*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
537*35238bceSAndroid Build Coastguard Worker
538*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_dataBuffer);
539*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBuffer);
540*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, sizeof(pointData), pointData, GL_STATIC_DRAW);
541*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer");
542*35238bceSAndroid Build Coastguard Worker }
543*35238bceSAndroid Build Coastguard Worker }
544*35238bceSAndroid Build Coastguard Worker
deinit(void)545*35238bceSAndroid Build Coastguard Worker void IdentityTessellationShaderCase::deinit(void)
546*35238bceSAndroid Build Coastguard Worker {
547*35238bceSAndroid Build Coastguard Worker if (m_dataBuffer)
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dataBuffer);
550*35238bceSAndroid Build Coastguard Worker m_dataBuffer = 0;
551*35238bceSAndroid Build Coastguard Worker }
552*35238bceSAndroid Build Coastguard Worker }
553*35238bceSAndroid Build Coastguard Worker
iterate(void)554*35238bceSAndroid Build Coastguard Worker IdentityTessellationShaderCase::IterateResult IdentityTessellationShaderCase::iterate(void)
555*35238bceSAndroid Build Coastguard Worker {
556*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
557*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithTessellation(RENDER_SIZE, RENDER_SIZE);
558*35238bceSAndroid Build Coastguard Worker tcu::Surface resultWithoutTessellation(RENDER_SIZE, RENDER_SIZE);
559*35238bceSAndroid Build Coastguard Worker const int numPrimitiveVertices = (m_case == CASE_TRIANGLES) ? (3) : (2);
560*35238bceSAndroid Build Coastguard Worker
561*35238bceSAndroid Build Coastguard Worker const struct
562*35238bceSAndroid Build Coastguard Worker {
563*35238bceSAndroid Build Coastguard Worker const char *name;
564*35238bceSAndroid Build Coastguard Worker const char *description;
565*35238bceSAndroid Build Coastguard Worker bool containsTessellationShaders;
566*35238bceSAndroid Build Coastguard Worker tcu::PixelBufferAccess surfaceAccess;
567*35238bceSAndroid Build Coastguard Worker } renderTargets[] = {
568*35238bceSAndroid Build Coastguard Worker {"RenderWithTessellationShader", "Render with tessellation shader", true, resultWithTessellation.getAccess()},
569*35238bceSAndroid Build Coastguard Worker {"RenderWithoutTessellationShader", "Render without tessellation shader", false,
570*35238bceSAndroid Build Coastguard Worker resultWithoutTessellation.getAccess()},
571*35238bceSAndroid Build Coastguard Worker };
572*35238bceSAndroid Build Coastguard Worker
573*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
574*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
575*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set viewport");
576*35238bceSAndroid Build Coastguard Worker
577*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
578*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_SRC_ALPHA, GL_ONE);
579*35238bceSAndroid Build Coastguard Worker gl.blendEquation(GL_FUNC_ADD);
580*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set blend");
581*35238bceSAndroid Build Coastguard Worker
582*35238bceSAndroid Build Coastguard Worker // render with and without tessellation shader
583*35238bceSAndroid Build Coastguard Worker for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++renderNdx)
584*35238bceSAndroid Build Coastguard Worker {
585*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), renderTargets[renderNdx].name,
586*35238bceSAndroid Build Coastguard Worker renderTargets[renderNdx].description);
587*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
588*35238bceSAndroid Build Coastguard Worker
589*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource())
590*35238bceSAndroid Build Coastguard Worker << glu::GeometrySource(getGeometrySource(renderTargets[renderNdx].containsTessellationShaders));
591*35238bceSAndroid Build Coastguard Worker
592*35238bceSAndroid Build Coastguard Worker if (renderTargets[renderNdx].containsTessellationShaders)
593*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(getTessellationControlSource())
594*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource());
595*35238bceSAndroid Build Coastguard Worker
596*35238bceSAndroid Build Coastguard Worker {
597*35238bceSAndroid Build Coastguard Worker const glu::ShaderProgram program(m_context.getRenderContext(), sources);
598*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
599*35238bceSAndroid Build Coastguard Worker const int posLocation = gl.getAttribLocation(program.getProgram(), "a_position");
600*35238bceSAndroid Build Coastguard Worker
601*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << program;
602*35238bceSAndroid Build Coastguard Worker
603*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
604*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
605*35238bceSAndroid Build Coastguard Worker if (posLocation == -1)
606*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("a_position location was -1");
607*35238bceSAndroid Build Coastguard Worker
608*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
609*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBuffer);
610*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
611*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
612*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs");
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker gl.useProgram(program.getProgram());
615*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
616*35238bceSAndroid Build Coastguard Worker
617*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
618*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
619*35238bceSAndroid Build Coastguard Worker
620*35238bceSAndroid Build Coastguard Worker if (renderTargets[renderNdx].containsTessellationShaders)
621*35238bceSAndroid Build Coastguard Worker {
622*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, numPrimitiveVertices);
623*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
624*35238bceSAndroid Build Coastguard Worker
625*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, numPrimitiveVertices);
626*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches");
627*35238bceSAndroid Build Coastguard Worker }
628*35238bceSAndroid Build Coastguard Worker else
629*35238bceSAndroid Build Coastguard Worker {
630*35238bceSAndroid Build Coastguard Worker gl.drawArrays((m_case == CASE_TRIANGLES) ? (GL_TRIANGLES) : (GL_LINES), 0, numPrimitiveVertices);
631*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw primitives");
632*35238bceSAndroid Build Coastguard Worker }
633*35238bceSAndroid Build Coastguard Worker
634*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, renderTargets[renderNdx].surfaceAccess);
635*35238bceSAndroid Build Coastguard Worker }
636*35238bceSAndroid Build Coastguard Worker }
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker // compare
639*35238bceSAndroid Build Coastguard Worker {
640*35238bceSAndroid Build Coastguard Worker bool imageOk;
641*35238bceSAndroid Build Coastguard Worker
642*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getNumSamples() > 1)
643*35238bceSAndroid Build Coastguard Worker imageOk = tcu::fuzzyCompare(m_testCtx.getLog(), "ImageCompare", "Image comparison",
644*35238bceSAndroid Build Coastguard Worker resultWithoutTessellation.getAccess(), resultWithTessellation.getAccess(),
645*35238bceSAndroid Build Coastguard Worker 0.03f, tcu::COMPARE_LOG_RESULT);
646*35238bceSAndroid Build Coastguard Worker else
647*35238bceSAndroid Build Coastguard Worker imageOk = tcu::intThresholdPositionDeviationCompare(
648*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog(), "ImageCompare", "Image comparison", resultWithoutTessellation.getAccess(),
649*35238bceSAndroid Build Coastguard Worker resultWithTessellation.getAccess(), tcu::UVec4(8, 8, 8, 255), //!< threshold
650*35238bceSAndroid Build Coastguard Worker tcu::IVec3(1, 1, 0), //!< 3x3 search kernel
651*35238bceSAndroid Build Coastguard Worker true, //!< fragments may end up over the viewport, just ignore them
652*35238bceSAndroid Build Coastguard Worker tcu::COMPARE_LOG_RESULT);
653*35238bceSAndroid Build Coastguard Worker
654*35238bceSAndroid Build Coastguard Worker if (imageOk)
655*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
656*35238bceSAndroid Build Coastguard Worker else
657*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
658*35238bceSAndroid Build Coastguard Worker }
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker return STOP;
661*35238bceSAndroid Build Coastguard Worker }
662*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(void) const663*35238bceSAndroid Build Coastguard Worker std::string IdentityTessellationShaderCase::getTessellationControlSource(void) const
664*35238bceSAndroid Build Coastguard Worker {
665*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
666*35238bceSAndroid Build Coastguard Worker
667*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
668*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
669*35238bceSAndroid Build Coastguard Worker "layout(vertices = "
670*35238bceSAndroid Build Coastguard Worker << ((m_case == CASE_TRIANGLES) ? (3) : (2))
671*35238bceSAndroid Build Coastguard Worker << ") out;\n"
672*35238bceSAndroid Build Coastguard Worker "\n"
673*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_vertex_color[];\n"
674*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_control_color[];\n"
675*35238bceSAndroid Build Coastguard Worker "\n"
676*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
677*35238bceSAndroid Build Coastguard Worker "{\n"
678*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
679*35238bceSAndroid Build Coastguard Worker " v_control_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
680*35238bceSAndroid Build Coastguard Worker "\n";
681*35238bceSAndroid Build Coastguard Worker
682*35238bceSAndroid Build Coastguard Worker if (m_case == CASE_TRIANGLES)
683*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = 1.0;\n"
684*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 1.0;\n"
685*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 1.0;\n"
686*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 1.0;\n";
687*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_ISOLINES)
688*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = 1.0;\n"
689*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 1.0;\n";
690*35238bceSAndroid Build Coastguard Worker else
691*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
692*35238bceSAndroid Build Coastguard Worker
693*35238bceSAndroid Build Coastguard Worker buf << "}\n";
694*35238bceSAndroid Build Coastguard Worker
695*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
696*35238bceSAndroid Build Coastguard Worker }
697*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(void) const698*35238bceSAndroid Build Coastguard Worker std::string IdentityTessellationShaderCase::getTessellationEvaluationSource(void) const
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
701*35238bceSAndroid Build Coastguard Worker
702*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
703*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
704*35238bceSAndroid Build Coastguard Worker "layout("
705*35238bceSAndroid Build Coastguard Worker << ((m_case == CASE_TRIANGLES) ? ("triangles") : ("isolines"))
706*35238bceSAndroid Build Coastguard Worker << ") in;\n"
707*35238bceSAndroid Build Coastguard Worker "\n"
708*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_control_color[];\n"
709*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_evaluated_color;\n"
710*35238bceSAndroid Build Coastguard Worker "\n"
711*35238bceSAndroid Build Coastguard Worker "// note: No need to use precise gl_Position since we do not require gapless geometry\n"
712*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
713*35238bceSAndroid Build Coastguard Worker "{\n";
714*35238bceSAndroid Build Coastguard Worker
715*35238bceSAndroid Build Coastguard Worker if (m_case == CASE_TRIANGLES)
716*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + "
717*35238bceSAndroid Build Coastguard Worker "gl_TessCoord.z * gl_in[2].gl_Position;\n"
718*35238bceSAndroid Build Coastguard Worker " v_evaluated_color = gl_TessCoord.x * v_control_color[0] + gl_TessCoord.y * v_control_color[1] + "
719*35238bceSAndroid Build Coastguard Worker "gl_TessCoord.z * v_control_color[2];\n";
720*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_ISOLINES)
721*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
722*35238bceSAndroid Build Coastguard Worker " v_evaluated_color = mix(v_control_color[0], v_control_color[1], gl_TessCoord.x);\n";
723*35238bceSAndroid Build Coastguard Worker else
724*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker buf << "}\n";
727*35238bceSAndroid Build Coastguard Worker
728*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
729*35238bceSAndroid Build Coastguard Worker }
730*35238bceSAndroid Build Coastguard Worker
getGeometrySource(bool tessellationActive) const731*35238bceSAndroid Build Coastguard Worker std::string IdentityTessellationShaderCase::getGeometrySource(bool tessellationActive) const
732*35238bceSAndroid Build Coastguard Worker {
733*35238bceSAndroid Build Coastguard Worker const char *const colorSourceName = (tessellationActive) ? ("v_evaluated_color") : ("v_vertex_color");
734*35238bceSAndroid Build Coastguard Worker const char *const geometryInputPrimitive = (m_case == CASE_ISOLINES) ? ("lines") : ("triangles");
735*35238bceSAndroid Build Coastguard Worker const char *const geometryOutputPrimitive = (m_case == CASE_ISOLINES) ? ("line_strip") : ("triangle_strip");
736*35238bceSAndroid Build Coastguard Worker const int numEmitVertices = (m_case == CASE_ISOLINES) ? (11) : (8);
737*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
738*35238bceSAndroid Build Coastguard Worker
739*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
740*35238bceSAndroid Build Coastguard Worker "${EXTENSION_GEOMETRY_SHADER}"
741*35238bceSAndroid Build Coastguard Worker "layout("
742*35238bceSAndroid Build Coastguard Worker << geometryInputPrimitive
743*35238bceSAndroid Build Coastguard Worker << ") in;\n"
744*35238bceSAndroid Build Coastguard Worker "layout("
745*35238bceSAndroid Build Coastguard Worker << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices
746*35238bceSAndroid Build Coastguard Worker << ") out;\n"
747*35238bceSAndroid Build Coastguard Worker "\n"
748*35238bceSAndroid Build Coastguard Worker "in highp vec4 "
749*35238bceSAndroid Build Coastguard Worker << colorSourceName
750*35238bceSAndroid Build Coastguard Worker << "[];\n"
751*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_fragment_color;\n"
752*35238bceSAndroid Build Coastguard Worker "\n"
753*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
754*35238bceSAndroid Build Coastguard Worker "{\n";
755*35238bceSAndroid Build Coastguard Worker
756*35238bceSAndroid Build Coastguard Worker if (m_case == CASE_TRIANGLES)
757*35238bceSAndroid Build Coastguard Worker {
758*35238bceSAndroid Build Coastguard Worker buf << " vec4 centerPos = (gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position) / 3.0f;\n"
759*35238bceSAndroid Build Coastguard Worker "\n"
760*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < 4; ++ndx)\n"
761*35238bceSAndroid Build Coastguard Worker " {\n"
762*35238bceSAndroid Build Coastguard Worker " gl_Position = centerPos + (centerPos - gl_in[ndx % 3].gl_Position);\n"
763*35238bceSAndroid Build Coastguard Worker " v_fragment_color = "
764*35238bceSAndroid Build Coastguard Worker << colorSourceName
765*35238bceSAndroid Build Coastguard Worker << "[ndx % 3];\n"
766*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
767*35238bceSAndroid Build Coastguard Worker "\n"
768*35238bceSAndroid Build Coastguard Worker " gl_Position = centerPos + 0.7 * (centerPos - gl_in[ndx % 3].gl_Position);\n"
769*35238bceSAndroid Build Coastguard Worker " v_fragment_color = "
770*35238bceSAndroid Build Coastguard Worker << colorSourceName
771*35238bceSAndroid Build Coastguard Worker << "[ndx % 3];\n"
772*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
773*35238bceSAndroid Build Coastguard Worker " }\n";
774*35238bceSAndroid Build Coastguard Worker }
775*35238bceSAndroid Build Coastguard Worker else if (m_case == CASE_ISOLINES)
776*35238bceSAndroid Build Coastguard Worker {
777*35238bceSAndroid Build Coastguard Worker buf << " vec4 mdir = vec4(gl_in[0].gl_Position.y - gl_in[1].gl_Position.y, gl_in[1].gl_Position.x - "
778*35238bceSAndroid Build Coastguard Worker "gl_in[0].gl_Position.x, 0.0, 0.0);\n"
779*35238bceSAndroid Build Coastguard Worker " for (int i = 0; i <= 10; ++i)\n"
780*35238bceSAndroid Build Coastguard Worker " {\n"
781*35238bceSAndroid Build Coastguard Worker " float xweight = cos(float(i) / 10.0 * 6.28) * 0.5 + 0.5;\n"
782*35238bceSAndroid Build Coastguard Worker " float mweight = sin(float(i) / 10.0 * 6.28) * 0.1 + 0.1;\n"
783*35238bceSAndroid Build Coastguard Worker " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, xweight) + mweight * mdir;\n"
784*35238bceSAndroid Build Coastguard Worker " v_fragment_color = mix("
785*35238bceSAndroid Build Coastguard Worker << colorSourceName << "[0], " << colorSourceName
786*35238bceSAndroid Build Coastguard Worker << "[1], xweight);\n"
787*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
788*35238bceSAndroid Build Coastguard Worker " }\n";
789*35238bceSAndroid Build Coastguard Worker }
790*35238bceSAndroid Build Coastguard Worker else
791*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
792*35238bceSAndroid Build Coastguard Worker
793*35238bceSAndroid Build Coastguard Worker buf << "}\n";
794*35238bceSAndroid Build Coastguard Worker
795*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
796*35238bceSAndroid Build Coastguard Worker }
797*35238bceSAndroid Build Coastguard Worker
798*35238bceSAndroid Build Coastguard Worker class FeedbackPrimitiveTypeCase : public TestCase
799*35238bceSAndroid Build Coastguard Worker {
800*35238bceSAndroid Build Coastguard Worker public:
801*35238bceSAndroid Build Coastguard Worker enum TessellationOutputType
802*35238bceSAndroid Build Coastguard Worker {
803*35238bceSAndroid Build Coastguard Worker TESSELLATION_OUT_TRIANGLES = 0,
804*35238bceSAndroid Build Coastguard Worker TESSELLATION_OUT_QUADS,
805*35238bceSAndroid Build Coastguard Worker TESSELLATION_OUT_ISOLINES,
806*35238bceSAndroid Build Coastguard Worker
807*35238bceSAndroid Build Coastguard Worker TESSELLATION_OUT_LAST
808*35238bceSAndroid Build Coastguard Worker };
809*35238bceSAndroid Build Coastguard Worker enum TessellationPointMode
810*35238bceSAndroid Build Coastguard Worker {
811*35238bceSAndroid Build Coastguard Worker TESSELLATION_POINTMODE_OFF = 0,
812*35238bceSAndroid Build Coastguard Worker TESSELLATION_POINTMODE_ON,
813*35238bceSAndroid Build Coastguard Worker
814*35238bceSAndroid Build Coastguard Worker TESSELLATION_POINTMODE_LAST
815*35238bceSAndroid Build Coastguard Worker };
816*35238bceSAndroid Build Coastguard Worker enum GeometryOutputType
817*35238bceSAndroid Build Coastguard Worker {
818*35238bceSAndroid Build Coastguard Worker GEOMETRY_OUTPUT_POINTS = 0,
819*35238bceSAndroid Build Coastguard Worker GEOMETRY_OUTPUT_LINES,
820*35238bceSAndroid Build Coastguard Worker GEOMETRY_OUTPUT_TRIANGLES,
821*35238bceSAndroid Build Coastguard Worker
822*35238bceSAndroid Build Coastguard Worker GEOMETRY_OUTPUT_LAST
823*35238bceSAndroid Build Coastguard Worker };
824*35238bceSAndroid Build Coastguard Worker
825*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase(Context &context, const char *name, const char *description,
826*35238bceSAndroid Build Coastguard Worker TessellationOutputType tessellationOutput, TessellationPointMode tessellationPointMode,
827*35238bceSAndroid Build Coastguard Worker GeometryOutputType geometryOutputType);
828*35238bceSAndroid Build Coastguard Worker ~FeedbackPrimitiveTypeCase(void);
829*35238bceSAndroid Build Coastguard Worker
830*35238bceSAndroid Build Coastguard Worker private:
831*35238bceSAndroid Build Coastguard Worker void init(void);
832*35238bceSAndroid Build Coastguard Worker void deinit(void);
833*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
834*35238bceSAndroid Build Coastguard Worker
835*35238bceSAndroid Build Coastguard Worker void renderWithFeedback(tcu::Surface &dst);
836*35238bceSAndroid Build Coastguard Worker void renderWithoutFeedback(tcu::Surface &dst);
837*35238bceSAndroid Build Coastguard Worker void verifyFeedbackResults(const std::vector<tcu::Vec4> &feedbackResult);
838*35238bceSAndroid Build Coastguard Worker void verifyRenderedImage(const tcu::Surface &image, const std::vector<tcu::Vec4> &vertices);
839*35238bceSAndroid Build Coastguard Worker
840*35238bceSAndroid Build Coastguard Worker void genTransformFeedback(void);
841*35238bceSAndroid Build Coastguard Worker int getNumGeneratedElementsPerPrimitive(void) const;
842*35238bceSAndroid Build Coastguard Worker int getNumGeneratedPrimitives(void) const;
843*35238bceSAndroid Build Coastguard Worker int getNumTessellatedPrimitives(void) const;
844*35238bceSAndroid Build Coastguard Worker int getGeometryAmplification(void) const;
845*35238bceSAndroid Build Coastguard Worker
846*35238bceSAndroid Build Coastguard Worker std::string getVertexSource(void) const;
847*35238bceSAndroid Build Coastguard Worker std::string getFragmentSource(void) const;
848*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(void) const;
849*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(void) const;
850*35238bceSAndroid Build Coastguard Worker std::string getGeometrySource(void) const;
851*35238bceSAndroid Build Coastguard Worker
852*35238bceSAndroid Build Coastguard Worker static const char *getTessellationOutputDescription(TessellationOutputType tessellationOutput,
853*35238bceSAndroid Build Coastguard Worker TessellationPointMode tessellationPointMode);
854*35238bceSAndroid Build Coastguard Worker static const char *getGeometryInputDescription(TessellationOutputType tessellationOutput,
855*35238bceSAndroid Build Coastguard Worker TessellationPointMode tessellationPointMode);
856*35238bceSAndroid Build Coastguard Worker static const char *getGeometryOutputDescription(GeometryOutputType geometryOutput);
857*35238bceSAndroid Build Coastguard Worker glw::GLenum getOutputPrimitiveGLType(void) const;
858*35238bceSAndroid Build Coastguard Worker
859*35238bceSAndroid Build Coastguard Worker enum
860*35238bceSAndroid Build Coastguard Worker {
861*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 128,
862*35238bceSAndroid Build Coastguard Worker };
863*35238bceSAndroid Build Coastguard Worker
864*35238bceSAndroid Build Coastguard Worker const TessellationOutputType m_tessellationOutput;
865*35238bceSAndroid Build Coastguard Worker const TessellationPointMode m_tessellationPointMode;
866*35238bceSAndroid Build Coastguard Worker const GeometryOutputType m_geometryOutputType;
867*35238bceSAndroid Build Coastguard Worker
868*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_feedbackProgram;
869*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_nonFeedbackProgram;
870*35238bceSAndroid Build Coastguard Worker uint32_t m_patchBuffer;
871*35238bceSAndroid Build Coastguard Worker uint32_t m_feedbackID;
872*35238bceSAndroid Build Coastguard Worker uint32_t m_feedbackBuffer;
873*35238bceSAndroid Build Coastguard Worker };
874*35238bceSAndroid Build Coastguard Worker
FeedbackPrimitiveTypeCase(Context & context,const char * name,const char * description,TessellationOutputType tessellationOutput,TessellationPointMode tessellationPointMode,GeometryOutputType geometryOutputType)875*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::FeedbackPrimitiveTypeCase(Context &context, const char *name, const char *description,
876*35238bceSAndroid Build Coastguard Worker TessellationOutputType tessellationOutput,
877*35238bceSAndroid Build Coastguard Worker TessellationPointMode tessellationPointMode,
878*35238bceSAndroid Build Coastguard Worker GeometryOutputType geometryOutputType)
879*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
880*35238bceSAndroid Build Coastguard Worker , m_tessellationOutput(tessellationOutput)
881*35238bceSAndroid Build Coastguard Worker , m_tessellationPointMode(tessellationPointMode)
882*35238bceSAndroid Build Coastguard Worker , m_geometryOutputType(geometryOutputType)
883*35238bceSAndroid Build Coastguard Worker , m_feedbackProgram(DE_NULL)
884*35238bceSAndroid Build Coastguard Worker , m_nonFeedbackProgram(DE_NULL)
885*35238bceSAndroid Build Coastguard Worker , m_patchBuffer(0)
886*35238bceSAndroid Build Coastguard Worker , m_feedbackID(0)
887*35238bceSAndroid Build Coastguard Worker , m_feedbackBuffer(0)
888*35238bceSAndroid Build Coastguard Worker {
889*35238bceSAndroid Build Coastguard Worker DE_ASSERT(tessellationOutput < TESSELLATION_OUT_LAST);
890*35238bceSAndroid Build Coastguard Worker DE_ASSERT(tessellationPointMode < TESSELLATION_POINTMODE_LAST);
891*35238bceSAndroid Build Coastguard Worker DE_ASSERT(geometryOutputType < GEOMETRY_OUTPUT_LAST);
892*35238bceSAndroid Build Coastguard Worker }
893*35238bceSAndroid Build Coastguard Worker
~FeedbackPrimitiveTypeCase(void)894*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::~FeedbackPrimitiveTypeCase(void)
895*35238bceSAndroid Build Coastguard Worker {
896*35238bceSAndroid Build Coastguard Worker deinit();
897*35238bceSAndroid Build Coastguard Worker }
898*35238bceSAndroid Build Coastguard Worker
init(void)899*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::init(void)
900*35238bceSAndroid Build Coastguard Worker {
901*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker // Requirements
904*35238bceSAndroid Build Coastguard Worker const bool supportsES32orGL45 =
905*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
906*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
907*35238bceSAndroid Build Coastguard Worker
908*35238bceSAndroid Build Coastguard Worker if (!supportsES32orGL45 && (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
909*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")))
910*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
911*35238bceSAndroid Build Coastguard Worker
912*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
913*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" +
914*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_SIZE) + " or larger render target.");
915*35238bceSAndroid Build Coastguard Worker
916*35238bceSAndroid Build Coastguard Worker // Log
917*35238bceSAndroid Build Coastguard Worker
918*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Testing "
919*35238bceSAndroid Build Coastguard Worker << getTessellationOutputDescription(m_tessellationOutput, m_tessellationPointMode) << "->"
920*35238bceSAndroid Build Coastguard Worker << getGeometryInputDescription(m_tessellationOutput, m_tessellationPointMode)
921*35238bceSAndroid Build Coastguard Worker << " primitive conversion with and without transform feedback.\n"
922*35238bceSAndroid Build Coastguard Worker << "Sending a patch of 4 vertices (2x2 uniform grid) to tessellation control shader.\n"
923*35238bceSAndroid Build Coastguard Worker << "Control shader emits a patch of 9 vertices (3x3 uniform grid).\n"
924*35238bceSAndroid Build Coastguard Worker << "Setting outer tessellation level = 3, inner = 3.\n"
925*35238bceSAndroid Build Coastguard Worker << "Primitive generator emits "
926*35238bceSAndroid Build Coastguard Worker << getTessellationOutputDescription(m_tessellationOutput, m_tessellationPointMode) << "\n"
927*35238bceSAndroid Build Coastguard Worker << "Geometry shader transforms emitted primitives to "
928*35238bceSAndroid Build Coastguard Worker << getGeometryOutputDescription(m_geometryOutputType) << "\n"
929*35238bceSAndroid Build Coastguard Worker << "Reading back vertex positions of generated primitives using transform feedback.\n"
930*35238bceSAndroid Build Coastguard Worker << "Verifying rendered image and feedback vertices are consistent.\n"
931*35238bceSAndroid Build Coastguard Worker << "Rendering scene again with identical shader program, but without setting feedback varying. "
932*35238bceSAndroid Build Coastguard Worker "Expecting similar output image."
933*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
934*35238bceSAndroid Build Coastguard Worker
935*35238bceSAndroid Build Coastguard Worker // Resources
936*35238bceSAndroid Build Coastguard Worker
937*35238bceSAndroid Build Coastguard Worker {
938*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 patchBufferData[4] = {
939*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-0.9f, -0.9f, 0.0f, 1.0f),
940*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-0.9f, 0.9f, 0.0f, 1.0f),
941*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.9f, -0.9f, 0.0f, 1.0f),
942*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.9f, 0.9f, 0.0f, 1.0f),
943*35238bceSAndroid Build Coastguard Worker };
944*35238bceSAndroid Build Coastguard Worker
945*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_patchBuffer);
946*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer);
947*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, sizeof(patchBufferData), patchBufferData, GL_STATIC_DRAW);
948*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer");
949*35238bceSAndroid Build Coastguard Worker }
950*35238bceSAndroid Build Coastguard Worker
951*35238bceSAndroid Build Coastguard Worker m_feedbackProgram = new glu::ShaderProgram(
952*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
953*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource())
954*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(getTessellationControlSource())
955*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource())
956*35238bceSAndroid Build Coastguard Worker << glu::GeometrySource(getGeometrySource())
957*35238bceSAndroid Build Coastguard Worker << glu::TransformFeedbackVarying("tf_someVertexPosition")
958*35238bceSAndroid Build Coastguard Worker << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS));
959*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_feedbackProgram;
960*35238bceSAndroid Build Coastguard Worker if (!m_feedbackProgram->isOk())
961*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
962*35238bceSAndroid Build Coastguard Worker
963*35238bceSAndroid Build Coastguard Worker m_nonFeedbackProgram = new glu::ShaderProgram(
964*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
965*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource())
966*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(getTessellationControlSource())
967*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource())
968*35238bceSAndroid Build Coastguard Worker << glu::GeometrySource(getGeometrySource()));
969*35238bceSAndroid Build Coastguard Worker if (!m_nonFeedbackProgram->isOk())
970*35238bceSAndroid Build Coastguard Worker {
971*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_nonFeedbackProgram;
972*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
973*35238bceSAndroid Build Coastguard Worker }
974*35238bceSAndroid Build Coastguard Worker
975*35238bceSAndroid Build Coastguard Worker genTransformFeedback();
976*35238bceSAndroid Build Coastguard Worker }
977*35238bceSAndroid Build Coastguard Worker
deinit(void)978*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::deinit(void)
979*35238bceSAndroid Build Coastguard Worker {
980*35238bceSAndroid Build Coastguard Worker if (m_patchBuffer)
981*35238bceSAndroid Build Coastguard Worker {
982*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_patchBuffer);
983*35238bceSAndroid Build Coastguard Worker m_patchBuffer = 0;
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker
986*35238bceSAndroid Build Coastguard Worker if (m_feedbackBuffer)
987*35238bceSAndroid Build Coastguard Worker {
988*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_feedbackBuffer);
989*35238bceSAndroid Build Coastguard Worker m_feedbackBuffer = 0;
990*35238bceSAndroid Build Coastguard Worker }
991*35238bceSAndroid Build Coastguard Worker
992*35238bceSAndroid Build Coastguard Worker if (m_feedbackID)
993*35238bceSAndroid Build Coastguard Worker {
994*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteTransformFeedbacks(1, &m_feedbackID);
995*35238bceSAndroid Build Coastguard Worker m_feedbackID = 0;
996*35238bceSAndroid Build Coastguard Worker }
997*35238bceSAndroid Build Coastguard Worker
998*35238bceSAndroid Build Coastguard Worker if (m_feedbackProgram)
999*35238bceSAndroid Build Coastguard Worker {
1000*35238bceSAndroid Build Coastguard Worker delete m_feedbackProgram;
1001*35238bceSAndroid Build Coastguard Worker m_feedbackProgram = DE_NULL;
1002*35238bceSAndroid Build Coastguard Worker }
1003*35238bceSAndroid Build Coastguard Worker
1004*35238bceSAndroid Build Coastguard Worker if (m_nonFeedbackProgram)
1005*35238bceSAndroid Build Coastguard Worker {
1006*35238bceSAndroid Build Coastguard Worker delete m_nonFeedbackProgram;
1007*35238bceSAndroid Build Coastguard Worker m_nonFeedbackProgram = DE_NULL;
1008*35238bceSAndroid Build Coastguard Worker }
1009*35238bceSAndroid Build Coastguard Worker }
1010*35238bceSAndroid Build Coastguard Worker
iterate(void)1011*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::IterateResult FeedbackPrimitiveTypeCase::iterate(void)
1012*35238bceSAndroid Build Coastguard Worker {
1013*35238bceSAndroid Build Coastguard Worker tcu::Surface feedbackResult(RENDER_SIZE, RENDER_SIZE);
1014*35238bceSAndroid Build Coastguard Worker tcu::Surface nonFeedbackResult(RENDER_SIZE, RENDER_SIZE);
1015*35238bceSAndroid Build Coastguard Worker
1016*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1017*35238bceSAndroid Build Coastguard Worker
1018*35238bceSAndroid Build Coastguard Worker // render with and without XFB
1019*35238bceSAndroid Build Coastguard Worker renderWithFeedback(feedbackResult);
1020*35238bceSAndroid Build Coastguard Worker renderWithoutFeedback(nonFeedbackResult);
1021*35238bceSAndroid Build Coastguard Worker
1022*35238bceSAndroid Build Coastguard Worker // compare
1023*35238bceSAndroid Build Coastguard Worker {
1024*35238bceSAndroid Build Coastguard Worker bool imageOk;
1025*35238bceSAndroid Build Coastguard Worker
1026*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1027*35238bceSAndroid Build Coastguard Worker << "Comparing the image rendered with no transform feedback against the image rendered with "
1028*35238bceSAndroid Build Coastguard Worker "enabled transform feedback."
1029*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1030*35238bceSAndroid Build Coastguard Worker
1031*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getNumSamples() > 1)
1032*35238bceSAndroid Build Coastguard Worker imageOk =
1033*35238bceSAndroid Build Coastguard Worker tcu::fuzzyCompare(m_testCtx.getLog(), "ImageCompare", "Image comparison", feedbackResult.getAccess(),
1034*35238bceSAndroid Build Coastguard Worker nonFeedbackResult.getAccess(), 0.03f, tcu::COMPARE_LOG_RESULT);
1035*35238bceSAndroid Build Coastguard Worker else
1036*35238bceSAndroid Build Coastguard Worker imageOk = tcu::intThresholdPositionDeviationCompare(
1037*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog(), "ImageCompare", "Image comparison", feedbackResult.getAccess(),
1038*35238bceSAndroid Build Coastguard Worker nonFeedbackResult.getAccess(), tcu::UVec4(8, 8, 8, 255), //!< threshold
1039*35238bceSAndroid Build Coastguard Worker tcu::IVec3(1, 1, 0), //!< 3x3 search kernel
1040*35238bceSAndroid Build Coastguard Worker true, //!< fragments may end up over the viewport, just ignore them
1041*35238bceSAndroid Build Coastguard Worker tcu::COMPARE_LOG_RESULT);
1042*35238bceSAndroid Build Coastguard Worker
1043*35238bceSAndroid Build Coastguard Worker if (!imageOk)
1044*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
1045*35238bceSAndroid Build Coastguard Worker }
1046*35238bceSAndroid Build Coastguard Worker
1047*35238bceSAndroid Build Coastguard Worker return STOP;
1048*35238bceSAndroid Build Coastguard Worker }
1049*35238bceSAndroid Build Coastguard Worker
renderWithFeedback(tcu::Surface & dst)1050*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::renderWithFeedback(tcu::Surface &dst)
1051*35238bceSAndroid Build Coastguard Worker {
1052*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1053*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
1054*35238bceSAndroid Build Coastguard Worker const glu::Query primitivesGeneratedQuery(m_context.getRenderContext());
1055*35238bceSAndroid Build Coastguard Worker const int posLocation = gl.getAttribLocation(m_feedbackProgram->getProgram(), "a_position");
1056*35238bceSAndroid Build Coastguard Worker const glw::GLenum feedbackPrimitiveMode = getOutputPrimitiveGLType();
1057*35238bceSAndroid Build Coastguard Worker
1058*35238bceSAndroid Build Coastguard Worker if (posLocation == -1)
1059*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("a_position was -1");
1060*35238bceSAndroid Build Coastguard Worker
1061*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering with transform feedback" << tcu::TestLog::EndMessage;
1062*35238bceSAndroid Build Coastguard Worker
1063*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, dst.getWidth(), dst.getHeight());
1064*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1065*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
1066*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1067*35238bceSAndroid Build Coastguard Worker
1068*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
1069*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer);
1070*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
1071*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
1072*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs");
1073*35238bceSAndroid Build Coastguard Worker
1074*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_feedbackProgram->getProgram());
1075*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
1076*35238bceSAndroid Build Coastguard Worker
1077*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 4);
1078*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
1079*35238bceSAndroid Build Coastguard Worker
1080*35238bceSAndroid Build Coastguard Worker gl.beginQuery(GL_PRIMITIVES_GENERATED, *primitivesGeneratedQuery);
1081*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "begin GL_PRIMITIVES_GENERATED query");
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Begin transform feedback with mode "
1084*35238bceSAndroid Build Coastguard Worker << glu::getPrimitiveTypeStr(feedbackPrimitiveMode) << tcu::TestLog::EndMessage;
1085*35238bceSAndroid Build Coastguard Worker
1086*35238bceSAndroid Build Coastguard Worker gl.beginTransformFeedback(feedbackPrimitiveMode);
1087*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "begin xfb");
1088*35238bceSAndroid Build Coastguard Worker
1089*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Calling drawArrays with mode GL_PATCHES"
1090*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1091*35238bceSAndroid Build Coastguard Worker
1092*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 4);
1093*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches");
1094*35238bceSAndroid Build Coastguard Worker
1095*35238bceSAndroid Build Coastguard Worker gl.endTransformFeedback();
1096*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "end xfb");
1097*35238bceSAndroid Build Coastguard Worker
1098*35238bceSAndroid Build Coastguard Worker gl.endQuery(GL_PRIMITIVES_GENERATED);
1099*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "end GL_PRIMITIVES_GENERATED query");
1100*35238bceSAndroid Build Coastguard Worker
1101*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1102*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1103*35238bceSAndroid Build Coastguard Worker
1104*35238bceSAndroid Build Coastguard Worker // verify GL_PRIMITIVES_GENERATED
1105*35238bceSAndroid Build Coastguard Worker {
1106*35238bceSAndroid Build Coastguard Worker glw::GLuint primitivesGeneratedResult = 0;
1107*35238bceSAndroid Build Coastguard Worker gl.getQueryObjectuiv(*primitivesGeneratedQuery, GL_QUERY_RESULT, &primitivesGeneratedResult);
1108*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_PRIMITIVES_GENERATED value");
1109*35238bceSAndroid Build Coastguard Worker
1110*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GL_PRIMITIVES_GENERATED, expecting "
1111*35238bceSAndroid Build Coastguard Worker << getNumGeneratedPrimitives() << tcu::TestLog::EndMessage;
1112*35238bceSAndroid Build Coastguard Worker
1113*35238bceSAndroid Build Coastguard Worker if ((int)primitivesGeneratedResult != getNumGeneratedPrimitives())
1114*35238bceSAndroid Build Coastguard Worker {
1115*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_PRIMITIVES_GENERATED was "
1116*35238bceSAndroid Build Coastguard Worker << primitivesGeneratedResult << tcu::TestLog::EndMessage;
1117*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected GL_PRIMITIVES_GENERATED");
1118*35238bceSAndroid Build Coastguard Worker }
1119*35238bceSAndroid Build Coastguard Worker else
1120*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "GL_PRIMITIVES_GENERATED valid." << tcu::TestLog::EndMessage;
1121*35238bceSAndroid Build Coastguard Worker }
1122*35238bceSAndroid Build Coastguard Worker
1123*35238bceSAndroid Build Coastguard Worker // feedback
1124*35238bceSAndroid Build Coastguard Worker {
1125*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> feedbackResults(getNumGeneratedElementsPerPrimitive() * getNumGeneratedPrimitives());
1126*35238bceSAndroid Build Coastguard Worker const void *mappedPtr =
1127*35238bceSAndroid Build Coastguard Worker gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
1128*35238bceSAndroid Build Coastguard Worker (glw::GLsizeiptr)(feedbackResults.size() * sizeof(tcu::Vec4)), GL_MAP_READ_BIT);
1129*35238bceSAndroid Build Coastguard Worker glw::GLboolean unmapResult;
1130*35238bceSAndroid Build Coastguard Worker
1131*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "mapBufferRange");
1132*35238bceSAndroid Build Coastguard Worker
1133*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Reading transform feedback buffer." << tcu::TestLog::EndMessage;
1134*35238bceSAndroid Build Coastguard Worker if (!mappedPtr)
1135*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("mapBufferRange returned null");
1136*35238bceSAndroid Build Coastguard Worker
1137*35238bceSAndroid Build Coastguard Worker deMemcpy(feedbackResults[0].getPtr(), mappedPtr, (int)(feedbackResults.size() * sizeof(tcu::Vec4)));
1138*35238bceSAndroid Build Coastguard Worker
1139*35238bceSAndroid Build Coastguard Worker unmapResult = gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
1140*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "unmapBuffer");
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker if (unmapResult != GL_TRUE)
1143*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("unmapBuffer failed, did not return true");
1144*35238bceSAndroid Build Coastguard Worker
1145*35238bceSAndroid Build Coastguard Worker // verify transform results
1146*35238bceSAndroid Build Coastguard Worker verifyFeedbackResults(feedbackResults);
1147*35238bceSAndroid Build Coastguard Worker
1148*35238bceSAndroid Build Coastguard Worker // verify feedback results are consistent with rendered image
1149*35238bceSAndroid Build Coastguard Worker verifyRenderedImage(dst, feedbackResults);
1150*35238bceSAndroid Build Coastguard Worker }
1151*35238bceSAndroid Build Coastguard Worker }
1152*35238bceSAndroid Build Coastguard Worker
renderWithoutFeedback(tcu::Surface & dst)1153*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::renderWithoutFeedback(tcu::Surface &dst)
1154*35238bceSAndroid Build Coastguard Worker {
1155*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1156*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
1157*35238bceSAndroid Build Coastguard Worker const int posLocation = gl.getAttribLocation(m_nonFeedbackProgram->getProgram(), "a_position");
1158*35238bceSAndroid Build Coastguard Worker
1159*35238bceSAndroid Build Coastguard Worker if (posLocation == -1)
1160*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("a_position was -1");
1161*35238bceSAndroid Build Coastguard Worker
1162*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering without transform feedback" << tcu::TestLog::EndMessage;
1163*35238bceSAndroid Build Coastguard Worker
1164*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, dst.getWidth(), dst.getHeight());
1165*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1166*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
1167*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1168*35238bceSAndroid Build Coastguard Worker
1169*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
1170*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer);
1171*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
1172*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
1173*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs");
1174*35238bceSAndroid Build Coastguard Worker
1175*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_nonFeedbackProgram->getProgram());
1176*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
1177*35238bceSAndroid Build Coastguard Worker
1178*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 4);
1179*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
1180*35238bceSAndroid Build Coastguard Worker
1181*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Calling drawArrays with mode GL_PATCHES"
1182*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1183*35238bceSAndroid Build Coastguard Worker
1184*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 4);
1185*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches");
1186*35238bceSAndroid Build Coastguard Worker
1187*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1188*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels");
1189*35238bceSAndroid Build Coastguard Worker }
1190*35238bceSAndroid Build Coastguard Worker
verifyFeedbackResults(const std::vector<tcu::Vec4> & feedbackResult)1191*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::verifyFeedbackResults(const std::vector<tcu::Vec4> &feedbackResult)
1192*35238bceSAndroid Build Coastguard Worker {
1193*35238bceSAndroid Build Coastguard Worker const int geometryAmplification = getGeometryAmplification();
1194*35238bceSAndroid Build Coastguard Worker const int elementsPerPrimitive = getNumGeneratedElementsPerPrimitive();
1195*35238bceSAndroid Build Coastguard Worker const int errorFloodThreshold = 8;
1196*35238bceSAndroid Build Coastguard Worker int readNdx = 0;
1197*35238bceSAndroid Build Coastguard Worker int numErrors = 0;
1198*35238bceSAndroid Build Coastguard Worker
1199*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying feedback results." << tcu::TestLog::EndMessage;
1200*35238bceSAndroid Build Coastguard Worker
1201*35238bceSAndroid Build Coastguard Worker for (int tessellatedPrimitiveNdx = 0; tessellatedPrimitiveNdx < getNumTessellatedPrimitives();
1202*35238bceSAndroid Build Coastguard Worker ++tessellatedPrimitiveNdx)
1203*35238bceSAndroid Build Coastguard Worker {
1204*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 primitiveVertex = feedbackResult[readNdx];
1205*35238bceSAndroid Build Coastguard Worker
1206*35238bceSAndroid Build Coastguard Worker // check the generated vertices are in the proper range (range: -0.4 <-> 0.4)
1207*35238bceSAndroid Build Coastguard Worker {
1208*35238bceSAndroid Build Coastguard Worker const float equalThreshold = 1.0e-6f;
1209*35238bceSAndroid Build Coastguard Worker const bool centroidOk =
1210*35238bceSAndroid Build Coastguard Worker (primitiveVertex.x() >= -0.4f - equalThreshold) && (primitiveVertex.x() <= 0.4f + equalThreshold) &&
1211*35238bceSAndroid Build Coastguard Worker (primitiveVertex.y() >= -0.4f - equalThreshold) && (primitiveVertex.y() <= 0.4f + equalThreshold) &&
1212*35238bceSAndroid Build Coastguard Worker (de::abs(primitiveVertex.z()) < equalThreshold) &&
1213*35238bceSAndroid Build Coastguard Worker (de::abs(primitiveVertex.w() - 1.0f) < equalThreshold);
1214*35238bceSAndroid Build Coastguard Worker
1215*35238bceSAndroid Build Coastguard Worker if (!centroidOk && numErrors++ < errorFloodThreshold)
1216*35238bceSAndroid Build Coastguard Worker {
1217*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Element at index " << (readNdx)
1218*35238bceSAndroid Build Coastguard Worker << " (tessellation invocation " << tessellatedPrimitiveNdx << ")\n"
1219*35238bceSAndroid Build Coastguard Worker << "\texpected vertex in range: ( [-0.4, 0.4], [-0.4, 0.4], 0.0, 1.0 )\n"
1220*35238bceSAndroid Build Coastguard Worker << "\tgot: " << primitiveVertex << tcu::TestLog::EndMessage;
1221*35238bceSAndroid Build Coastguard Worker
1222*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid feedback output");
1223*35238bceSAndroid Build Coastguard Worker
1224*35238bceSAndroid Build Coastguard Worker ++readNdx;
1225*35238bceSAndroid Build Coastguard Worker continue;
1226*35238bceSAndroid Build Coastguard Worker }
1227*35238bceSAndroid Build Coastguard Worker }
1228*35238bceSAndroid Build Coastguard Worker
1229*35238bceSAndroid Build Coastguard Worker // check all other primitives generated from this tessellated primitive have the same feedback value
1230*35238bceSAndroid Build Coastguard Worker for (int generatedPrimitiveNdx = 0; generatedPrimitiveNdx < geometryAmplification; ++generatedPrimitiveNdx)
1231*35238bceSAndroid Build Coastguard Worker for (int primitiveVertexNdx = 0; primitiveVertexNdx < elementsPerPrimitive; ++primitiveVertexNdx)
1232*35238bceSAndroid Build Coastguard Worker {
1233*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 generatedElementVertex = feedbackResult[readNdx];
1234*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 equalThreshold(1.0e-6f);
1235*35238bceSAndroid Build Coastguard Worker
1236*35238bceSAndroid Build Coastguard Worker if (tcu::boolAny(tcu::greaterThan(tcu::abs(primitiveVertex - generatedElementVertex), equalThreshold)))
1237*35238bceSAndroid Build Coastguard Worker {
1238*35238bceSAndroid Build Coastguard Worker if (numErrors++ < errorFloodThreshold)
1239*35238bceSAndroid Build Coastguard Worker {
1240*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1241*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << "Element at index " << (readNdx) << " (tessellation invocation "
1242*35238bceSAndroid Build Coastguard Worker << tessellatedPrimitiveNdx << ", geometry primitive " << generatedPrimitiveNdx
1243*35238bceSAndroid Build Coastguard Worker << ", emitted vertex " << primitiveVertexNdx << "):\n"
1244*35238bceSAndroid Build Coastguard Worker << "\tfeedback result was not contant over whole primitive.\n"
1245*35238bceSAndroid Build Coastguard Worker << "\tfirst emitted value: " << primitiveVertex << "\n"
1246*35238bceSAndroid Build Coastguard Worker << "\tcurrent emitted value:" << generatedElementVertex << "\n"
1247*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1248*35238bceSAndroid Build Coastguard Worker }
1249*35238bceSAndroid Build Coastguard Worker
1250*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
1251*35238bceSAndroid Build Coastguard Worker "got multiple different feedback values for a single primitive");
1252*35238bceSAndroid Build Coastguard Worker }
1253*35238bceSAndroid Build Coastguard Worker
1254*35238bceSAndroid Build Coastguard Worker readNdx++;
1255*35238bceSAndroid Build Coastguard Worker }
1256*35238bceSAndroid Build Coastguard Worker }
1257*35238bceSAndroid Build Coastguard Worker
1258*35238bceSAndroid Build Coastguard Worker if (numErrors > errorFloodThreshold)
1259*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (numErrors - errorFloodThreshold) << " error(s)."
1260*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1261*35238bceSAndroid Build Coastguard Worker }
1262*35238bceSAndroid Build Coastguard Worker
feedbackResultCompare(const tcu::Vec4 & a,const tcu::Vec4 & b)1263*35238bceSAndroid Build Coastguard Worker static bool feedbackResultCompare(const tcu::Vec4 &a, const tcu::Vec4 &b)
1264*35238bceSAndroid Build Coastguard Worker {
1265*35238bceSAndroid Build Coastguard Worker if (a.x() < b.x())
1266*35238bceSAndroid Build Coastguard Worker return true;
1267*35238bceSAndroid Build Coastguard Worker if (a.x() > b.x())
1268*35238bceSAndroid Build Coastguard Worker return false;
1269*35238bceSAndroid Build Coastguard Worker
1270*35238bceSAndroid Build Coastguard Worker return a.y() < b.y();
1271*35238bceSAndroid Build Coastguard Worker }
1272*35238bceSAndroid Build Coastguard Worker
verifyRenderedImage(const tcu::Surface & image,const std::vector<tcu::Vec4> & tfVertices)1273*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::verifyRenderedImage(const tcu::Surface &image, const std::vector<tcu::Vec4> &tfVertices)
1274*35238bceSAndroid Build Coastguard Worker {
1275*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> vertices;
1276*35238bceSAndroid Build Coastguard Worker
1277*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Comparing result image against feedback results."
1278*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1279*35238bceSAndroid Build Coastguard Worker
1280*35238bceSAndroid Build Coastguard Worker // Check only unique vertices
1281*35238bceSAndroid Build Coastguard Worker std::unique_copy(tfVertices.begin(), tfVertices.end(), std::back_insert_iterator<std::vector<tcu::Vec4>>(vertices));
1282*35238bceSAndroid Build Coastguard Worker std::sort(vertices.begin(), vertices.end(), feedbackResultCompare);
1283*35238bceSAndroid Build Coastguard Worker vertices.erase(std::unique(vertices.begin(), vertices.end()), vertices.end());
1284*35238bceSAndroid Build Coastguard Worker
1285*35238bceSAndroid Build Coastguard Worker // Verifying vertices recorded with feedback actually ended up on the result image
1286*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)vertices.size(); ++ndx)
1287*35238bceSAndroid Build Coastguard Worker {
1288*35238bceSAndroid Build Coastguard Worker // Rasterization (of lines) may deviate by one pixel. In addition to that, allow minimal errors in rasterized position vs. feedback result.
1289*35238bceSAndroid Build Coastguard Worker // This minimal error could result in a difference in rounding => allow one additional pixel in deviation
1290*35238bceSAndroid Build Coastguard Worker
1291*35238bceSAndroid Build Coastguard Worker const int rasterDeviation = 2;
1292*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 rasterPos((int)deFloatRound((vertices[ndx].x() * 0.5f + 0.5f) * (float)image.getWidth()),
1293*35238bceSAndroid Build Coastguard Worker (int)deFloatRound((vertices[ndx].y() * 0.5f + 0.5f) * (float)image.getHeight()));
1294*35238bceSAndroid Build Coastguard Worker
1295*35238bceSAndroid Build Coastguard Worker // Find produced rasterization results
1296*35238bceSAndroid Build Coastguard Worker bool found = false;
1297*35238bceSAndroid Build Coastguard Worker
1298*35238bceSAndroid Build Coastguard Worker for (int dy = -rasterDeviation; dy <= rasterDeviation && !found; ++dy)
1299*35238bceSAndroid Build Coastguard Worker for (int dx = -rasterDeviation; dx <= rasterDeviation && !found; ++dx)
1300*35238bceSAndroid Build Coastguard Worker {
1301*35238bceSAndroid Build Coastguard Worker // Raster result could end up outside the viewport
1302*35238bceSAndroid Build Coastguard Worker if (rasterPos.x() + dx < 0 || rasterPos.x() + dx >= image.getWidth() || rasterPos.y() + dy < 0 ||
1303*35238bceSAndroid Build Coastguard Worker rasterPos.y() + dy >= image.getHeight())
1304*35238bceSAndroid Build Coastguard Worker found = true;
1305*35238bceSAndroid Build Coastguard Worker else
1306*35238bceSAndroid Build Coastguard Worker {
1307*35238bceSAndroid Build Coastguard Worker const tcu::RGBA result = image.getPixel(rasterPos.x() + dx, rasterPos.y() + dy);
1308*35238bceSAndroid Build Coastguard Worker
1309*35238bceSAndroid Build Coastguard Worker if (!isBlack(result))
1310*35238bceSAndroid Build Coastguard Worker found = true;
1311*35238bceSAndroid Build Coastguard Worker }
1312*35238bceSAndroid Build Coastguard Worker }
1313*35238bceSAndroid Build Coastguard Worker
1314*35238bceSAndroid Build Coastguard Worker if (!found)
1315*35238bceSAndroid Build Coastguard Worker {
1316*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Vertex " << vertices[ndx] << "\n"
1317*35238bceSAndroid Build Coastguard Worker << "\tCould not find rasterization output for vertex.\n"
1318*35238bceSAndroid Build Coastguard Worker << "\tExpected non-black pixels near " << rasterPos << tcu::TestLog::EndMessage;
1319*35238bceSAndroid Build Coastguard Worker
1320*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid result image");
1321*35238bceSAndroid Build Coastguard Worker }
1322*35238bceSAndroid Build Coastguard Worker }
1323*35238bceSAndroid Build Coastguard Worker }
1324*35238bceSAndroid Build Coastguard Worker
genTransformFeedback(void)1325*35238bceSAndroid Build Coastguard Worker void FeedbackPrimitiveTypeCase::genTransformFeedback(void)
1326*35238bceSAndroid Build Coastguard Worker {
1327*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1328*35238bceSAndroid Build Coastguard Worker const int elementsPerPrimitive = getNumGeneratedElementsPerPrimitive();
1329*35238bceSAndroid Build Coastguard Worker const int feedbackPrimitives = getNumGeneratedPrimitives();
1330*35238bceSAndroid Build Coastguard Worker const int feedbackElements = elementsPerPrimitive * feedbackPrimitives;
1331*35238bceSAndroid Build Coastguard Worker const std::vector<tcu::Vec4> initialBuffer(feedbackElements, tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f));
1332*35238bceSAndroid Build Coastguard Worker
1333*35238bceSAndroid Build Coastguard Worker gl.genTransformFeedbacks(1, &m_feedbackID);
1334*35238bceSAndroid Build Coastguard Worker gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_feedbackID);
1335*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen transform feedback");
1336*35238bceSAndroid Build Coastguard Worker
1337*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_feedbackBuffer);
1338*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_feedbackBuffer);
1339*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(tcu::Vec4) * initialBuffer.size(), initialBuffer[0].getPtr(),
1340*35238bceSAndroid Build Coastguard Worker GL_STATIC_COPY);
1341*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen feedback buffer");
1342*35238bceSAndroid Build Coastguard Worker
1343*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_feedbackBuffer);
1344*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind feedback buffer");
1345*35238bceSAndroid Build Coastguard Worker }
1346*35238bceSAndroid Build Coastguard Worker
getTriangleNumOutputPrimitives(int tessellationLevel)1347*35238bceSAndroid Build Coastguard Worker static int getTriangleNumOutputPrimitives(int tessellationLevel)
1348*35238bceSAndroid Build Coastguard Worker {
1349*35238bceSAndroid Build Coastguard Worker if (tessellationLevel == 1)
1350*35238bceSAndroid Build Coastguard Worker return 1;
1351*35238bceSAndroid Build Coastguard Worker else if (tessellationLevel == 2)
1352*35238bceSAndroid Build Coastguard Worker return 6;
1353*35238bceSAndroid Build Coastguard Worker else
1354*35238bceSAndroid Build Coastguard Worker return 3 * (2 + 2 * (tessellationLevel - 2)) + getTriangleNumOutputPrimitives(tessellationLevel - 2);
1355*35238bceSAndroid Build Coastguard Worker }
1356*35238bceSAndroid Build Coastguard Worker
getTriangleNumOutputPrimitivesPoints(int tessellationLevel)1357*35238bceSAndroid Build Coastguard Worker static int getTriangleNumOutputPrimitivesPoints(int tessellationLevel)
1358*35238bceSAndroid Build Coastguard Worker {
1359*35238bceSAndroid Build Coastguard Worker if (tessellationLevel == 0)
1360*35238bceSAndroid Build Coastguard Worker return 1;
1361*35238bceSAndroid Build Coastguard Worker else if (tessellationLevel == 1)
1362*35238bceSAndroid Build Coastguard Worker return 3;
1363*35238bceSAndroid Build Coastguard Worker else
1364*35238bceSAndroid Build Coastguard Worker return 3 + 3 * (tessellationLevel - 1) + getTriangleNumOutputPrimitivesPoints(tessellationLevel - 2);
1365*35238bceSAndroid Build Coastguard Worker }
1366*35238bceSAndroid Build Coastguard Worker
getNumGeneratedElementsPerPrimitive(void) const1367*35238bceSAndroid Build Coastguard Worker int FeedbackPrimitiveTypeCase::getNumGeneratedElementsPerPrimitive(void) const
1368*35238bceSAndroid Build Coastguard Worker {
1369*35238bceSAndroid Build Coastguard Worker if (m_geometryOutputType == GEOMETRY_OUTPUT_TRIANGLES)
1370*35238bceSAndroid Build Coastguard Worker return 3;
1371*35238bceSAndroid Build Coastguard Worker else if (m_geometryOutputType == GEOMETRY_OUTPUT_LINES)
1372*35238bceSAndroid Build Coastguard Worker return 2;
1373*35238bceSAndroid Build Coastguard Worker else if (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS)
1374*35238bceSAndroid Build Coastguard Worker return 1;
1375*35238bceSAndroid Build Coastguard Worker else
1376*35238bceSAndroid Build Coastguard Worker {
1377*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1378*35238bceSAndroid Build Coastguard Worker return -1;
1379*35238bceSAndroid Build Coastguard Worker }
1380*35238bceSAndroid Build Coastguard Worker }
1381*35238bceSAndroid Build Coastguard Worker
getNumGeneratedPrimitives(void) const1382*35238bceSAndroid Build Coastguard Worker int FeedbackPrimitiveTypeCase::getNumGeneratedPrimitives(void) const
1383*35238bceSAndroid Build Coastguard Worker {
1384*35238bceSAndroid Build Coastguard Worker return getNumTessellatedPrimitives() * getGeometryAmplification();
1385*35238bceSAndroid Build Coastguard Worker }
1386*35238bceSAndroid Build Coastguard Worker
getNumTessellatedPrimitives(void) const1387*35238bceSAndroid Build Coastguard Worker int FeedbackPrimitiveTypeCase::getNumTessellatedPrimitives(void) const
1388*35238bceSAndroid Build Coastguard Worker {
1389*35238bceSAndroid Build Coastguard Worker const int tessellationLevel = 3;
1390*35238bceSAndroid Build Coastguard Worker
1391*35238bceSAndroid Build Coastguard Worker if (m_tessellationPointMode == TESSELLATION_POINTMODE_OFF)
1392*35238bceSAndroid Build Coastguard Worker {
1393*35238bceSAndroid Build Coastguard Worker if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES)
1394*35238bceSAndroid Build Coastguard Worker return getTriangleNumOutputPrimitives(tessellationLevel);
1395*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_QUADS)
1396*35238bceSAndroid Build Coastguard Worker return tessellationLevel * tessellationLevel * 2; // tessellated as triangles
1397*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES)
1398*35238bceSAndroid Build Coastguard Worker return tessellationLevel * tessellationLevel;
1399*35238bceSAndroid Build Coastguard Worker }
1400*35238bceSAndroid Build Coastguard Worker else if (m_tessellationPointMode == TESSELLATION_POINTMODE_ON)
1401*35238bceSAndroid Build Coastguard Worker {
1402*35238bceSAndroid Build Coastguard Worker if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES)
1403*35238bceSAndroid Build Coastguard Worker return getTriangleNumOutputPrimitivesPoints(tessellationLevel);
1404*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_QUADS)
1405*35238bceSAndroid Build Coastguard Worker return (tessellationLevel + 1) * (tessellationLevel + 1);
1406*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES)
1407*35238bceSAndroid Build Coastguard Worker return tessellationLevel * (tessellationLevel + 1);
1408*35238bceSAndroid Build Coastguard Worker }
1409*35238bceSAndroid Build Coastguard Worker
1410*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1411*35238bceSAndroid Build Coastguard Worker return -1;
1412*35238bceSAndroid Build Coastguard Worker }
1413*35238bceSAndroid Build Coastguard Worker
getGeometryAmplification(void) const1414*35238bceSAndroid Build Coastguard Worker int FeedbackPrimitiveTypeCase::getGeometryAmplification(void) const
1415*35238bceSAndroid Build Coastguard Worker {
1416*35238bceSAndroid Build Coastguard Worker const int outputAmplification = (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? (2) : (1);
1417*35238bceSAndroid Build Coastguard Worker const int numInputVertices = (m_tessellationPointMode) ? (1) :
1418*35238bceSAndroid Build Coastguard Worker (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? (2) :
1419*35238bceSAndroid Build Coastguard Worker (3);
1420*35238bceSAndroid Build Coastguard Worker
1421*35238bceSAndroid Build Coastguard Worker return outputAmplification * numInputVertices;
1422*35238bceSAndroid Build Coastguard Worker }
1423*35238bceSAndroid Build Coastguard Worker
getOutputPrimitiveGLType(void) const1424*35238bceSAndroid Build Coastguard Worker glw::GLenum FeedbackPrimitiveTypeCase::getOutputPrimitiveGLType(void) const
1425*35238bceSAndroid Build Coastguard Worker {
1426*35238bceSAndroid Build Coastguard Worker if (m_geometryOutputType == GEOMETRY_OUTPUT_TRIANGLES)
1427*35238bceSAndroid Build Coastguard Worker return GL_TRIANGLES;
1428*35238bceSAndroid Build Coastguard Worker else if (m_geometryOutputType == GEOMETRY_OUTPUT_LINES)
1429*35238bceSAndroid Build Coastguard Worker return GL_LINES;
1430*35238bceSAndroid Build Coastguard Worker else if (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS)
1431*35238bceSAndroid Build Coastguard Worker return GL_POINTS;
1432*35238bceSAndroid Build Coastguard Worker else
1433*35238bceSAndroid Build Coastguard Worker {
1434*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1435*35238bceSAndroid Build Coastguard Worker return -1;
1436*35238bceSAndroid Build Coastguard Worker }
1437*35238bceSAndroid Build Coastguard Worker }
1438*35238bceSAndroid Build Coastguard Worker
getVertexSource(void) const1439*35238bceSAndroid Build Coastguard Worker std::string FeedbackPrimitiveTypeCase::getVertexSource(void) const
1440*35238bceSAndroid Build Coastguard Worker {
1441*35238bceSAndroid Build Coastguard Worker return specializeShader(s_positionVertexShader, m_context.getRenderContext().getType());
1442*35238bceSAndroid Build Coastguard Worker }
1443*35238bceSAndroid Build Coastguard Worker
getFragmentSource(void) const1444*35238bceSAndroid Build Coastguard Worker std::string FeedbackPrimitiveTypeCase::getFragmentSource(void) const
1445*35238bceSAndroid Build Coastguard Worker {
1446*35238bceSAndroid Build Coastguard Worker return specializeShader(s_whiteOutputFragmentShader, m_context.getRenderContext().getType());
1447*35238bceSAndroid Build Coastguard Worker }
1448*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(void) const1449*35238bceSAndroid Build Coastguard Worker std::string FeedbackPrimitiveTypeCase::getTessellationControlSource(void) const
1450*35238bceSAndroid Build Coastguard Worker {
1451*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1452*35238bceSAndroid Build Coastguard Worker
1453*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
1454*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
1455*35238bceSAndroid Build Coastguard Worker "layout(vertices = 9) out;\n"
1456*35238bceSAndroid Build Coastguard Worker "\n"
1457*35238bceSAndroid Build Coastguard Worker "uniform highp float u_innerTessellationLevel;\n"
1458*35238bceSAndroid Build Coastguard Worker "uniform highp float u_outerTessellationLevel;\n"
1459*35238bceSAndroid Build Coastguard Worker "\n"
1460*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1461*35238bceSAndroid Build Coastguard Worker "{\n"
1462*35238bceSAndroid Build Coastguard Worker " if (gl_PatchVerticesIn != 4)\n"
1463*35238bceSAndroid Build Coastguard Worker " return;\n"
1464*35238bceSAndroid Build Coastguard Worker "\n"
1465*35238bceSAndroid Build Coastguard Worker " // Convert input 2x2 grid to 3x3 grid\n"
1466*35238bceSAndroid Build Coastguard Worker " float xweight = float(gl_InvocationID % 3) / 2.0f;\n"
1467*35238bceSAndroid Build Coastguard Worker " float yweight = float(gl_InvocationID / 3) / 2.0f;\n"
1468*35238bceSAndroid Build Coastguard Worker "\n"
1469*35238bceSAndroid Build Coastguard Worker " vec4 y0 = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, yweight);\n"
1470*35238bceSAndroid Build Coastguard Worker " vec4 y1 = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, yweight);\n"
1471*35238bceSAndroid Build Coastguard Worker "\n"
1472*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = mix(y0, y1, xweight);\n"
1473*35238bceSAndroid Build Coastguard Worker "\n";
1474*35238bceSAndroid Build Coastguard Worker
1475*35238bceSAndroid Build Coastguard Worker if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES)
1476*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = 3.0;\n"
1477*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 3.0;\n"
1478*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 3.0;\n"
1479*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 3.0;\n";
1480*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_QUADS)
1481*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = 3.0;\n"
1482*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 3.0;\n"
1483*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 3.0;\n"
1484*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = 3.0;\n"
1485*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 3.0;\n"
1486*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = 3.0;\n";
1487*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES)
1488*35238bceSAndroid Build Coastguard Worker buf << " gl_TessLevelOuter[0] = 3.0;\n"
1489*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 3.0;\n";
1490*35238bceSAndroid Build Coastguard Worker else
1491*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1492*35238bceSAndroid Build Coastguard Worker
1493*35238bceSAndroid Build Coastguard Worker buf << "}\n";
1494*35238bceSAndroid Build Coastguard Worker
1495*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
1496*35238bceSAndroid Build Coastguard Worker }
1497*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(void) const1498*35238bceSAndroid Build Coastguard Worker std::string FeedbackPrimitiveTypeCase::getTessellationEvaluationSource(void) const
1499*35238bceSAndroid Build Coastguard Worker {
1500*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1501*35238bceSAndroid Build Coastguard Worker
1502*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
1503*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
1504*35238bceSAndroid Build Coastguard Worker "layout("
1505*35238bceSAndroid Build Coastguard Worker << ((m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) ? ("triangles") :
1506*35238bceSAndroid Build Coastguard Worker (m_tessellationOutput == TESSELLATION_OUT_QUADS) ? ("quads") :
1507*35238bceSAndroid Build Coastguard Worker ("isolines"))
1508*35238bceSAndroid Build Coastguard Worker << ((m_tessellationPointMode) ? (", point_mode") : (""))
1509*35238bceSAndroid Build Coastguard Worker << ") in;\n"
1510*35238bceSAndroid Build Coastguard Worker "\n"
1511*35238bceSAndroid Build Coastguard Worker "out highp vec4 v_tessellationCoords;\n"
1512*35238bceSAndroid Build Coastguard Worker "\n"
1513*35238bceSAndroid Build Coastguard Worker "// note: No need to use precise gl_Position since we do not require gapless geometry\n"
1514*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1515*35238bceSAndroid Build Coastguard Worker "{\n"
1516*35238bceSAndroid Build Coastguard Worker " if (gl_PatchVerticesIn != 9)\n"
1517*35238bceSAndroid Build Coastguard Worker " return;\n"
1518*35238bceSAndroid Build Coastguard Worker "\n"
1519*35238bceSAndroid Build Coastguard Worker " vec4 patchCentroid = vec4(0.0);\n"
1520*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < gl_PatchVerticesIn; ++ndx)\n"
1521*35238bceSAndroid Build Coastguard Worker " patchCentroid += gl_in[ndx].gl_Position;\n"
1522*35238bceSAndroid Build Coastguard Worker " patchCentroid /= patchCentroid.w;\n"
1523*35238bceSAndroid Build Coastguard Worker "\n";
1524*35238bceSAndroid Build Coastguard Worker
1525*35238bceSAndroid Build Coastguard Worker if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES)
1526*35238bceSAndroid Build Coastguard Worker buf << " // map barycentric coords to 2d coords\n"
1527*35238bceSAndroid Build Coastguard Worker " const vec3 tessDirX = vec3( 0.4, 0.4, 0.0);\n"
1528*35238bceSAndroid Build Coastguard Worker " const vec3 tessDirY = vec3( 0.0, -0.4, 0.0);\n"
1529*35238bceSAndroid Build Coastguard Worker " const vec3 tessDirZ = vec3(-0.4, 0.4, 0.0);\n"
1530*35238bceSAndroid Build Coastguard Worker " gl_Position = patchCentroid + vec4(gl_TessCoord.x * tessDirX + gl_TessCoord.y * tessDirY + "
1531*35238bceSAndroid Build Coastguard Worker "gl_TessCoord.z * tessDirZ, 0.0);\n";
1532*35238bceSAndroid Build Coastguard Worker else if (m_tessellationOutput == TESSELLATION_OUT_QUADS || m_tessellationOutput == TESSELLATION_OUT_ISOLINES)
1533*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = patchCentroid + vec4(gl_TessCoord.x * 0.8 - 0.4, gl_TessCoord.y * 0.8 - 0.4, 0.0, "
1534*35238bceSAndroid Build Coastguard Worker "0.0);\n";
1535*35238bceSAndroid Build Coastguard Worker else
1536*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1537*35238bceSAndroid Build Coastguard Worker
1538*35238bceSAndroid Build Coastguard Worker buf << " v_tessellationCoords = vec4(gl_TessCoord, 0.0);\n"
1539*35238bceSAndroid Build Coastguard Worker "}\n";
1540*35238bceSAndroid Build Coastguard Worker
1541*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
1542*35238bceSAndroid Build Coastguard Worker }
1543*35238bceSAndroid Build Coastguard Worker
getGeometrySource(void) const1544*35238bceSAndroid Build Coastguard Worker std::string FeedbackPrimitiveTypeCase::getGeometrySource(void) const
1545*35238bceSAndroid Build Coastguard Worker {
1546*35238bceSAndroid Build Coastguard Worker const char *const geometryInputPrimitive = (m_tessellationPointMode) ? ("points") :
1547*35238bceSAndroid Build Coastguard Worker (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? ("lines") :
1548*35238bceSAndroid Build Coastguard Worker ("triangles");
1549*35238bceSAndroid Build Coastguard Worker const char *const geometryOutputPrimitive = (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) ? ("points") :
1550*35238bceSAndroid Build Coastguard Worker (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? ("line_strip") :
1551*35238bceSAndroid Build Coastguard Worker ("triangle_strip");
1552*35238bceSAndroid Build Coastguard Worker const int numInputVertices = (m_tessellationPointMode) ? (1) :
1553*35238bceSAndroid Build Coastguard Worker (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? (2) :
1554*35238bceSAndroid Build Coastguard Worker (3);
1555*35238bceSAndroid Build Coastguard Worker const int numSingleVertexOutputVertices = (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) ? (1) :
1556*35238bceSAndroid Build Coastguard Worker (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? (4) :
1557*35238bceSAndroid Build Coastguard Worker (3);
1558*35238bceSAndroid Build Coastguard Worker const int numEmitVertices = numInputVertices * numSingleVertexOutputVertices;
1559*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1560*35238bceSAndroid Build Coastguard Worker
1561*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
1562*35238bceSAndroid Build Coastguard Worker "${EXTENSION_GEOMETRY_SHADER}"
1563*35238bceSAndroid Build Coastguard Worker "layout("
1564*35238bceSAndroid Build Coastguard Worker << geometryInputPrimitive
1565*35238bceSAndroid Build Coastguard Worker << ") in;\n"
1566*35238bceSAndroid Build Coastguard Worker "layout("
1567*35238bceSAndroid Build Coastguard Worker << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices
1568*35238bceSAndroid Build Coastguard Worker << ") out;\n"
1569*35238bceSAndroid Build Coastguard Worker "\n"
1570*35238bceSAndroid Build Coastguard Worker "in highp vec4 v_tessellationCoords[];\n"
1571*35238bceSAndroid Build Coastguard Worker "out highp vec4 tf_someVertexPosition;\n"
1572*35238bceSAndroid Build Coastguard Worker "\n"
1573*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1574*35238bceSAndroid Build Coastguard Worker "{\n"
1575*35238bceSAndroid Build Coastguard Worker " // Emit primitive\n"
1576*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < gl_in.length(); ++ndx)\n"
1577*35238bceSAndroid Build Coastguard Worker " {\n";
1578*35238bceSAndroid Build Coastguard Worker
1579*35238bceSAndroid Build Coastguard Worker switch (m_geometryOutputType)
1580*35238bceSAndroid Build Coastguard Worker {
1581*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_POINTS:
1582*35238bceSAndroid Build Coastguard Worker buf << " // Draw point on vertex\n"
1583*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position;\n"
1584*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1585*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n";
1586*35238bceSAndroid Build Coastguard Worker break;
1587*35238bceSAndroid Build Coastguard Worker
1588*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_LINES:
1589*35238bceSAndroid Build Coastguard Worker buf << " // Draw cross on vertex\n"
1590*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4(-0.02, -0.02, 0.0, 0.0);\n"
1591*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1592*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1593*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, 0.02, 0.0, 0.0);\n"
1594*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1595*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1596*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
1597*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, -0.02, 0.0, 0.0);\n"
1598*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1599*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1600*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4(-0.02, 0.02, 0.0, 0.0);\n"
1601*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1602*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1603*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n";
1604*35238bceSAndroid Build Coastguard Worker break;
1605*35238bceSAndroid Build Coastguard Worker
1606*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_TRIANGLES:
1607*35238bceSAndroid Build Coastguard Worker buf << " // Draw triangle on vertex\n"
1608*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4( 0.00, -0.02, 0.0, 0.0);\n"
1609*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1610*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1611*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, 0.00, 0.0, 0.0);\n"
1612*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1613*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1614*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4( -0.02, 0.00, 0.0, 0.0);\n"
1615*35238bceSAndroid Build Coastguard Worker " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n"
1616*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
1617*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n";
1618*35238bceSAndroid Build Coastguard Worker break;
1619*35238bceSAndroid Build Coastguard Worker
1620*35238bceSAndroid Build Coastguard Worker default:
1621*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1622*35238bceSAndroid Build Coastguard Worker return "";
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker
1625*35238bceSAndroid Build Coastguard Worker buf << " }\n"
1626*35238bceSAndroid Build Coastguard Worker "}\n";
1627*35238bceSAndroid Build Coastguard Worker
1628*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
1629*35238bceSAndroid Build Coastguard Worker }
1630*35238bceSAndroid Build Coastguard Worker
getTessellationOutputDescription(TessellationOutputType tessellationOutput,TessellationPointMode pointMode)1631*35238bceSAndroid Build Coastguard Worker const char *FeedbackPrimitiveTypeCase::getTessellationOutputDescription(TessellationOutputType tessellationOutput,
1632*35238bceSAndroid Build Coastguard Worker TessellationPointMode pointMode)
1633*35238bceSAndroid Build Coastguard Worker {
1634*35238bceSAndroid Build Coastguard Worker switch (tessellationOutput)
1635*35238bceSAndroid Build Coastguard Worker {
1636*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_TRIANGLES:
1637*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points (triangles in point mode)") : ("triangles");
1638*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_QUADS:
1639*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points (quads in point mode)") : ("quads");
1640*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_ISOLINES:
1641*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points (isolines in point mode)") : ("isolines");
1642*35238bceSAndroid Build Coastguard Worker default:
1643*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1644*35238bceSAndroid Build Coastguard Worker return DE_NULL;
1645*35238bceSAndroid Build Coastguard Worker }
1646*35238bceSAndroid Build Coastguard Worker }
1647*35238bceSAndroid Build Coastguard Worker
getGeometryInputDescription(TessellationOutputType tessellationOutput,TessellationPointMode pointMode)1648*35238bceSAndroid Build Coastguard Worker const char *FeedbackPrimitiveTypeCase::getGeometryInputDescription(TessellationOutputType tessellationOutput,
1649*35238bceSAndroid Build Coastguard Worker TessellationPointMode pointMode)
1650*35238bceSAndroid Build Coastguard Worker {
1651*35238bceSAndroid Build Coastguard Worker switch (tessellationOutput)
1652*35238bceSAndroid Build Coastguard Worker {
1653*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_TRIANGLES:
1654*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points") : ("triangles");
1655*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_QUADS:
1656*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points") : ("triangles");
1657*35238bceSAndroid Build Coastguard Worker case TESSELLATION_OUT_ISOLINES:
1658*35238bceSAndroid Build Coastguard Worker return (pointMode) ? ("points") : ("lines");
1659*35238bceSAndroid Build Coastguard Worker default:
1660*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1661*35238bceSAndroid Build Coastguard Worker return DE_NULL;
1662*35238bceSAndroid Build Coastguard Worker }
1663*35238bceSAndroid Build Coastguard Worker }
1664*35238bceSAndroid Build Coastguard Worker
getGeometryOutputDescription(GeometryOutputType geometryOutput)1665*35238bceSAndroid Build Coastguard Worker const char *FeedbackPrimitiveTypeCase::getGeometryOutputDescription(GeometryOutputType geometryOutput)
1666*35238bceSAndroid Build Coastguard Worker {
1667*35238bceSAndroid Build Coastguard Worker switch (geometryOutput)
1668*35238bceSAndroid Build Coastguard Worker {
1669*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_POINTS:
1670*35238bceSAndroid Build Coastguard Worker return "points";
1671*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_LINES:
1672*35238bceSAndroid Build Coastguard Worker return "lines";
1673*35238bceSAndroid Build Coastguard Worker case GEOMETRY_OUTPUT_TRIANGLES:
1674*35238bceSAndroid Build Coastguard Worker return "triangles";
1675*35238bceSAndroid Build Coastguard Worker default:
1676*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1677*35238bceSAndroid Build Coastguard Worker return DE_NULL;
1678*35238bceSAndroid Build Coastguard Worker }
1679*35238bceSAndroid Build Coastguard Worker }
1680*35238bceSAndroid Build Coastguard Worker
1681*35238bceSAndroid Build Coastguard Worker class PointSizeCase : public TestCase
1682*35238bceSAndroid Build Coastguard Worker {
1683*35238bceSAndroid Build Coastguard Worker public:
1684*35238bceSAndroid Build Coastguard Worker enum Flags
1685*35238bceSAndroid Build Coastguard Worker {
1686*35238bceSAndroid Build Coastguard Worker FLAG_VERTEX_SET = 0x01, // !< set gl_PointSize in vertex shader
1687*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_CONTROL_SET = 0x02, // !< set gl_PointSize in tessellation evaluation shader
1688*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_EVALUATION_SET = 0x04, // !< set gl_PointSize in tessellation control shader
1689*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_ADD = 0x08, // !< read and add to gl_PointSize in tessellation shader pair
1690*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_DONT_SET = 0x10, // !< don't set gl_PointSize in tessellation shader
1691*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_SET = 0x20, // !< set gl_PointSize in geometry shader
1692*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_ADD = 0x40, // !< read and add to gl_PointSize in geometry shader
1693*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_DONT_SET = 0x80, // !< don't set gl_PointSize in geometry shader
1694*35238bceSAndroid Build Coastguard Worker };
1695*35238bceSAndroid Build Coastguard Worker
1696*35238bceSAndroid Build Coastguard Worker PointSizeCase(Context &context, const char *name, const char *description, int flags);
1697*35238bceSAndroid Build Coastguard Worker ~PointSizeCase(void);
1698*35238bceSAndroid Build Coastguard Worker
1699*35238bceSAndroid Build Coastguard Worker static std::string genTestCaseName(int flags);
1700*35238bceSAndroid Build Coastguard Worker static std::string genTestCaseDescription(int flags);
1701*35238bceSAndroid Build Coastguard Worker
1702*35238bceSAndroid Build Coastguard Worker private:
1703*35238bceSAndroid Build Coastguard Worker void init(void);
1704*35238bceSAndroid Build Coastguard Worker void deinit(void);
1705*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
1706*35238bceSAndroid Build Coastguard Worker
1707*35238bceSAndroid Build Coastguard Worker void checkExtensions(void) const;
1708*35238bceSAndroid Build Coastguard Worker void checkPointSizeRequirements(void) const;
1709*35238bceSAndroid Build Coastguard Worker
1710*35238bceSAndroid Build Coastguard Worker void renderTo(tcu::Surface &dst);
1711*35238bceSAndroid Build Coastguard Worker bool verifyImage(const tcu::Surface &src);
1712*35238bceSAndroid Build Coastguard Worker int getExpectedPointSize(void) const;
1713*35238bceSAndroid Build Coastguard Worker
1714*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void) const;
1715*35238bceSAndroid Build Coastguard Worker std::string genFragmentSource(void) const;
1716*35238bceSAndroid Build Coastguard Worker std::string genTessellationControlSource(void) const;
1717*35238bceSAndroid Build Coastguard Worker std::string genTessellationEvaluationSource(void) const;
1718*35238bceSAndroid Build Coastguard Worker std::string genGeometrySource(void) const;
1719*35238bceSAndroid Build Coastguard Worker
1720*35238bceSAndroid Build Coastguard Worker enum
1721*35238bceSAndroid Build Coastguard Worker {
1722*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 32,
1723*35238bceSAndroid Build Coastguard Worker };
1724*35238bceSAndroid Build Coastguard Worker
1725*35238bceSAndroid Build Coastguard Worker const int m_flags;
1726*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
1727*35238bceSAndroid Build Coastguard Worker };
1728*35238bceSAndroid Build Coastguard Worker
PointSizeCase(Context & context,const char * name,const char * description,int flags)1729*35238bceSAndroid Build Coastguard Worker PointSizeCase::PointSizeCase(Context &context, const char *name, const char *description, int flags)
1730*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
1731*35238bceSAndroid Build Coastguard Worker , m_flags(flags)
1732*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
1733*35238bceSAndroid Build Coastguard Worker {
1734*35238bceSAndroid Build Coastguard Worker }
1735*35238bceSAndroid Build Coastguard Worker
~PointSizeCase(void)1736*35238bceSAndroid Build Coastguard Worker PointSizeCase::~PointSizeCase(void)
1737*35238bceSAndroid Build Coastguard Worker {
1738*35238bceSAndroid Build Coastguard Worker deinit();
1739*35238bceSAndroid Build Coastguard Worker }
1740*35238bceSAndroid Build Coastguard Worker
genTestCaseName(int flags)1741*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genTestCaseName(int flags)
1742*35238bceSAndroid Build Coastguard Worker {
1743*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1744*35238bceSAndroid Build Coastguard Worker
1745*35238bceSAndroid Build Coastguard Worker // join per-bit descriptions into a single string with '_' separator
1746*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_VERTEX_SET)
1747*35238bceSAndroid Build Coastguard Worker buf << "vertex_set";
1748*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_CONTROL_SET)
1749*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_CONTROL_SET - 1)) ? ("_") : ("")) << "control_set";
1750*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_EVALUATION_SET)
1751*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_EVALUATION_SET - 1)) ? ("_") : ("")) << "evaluation_set";
1752*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_ADD)
1753*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_ADD - 1)) ? ("_") : ("")) << "control_pass_eval_add";
1754*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_DONT_SET)
1755*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_DONT_SET - 1)) ? ("_") : ("")) << "eval_default";
1756*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_SET)
1757*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_SET - 1)) ? ("_") : ("")) << "geometry_set";
1758*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_ADD)
1759*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_ADD - 1)) ? ("_") : ("")) << "geometry_add";
1760*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_DONT_SET)
1761*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_DONT_SET - 1)) ? ("_") : ("")) << "geometry_default";
1762*35238bceSAndroid Build Coastguard Worker
1763*35238bceSAndroid Build Coastguard Worker return buf.str();
1764*35238bceSAndroid Build Coastguard Worker }
1765*35238bceSAndroid Build Coastguard Worker
genTestCaseDescription(int flags)1766*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genTestCaseDescription(int flags)
1767*35238bceSAndroid Build Coastguard Worker {
1768*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1769*35238bceSAndroid Build Coastguard Worker
1770*35238bceSAndroid Build Coastguard Worker // join per-bit descriptions into a single string with ", " separator
1771*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_VERTEX_SET)
1772*35238bceSAndroid Build Coastguard Worker buf << "set point size in vertex shader";
1773*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_CONTROL_SET)
1774*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_CONTROL_SET - 1)) ? (", ") : (""))
1775*35238bceSAndroid Build Coastguard Worker << "set point size in tessellation control shader";
1776*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_EVALUATION_SET)
1777*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_EVALUATION_SET - 1)) ? (", ") : (""))
1778*35238bceSAndroid Build Coastguard Worker << "set point size in tessellation evaluation shader";
1779*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_ADD)
1780*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_ADD - 1)) ? (", ") : ("")) << "add to point size in tessellation shader";
1781*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_TESSELLATION_DONT_SET)
1782*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_TESSELLATION_DONT_SET - 1)) ? (", ") : (""))
1783*35238bceSAndroid Build Coastguard Worker << "don't set point size in tessellation evaluation shader";
1784*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_SET)
1785*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_SET - 1)) ? (", ") : ("")) << "set point size in geometry shader";
1786*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_ADD)
1787*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_ADD - 1)) ? (", ") : ("")) << "add to point size in geometry shader";
1788*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_GEOMETRY_DONT_SET)
1789*35238bceSAndroid Build Coastguard Worker buf << ((flags & (FLAG_GEOMETRY_DONT_SET - 1)) ? (", ") : ("")) << "don't set point size in geometry shader";
1790*35238bceSAndroid Build Coastguard Worker
1791*35238bceSAndroid Build Coastguard Worker return buf.str();
1792*35238bceSAndroid Build Coastguard Worker }
1793*35238bceSAndroid Build Coastguard Worker
init(void)1794*35238bceSAndroid Build Coastguard Worker void PointSizeCase::init(void)
1795*35238bceSAndroid Build Coastguard Worker {
1796*35238bceSAndroid Build Coastguard Worker checkExtensions();
1797*35238bceSAndroid Build Coastguard Worker checkPointSizeRequirements();
1798*35238bceSAndroid Build Coastguard Worker
1799*35238bceSAndroid Build Coastguard Worker if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
1800*35238bceSAndroid Build Coastguard Worker {
1801*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().enable(GL_PROGRAM_POINT_SIZE);
1802*35238bceSAndroid Build Coastguard Worker }
1803*35238bceSAndroid Build Coastguard Worker
1804*35238bceSAndroid Build Coastguard Worker // log
1805*35238bceSAndroid Build Coastguard Worker
1806*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_VERTEX_SET)
1807*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in vertex shader to 2.0."
1808*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1809*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_CONTROL_SET)
1810*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1811*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message
1812*35238bceSAndroid Build Coastguard Worker << "Setting point size in tessellation control shader to 4.0. (And ignoring it in evaluation)."
1813*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1814*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_EVALUATION_SET)
1815*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in tessellation evaluation shader to 4.0."
1816*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1817*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_ADD)
1818*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1819*35238bceSAndroid Build Coastguard Worker << "Reading point size in tessellation control shader and adding 2.0 to it in evaluation."
1820*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1821*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_DONT_SET)
1822*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1823*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message
1824*35238bceSAndroid Build Coastguard Worker << "Not setting point size in tessellation evaluation shader (resulting in the default point size)."
1825*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1826*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SET)
1827*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in geometry shader to 6.0."
1828*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1829*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_ADD)
1830*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Reading point size in geometry shader and adding 2.0."
1831*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1832*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_DONT_SET)
1833*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1834*35238bceSAndroid Build Coastguard Worker << "Not setting point size in geometry shader (resulting in the default point size)."
1835*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1836*35238bceSAndroid Build Coastguard Worker
1837*35238bceSAndroid Build Coastguard Worker // program
1838*35238bceSAndroid Build Coastguard Worker
1839*35238bceSAndroid Build Coastguard Worker {
1840*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
1841*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(genVertexSource()) << glu::FragmentSource(genFragmentSource());
1842*35238bceSAndroid Build Coastguard Worker
1843*35238bceSAndroid Build Coastguard Worker if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD |
1844*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_DONT_SET))
1845*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(genTessellationControlSource())
1846*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(genTessellationEvaluationSource());
1847*35238bceSAndroid Build Coastguard Worker
1848*35238bceSAndroid Build Coastguard Worker if (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD | FLAG_GEOMETRY_DONT_SET))
1849*35238bceSAndroid Build Coastguard Worker sources << glu::GeometrySource(genGeometrySource());
1850*35238bceSAndroid Build Coastguard Worker
1851*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources);
1852*35238bceSAndroid Build Coastguard Worker
1853*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
1854*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
1855*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
1856*35238bceSAndroid Build Coastguard Worker }
1857*35238bceSAndroid Build Coastguard Worker }
1858*35238bceSAndroid Build Coastguard Worker
deinit(void)1859*35238bceSAndroid Build Coastguard Worker void PointSizeCase::deinit(void)
1860*35238bceSAndroid Build Coastguard Worker {
1861*35238bceSAndroid Build Coastguard Worker if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
1862*35238bceSAndroid Build Coastguard Worker {
1863*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().disable(GL_PROGRAM_POINT_SIZE);
1864*35238bceSAndroid Build Coastguard Worker }
1865*35238bceSAndroid Build Coastguard Worker
1866*35238bceSAndroid Build Coastguard Worker delete m_program;
1867*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
1868*35238bceSAndroid Build Coastguard Worker }
1869*35238bceSAndroid Build Coastguard Worker
iterate(void)1870*35238bceSAndroid Build Coastguard Worker PointSizeCase::IterateResult PointSizeCase::iterate(void)
1871*35238bceSAndroid Build Coastguard Worker {
1872*35238bceSAndroid Build Coastguard Worker tcu::Surface resultImage(RENDER_SIZE, RENDER_SIZE);
1873*35238bceSAndroid Build Coastguard Worker
1874*35238bceSAndroid Build Coastguard Worker renderTo(resultImage);
1875*35238bceSAndroid Build Coastguard Worker
1876*35238bceSAndroid Build Coastguard Worker if (verifyImage(resultImage))
1877*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1878*35238bceSAndroid Build Coastguard Worker else
1879*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
1880*35238bceSAndroid Build Coastguard Worker
1881*35238bceSAndroid Build Coastguard Worker return STOP;
1882*35238bceSAndroid Build Coastguard Worker }
1883*35238bceSAndroid Build Coastguard Worker
checkExtensions(void) const1884*35238bceSAndroid Build Coastguard Worker void PointSizeCase::checkExtensions(void) const
1885*35238bceSAndroid Build Coastguard Worker {
1886*35238bceSAndroid Build Coastguard Worker glu::ContextType contextType = m_context.getRenderContext().getType();
1887*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(contextType, glu::ApiType::core(4, 5)))
1888*35238bceSAndroid Build Coastguard Worker return;
1889*35238bceSAndroid Build Coastguard Worker
1890*35238bceSAndroid Build Coastguard Worker std::vector<std::string> requiredExtensions;
1891*35238bceSAndroid Build Coastguard Worker const bool supportsES32 = glu::contextSupports(contextType, glu::ApiType::es(3, 2));
1892*35238bceSAndroid Build Coastguard Worker bool allOk = true;
1893*35238bceSAndroid Build Coastguard Worker
1894*35238bceSAndroid Build Coastguard Worker if ((m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD |
1895*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_DONT_SET)) &&
1896*35238bceSAndroid Build Coastguard Worker !supportsES32)
1897*35238bceSAndroid Build Coastguard Worker requiredExtensions.push_back("GL_EXT_tessellation_shader");
1898*35238bceSAndroid Build Coastguard Worker
1899*35238bceSAndroid Build Coastguard Worker if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD))
1900*35238bceSAndroid Build Coastguard Worker requiredExtensions.push_back("GL_EXT_tessellation_point_size");
1901*35238bceSAndroid Build Coastguard Worker
1902*35238bceSAndroid Build Coastguard Worker if ((m_flags & (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD | FLAG_GEOMETRY_DONT_SET))) && !supportsES32)
1903*35238bceSAndroid Build Coastguard Worker requiredExtensions.push_back("GL_EXT_geometry_shader");
1904*35238bceSAndroid Build Coastguard Worker
1905*35238bceSAndroid Build Coastguard Worker if (m_flags & (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD)))
1906*35238bceSAndroid Build Coastguard Worker requiredExtensions.push_back("GL_EXT_geometry_point_size");
1907*35238bceSAndroid Build Coastguard Worker
1908*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)requiredExtensions.size(); ++ndx)
1909*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported(requiredExtensions[ndx].c_str()))
1910*35238bceSAndroid Build Coastguard Worker allOk = false;
1911*35238bceSAndroid Build Coastguard Worker
1912*35238bceSAndroid Build Coastguard Worker if (!allOk)
1913*35238bceSAndroid Build Coastguard Worker {
1914*35238bceSAndroid Build Coastguard Worker std::ostringstream extensionList;
1915*35238bceSAndroid Build Coastguard Worker
1916*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)requiredExtensions.size(); ++ndx)
1917*35238bceSAndroid Build Coastguard Worker {
1918*35238bceSAndroid Build Coastguard Worker if (ndx != 0)
1919*35238bceSAndroid Build Coastguard Worker extensionList << ", ";
1920*35238bceSAndroid Build Coastguard Worker extensionList << requiredExtensions[ndx];
1921*35238bceSAndroid Build Coastguard Worker }
1922*35238bceSAndroid Build Coastguard Worker
1923*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires {" + extensionList.str() + "} extension(s)");
1924*35238bceSAndroid Build Coastguard Worker }
1925*35238bceSAndroid Build Coastguard Worker }
1926*35238bceSAndroid Build Coastguard Worker
checkPointSizeRequirements(void) const1927*35238bceSAndroid Build Coastguard Worker void PointSizeCase::checkPointSizeRequirements(void) const
1928*35238bceSAndroid Build Coastguard Worker {
1929*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1930*35238bceSAndroid Build Coastguard Worker float aliasedSizeRange[2] = {0.0f, 0.0f};
1931*35238bceSAndroid Build Coastguard Worker const int requiredSize = getExpectedPointSize();
1932*35238bceSAndroid Build Coastguard Worker
1933*35238bceSAndroid Build Coastguard Worker gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, aliasedSizeRange);
1934*35238bceSAndroid Build Coastguard Worker
1935*35238bceSAndroid Build Coastguard Worker if (float(requiredSize) > aliasedSizeRange[1])
1936*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires point size " + de::toString(requiredSize));
1937*35238bceSAndroid Build Coastguard Worker }
1938*35238bceSAndroid Build Coastguard Worker
renderTo(tcu::Surface & dst)1939*35238bceSAndroid Build Coastguard Worker void PointSizeCase::renderTo(tcu::Surface &dst)
1940*35238bceSAndroid Build Coastguard Worker {
1941*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1942*35238bceSAndroid Build Coastguard Worker const bool tessellationActive = (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET |
1943*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_ADD | FLAG_TESSELLATION_DONT_SET)) != 0;
1944*35238bceSAndroid Build Coastguard Worker const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
1945*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
1946*35238bceSAndroid Build Coastguard Worker
1947*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering single point." << tcu::TestLog::EndMessage;
1948*35238bceSAndroid Build Coastguard Worker
1949*35238bceSAndroid Build Coastguard Worker if (positionLocation == -1)
1950*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("Attribute a_position location was -1");
1951*35238bceSAndroid Build Coastguard Worker
1952*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
1953*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1954*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
1955*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1956*35238bceSAndroid Build Coastguard Worker
1957*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
1958*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao");
1959*35238bceSAndroid Build Coastguard Worker
1960*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
1961*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
1962*35238bceSAndroid Build Coastguard Worker
1963*35238bceSAndroid Build Coastguard Worker gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f);
1964*35238bceSAndroid Build Coastguard Worker
1965*35238bceSAndroid Build Coastguard Worker if (tessellationActive)
1966*35238bceSAndroid Build Coastguard Worker {
1967*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 1);
1968*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
1969*35238bceSAndroid Build Coastguard Worker
1970*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 1);
1971*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches");
1972*35238bceSAndroid Build Coastguard Worker }
1973*35238bceSAndroid Build Coastguard Worker else
1974*35238bceSAndroid Build Coastguard Worker {
1975*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_POINTS, 0, 1);
1976*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "draw points");
1977*35238bceSAndroid Build Coastguard Worker }
1978*35238bceSAndroid Build Coastguard Worker
1979*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1980*35238bceSAndroid Build Coastguard Worker }
1981*35238bceSAndroid Build Coastguard Worker
verifyImage(const tcu::Surface & src)1982*35238bceSAndroid Build Coastguard Worker bool PointSizeCase::verifyImage(const tcu::Surface &src)
1983*35238bceSAndroid Build Coastguard Worker {
1984*35238bceSAndroid Build Coastguard Worker const bool MSAATarget = (m_context.getRenderTarget().getNumSamples() > 1);
1985*35238bceSAndroid Build Coastguard Worker const int expectedSize = getExpectedPointSize();
1986*35238bceSAndroid Build Coastguard Worker
1987*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying rendered point size. Expecting " << expectedSize
1988*35238bceSAndroid Build Coastguard Worker << " pixels." << tcu::TestLog::EndMessage;
1989*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Image("RenderImage", "Rendered image", src.getAccess());
1990*35238bceSAndroid Build Coastguard Worker
1991*35238bceSAndroid Build Coastguard Worker {
1992*35238bceSAndroid Build Coastguard Worker bool resultAreaFound = false;
1993*35238bceSAndroid Build Coastguard Worker tcu::IVec4 resultArea;
1994*35238bceSAndroid Build Coastguard Worker
1995*35238bceSAndroid Build Coastguard Worker // Find rasterization output area
1996*35238bceSAndroid Build Coastguard Worker
1997*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < src.getHeight(); ++y)
1998*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < src.getWidth(); ++x)
1999*35238bceSAndroid Build Coastguard Worker {
2000*35238bceSAndroid Build Coastguard Worker if (!isBlack(src.getPixel(x, y)))
2001*35238bceSAndroid Build Coastguard Worker {
2002*35238bceSAndroid Build Coastguard Worker if (!resultAreaFound)
2003*35238bceSAndroid Build Coastguard Worker {
2004*35238bceSAndroid Build Coastguard Worker // first fragment
2005*35238bceSAndroid Build Coastguard Worker resultArea = tcu::IVec4(x, y, x + 1, y + 1);
2006*35238bceSAndroid Build Coastguard Worker resultAreaFound = true;
2007*35238bceSAndroid Build Coastguard Worker }
2008*35238bceSAndroid Build Coastguard Worker else
2009*35238bceSAndroid Build Coastguard Worker {
2010*35238bceSAndroid Build Coastguard Worker // union area
2011*35238bceSAndroid Build Coastguard Worker resultArea.x() = de::min(resultArea.x(), x);
2012*35238bceSAndroid Build Coastguard Worker resultArea.y() = de::min(resultArea.y(), y);
2013*35238bceSAndroid Build Coastguard Worker resultArea.z() = de::max(resultArea.z(), x + 1);
2014*35238bceSAndroid Build Coastguard Worker resultArea.w() = de::max(resultArea.w(), y + 1);
2015*35238bceSAndroid Build Coastguard Worker }
2016*35238bceSAndroid Build Coastguard Worker }
2017*35238bceSAndroid Build Coastguard Worker }
2018*35238bceSAndroid Build Coastguard Worker
2019*35238bceSAndroid Build Coastguard Worker if (!resultAreaFound)
2020*35238bceSAndroid Build Coastguard Worker {
2021*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verification failed, could not find any point fragments."
2022*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2023*35238bceSAndroid Build Coastguard Worker return false;
2024*35238bceSAndroid Build Coastguard Worker }
2025*35238bceSAndroid Build Coastguard Worker
2026*35238bceSAndroid Build Coastguard Worker // verify area size
2027*35238bceSAndroid Build Coastguard Worker if (MSAATarget)
2028*35238bceSAndroid Build Coastguard Worker {
2029*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 pointSize = resultArea.swizzle(2, 3) - resultArea.swizzle(0, 1);
2030*35238bceSAndroid Build Coastguard Worker
2031*35238bceSAndroid Build Coastguard Worker // MSAA: edges may be a little fuzzy
2032*35238bceSAndroid Build Coastguard Worker if (de::abs(pointSize.x() - pointSize.y()) > 1)
2033*35238bceSAndroid Build Coastguard Worker {
2034*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2035*35238bceSAndroid Build Coastguard Worker << "ERROR! Rasterized point is not a square. Detected point size was " << pointSize
2036*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2037*35238bceSAndroid Build Coastguard Worker return false;
2038*35238bceSAndroid Build Coastguard Worker }
2039*35238bceSAndroid Build Coastguard Worker
2040*35238bceSAndroid Build Coastguard Worker // MSAA may produce larger areas, allow one pixel larger
2041*35238bceSAndroid Build Coastguard Worker if (expectedSize != de::max(pointSize.x(), pointSize.y()) &&
2042*35238bceSAndroid Build Coastguard Worker (expectedSize + 1) != de::max(pointSize.x(), pointSize.y()))
2043*35238bceSAndroid Build Coastguard Worker {
2044*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Point size invalid, expected " << expectedSize
2045*35238bceSAndroid Build Coastguard Worker << ", got " << de::max(pointSize.x(), pointSize.y()) << tcu::TestLog::EndMessage;
2046*35238bceSAndroid Build Coastguard Worker return false;
2047*35238bceSAndroid Build Coastguard Worker }
2048*35238bceSAndroid Build Coastguard Worker }
2049*35238bceSAndroid Build Coastguard Worker else
2050*35238bceSAndroid Build Coastguard Worker {
2051*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 pointSize = resultArea.swizzle(2, 3) - resultArea.swizzle(0, 1);
2052*35238bceSAndroid Build Coastguard Worker
2053*35238bceSAndroid Build Coastguard Worker if (pointSize.x() != pointSize.y())
2054*35238bceSAndroid Build Coastguard Worker {
2055*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2056*35238bceSAndroid Build Coastguard Worker << "ERROR! Rasterized point is not a square. Point size was " << pointSize
2057*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2058*35238bceSAndroid Build Coastguard Worker return false;
2059*35238bceSAndroid Build Coastguard Worker }
2060*35238bceSAndroid Build Coastguard Worker
2061*35238bceSAndroid Build Coastguard Worker if (pointSize.x() != expectedSize)
2062*35238bceSAndroid Build Coastguard Worker {
2063*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Point size invalid, expected " << expectedSize
2064*35238bceSAndroid Build Coastguard Worker << ", got " << pointSize.x() << tcu::TestLog::EndMessage;
2065*35238bceSAndroid Build Coastguard Worker return false;
2066*35238bceSAndroid Build Coastguard Worker }
2067*35238bceSAndroid Build Coastguard Worker }
2068*35238bceSAndroid Build Coastguard Worker }
2069*35238bceSAndroid Build Coastguard Worker
2070*35238bceSAndroid Build Coastguard Worker return true;
2071*35238bceSAndroid Build Coastguard Worker }
2072*35238bceSAndroid Build Coastguard Worker
getExpectedPointSize(void) const2073*35238bceSAndroid Build Coastguard Worker int PointSizeCase::getExpectedPointSize(void) const
2074*35238bceSAndroid Build Coastguard Worker {
2075*35238bceSAndroid Build Coastguard Worker int addition = 0;
2076*35238bceSAndroid Build Coastguard Worker
2077*35238bceSAndroid Build Coastguard Worker // geometry
2078*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_DONT_SET)
2079*35238bceSAndroid Build Coastguard Worker return 1;
2080*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_SET)
2081*35238bceSAndroid Build Coastguard Worker return 6;
2082*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_ADD)
2083*35238bceSAndroid Build Coastguard Worker addition += 2;
2084*35238bceSAndroid Build Coastguard Worker
2085*35238bceSAndroid Build Coastguard Worker // tessellation
2086*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_EVALUATION_SET)
2087*35238bceSAndroid Build Coastguard Worker return 4 + addition;
2088*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_TESSELLATION_ADD)
2089*35238bceSAndroid Build Coastguard Worker addition += 2;
2090*35238bceSAndroid Build Coastguard Worker else if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_DONT_SET))
2091*35238bceSAndroid Build Coastguard Worker {
2092*35238bceSAndroid Build Coastguard Worker DE_ASSERT((m_flags & FLAG_GEOMETRY_ADD) == 0); // reading pointSize undefined
2093*35238bceSAndroid Build Coastguard Worker return 1;
2094*35238bceSAndroid Build Coastguard Worker }
2095*35238bceSAndroid Build Coastguard Worker
2096*35238bceSAndroid Build Coastguard Worker // vertex
2097*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_VERTEX_SET)
2098*35238bceSAndroid Build Coastguard Worker return 2 + addition;
2099*35238bceSAndroid Build Coastguard Worker
2100*35238bceSAndroid Build Coastguard Worker // undefined
2101*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2102*35238bceSAndroid Build Coastguard Worker return -1;
2103*35238bceSAndroid Build Coastguard Worker }
2104*35238bceSAndroid Build Coastguard Worker
genVertexSource(void) const2105*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genVertexSource(void) const
2106*35238bceSAndroid Build Coastguard Worker {
2107*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2108*35238bceSAndroid Build Coastguard Worker
2109*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2110*35238bceSAndroid Build Coastguard Worker << "in highp vec4 a_position;\n"
2111*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2112*35238bceSAndroid Build Coastguard Worker << "{\n"
2113*35238bceSAndroid Build Coastguard Worker << " gl_Position = a_position;\n";
2114*35238bceSAndroid Build Coastguard Worker
2115*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_VERTEX_SET)
2116*35238bceSAndroid Build Coastguard Worker buf << " gl_PointSize = 2.0;\n";
2117*35238bceSAndroid Build Coastguard Worker
2118*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2119*35238bceSAndroid Build Coastguard Worker
2120*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2121*35238bceSAndroid Build Coastguard Worker }
2122*35238bceSAndroid Build Coastguard Worker
genFragmentSource(void) const2123*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genFragmentSource(void) const
2124*35238bceSAndroid Build Coastguard Worker {
2125*35238bceSAndroid Build Coastguard Worker return specializeShader(s_whiteOutputFragmentShader, m_context.getRenderContext().getType());
2126*35238bceSAndroid Build Coastguard Worker }
2127*35238bceSAndroid Build Coastguard Worker
genTessellationControlSource(void) const2128*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genTessellationControlSource(void) const
2129*35238bceSAndroid Build Coastguard Worker {
2130*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2131*35238bceSAndroid Build Coastguard Worker
2132*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2133*35238bceSAndroid Build Coastguard Worker << "${EXTENSION_TESSELATION_SHADER}"
2134*35238bceSAndroid Build Coastguard Worker << ((m_flags & FLAG_TESSELLATION_DONT_SET) ? ("") : ("${EXTENSION_TESSELATION_POINT_SIZE}"))
2135*35238bceSAndroid Build Coastguard Worker << "layout(vertices = 1) out;\n"
2136*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2137*35238bceSAndroid Build Coastguard Worker << "{\n"
2138*35238bceSAndroid Build Coastguard Worker << " gl_TessLevelOuter[0] = 3.0;\n"
2139*35238bceSAndroid Build Coastguard Worker << " gl_TessLevelOuter[1] = 3.0;\n"
2140*35238bceSAndroid Build Coastguard Worker << " gl_TessLevelOuter[2] = 3.0;\n"
2141*35238bceSAndroid Build Coastguard Worker << " gl_TessLevelInner[0] = 3.0;\n"
2142*35238bceSAndroid Build Coastguard Worker << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
2143*35238bceSAndroid Build Coastguard Worker
2144*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_ADD)
2145*35238bceSAndroid Build Coastguard Worker buf << " // pass as is to eval\n"
2146*35238bceSAndroid Build Coastguard Worker << " gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n";
2147*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_TESSELLATION_CONTROL_SET)
2148*35238bceSAndroid Build Coastguard Worker buf << " // thrown away\n"
2149*35238bceSAndroid Build Coastguard Worker << " gl_out[gl_InvocationID].gl_PointSize = 4.0;\n";
2150*35238bceSAndroid Build Coastguard Worker
2151*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2152*35238bceSAndroid Build Coastguard Worker
2153*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2154*35238bceSAndroid Build Coastguard Worker }
2155*35238bceSAndroid Build Coastguard Worker
genTessellationEvaluationSource(void) const2156*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genTessellationEvaluationSource(void) const
2157*35238bceSAndroid Build Coastguard Worker {
2158*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2159*35238bceSAndroid Build Coastguard Worker
2160*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2161*35238bceSAndroid Build Coastguard Worker << "${EXTENSION_TESSELATION_SHADER}"
2162*35238bceSAndroid Build Coastguard Worker << ((m_flags & FLAG_TESSELLATION_DONT_SET) ? ("") : ("${EXTENSION_TESSELATION_POINT_SIZE}"))
2163*35238bceSAndroid Build Coastguard Worker << "layout(triangles, point_mode) in;\n"
2164*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2165*35238bceSAndroid Build Coastguard Worker << "{\n"
2166*35238bceSAndroid Build Coastguard Worker << " // hide all but one vertex\n"
2167*35238bceSAndroid Build Coastguard Worker << " if (gl_TessCoord.x < 0.99)\n"
2168*35238bceSAndroid Build Coastguard Worker << " gl_Position = vec4(-2.0, 0.0, 0.0, 1.0);\n"
2169*35238bceSAndroid Build Coastguard Worker << " else\n"
2170*35238bceSAndroid Build Coastguard Worker << " gl_Position = gl_in[0].gl_Position;\n";
2171*35238bceSAndroid Build Coastguard Worker
2172*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_ADD)
2173*35238bceSAndroid Build Coastguard Worker buf << "\n"
2174*35238bceSAndroid Build Coastguard Worker << " // add to point size\n"
2175*35238bceSAndroid Build Coastguard Worker << " gl_PointSize = gl_in[0].gl_PointSize + 2.0;\n";
2176*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_TESSELLATION_EVALUATION_SET)
2177*35238bceSAndroid Build Coastguard Worker buf << "\n"
2178*35238bceSAndroid Build Coastguard Worker << " // set point size\n"
2179*35238bceSAndroid Build Coastguard Worker << " gl_PointSize = 4.0;\n";
2180*35238bceSAndroid Build Coastguard Worker
2181*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2182*35238bceSAndroid Build Coastguard Worker
2183*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2184*35238bceSAndroid Build Coastguard Worker }
2185*35238bceSAndroid Build Coastguard Worker
genGeometrySource(void) const2186*35238bceSAndroid Build Coastguard Worker std::string PointSizeCase::genGeometrySource(void) const
2187*35238bceSAndroid Build Coastguard Worker {
2188*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2189*35238bceSAndroid Build Coastguard Worker
2190*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2191*35238bceSAndroid Build Coastguard Worker << "${EXTENSION_GEOMETRY_SHADER}"
2192*35238bceSAndroid Build Coastguard Worker << ((m_flags & FLAG_GEOMETRY_DONT_SET) ? ("") : ("${EXTENSION_GEOMETRY_POINT_SIZE}")) << "layout (points) in;\n"
2193*35238bceSAndroid Build Coastguard Worker << "layout (points, max_vertices=1) out;\n"
2194*35238bceSAndroid Build Coastguard Worker << "\n"
2195*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2196*35238bceSAndroid Build Coastguard Worker << "{\n";
2197*35238bceSAndroid Build Coastguard Worker
2198*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SET)
2199*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = gl_in[0].gl_Position;\n"
2200*35238bceSAndroid Build Coastguard Worker << " gl_PointSize = 6.0;\n";
2201*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_ADD)
2202*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = gl_in[0].gl_Position;\n"
2203*35238bceSAndroid Build Coastguard Worker << " gl_PointSize = gl_in[0].gl_PointSize + 2.0;\n";
2204*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_DONT_SET)
2205*35238bceSAndroid Build Coastguard Worker buf << " gl_Position = gl_in[0].gl_Position;\n";
2206*35238bceSAndroid Build Coastguard Worker
2207*35238bceSAndroid Build Coastguard Worker buf << " EmitVertex();\n"
2208*35238bceSAndroid Build Coastguard Worker << "}\n";
2209*35238bceSAndroid Build Coastguard Worker
2210*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2211*35238bceSAndroid Build Coastguard Worker }
2212*35238bceSAndroid Build Coastguard Worker
2213*35238bceSAndroid Build Coastguard Worker class AllowedRenderFailureException : public std::runtime_error
2214*35238bceSAndroid Build Coastguard Worker {
2215*35238bceSAndroid Build Coastguard Worker public:
AllowedRenderFailureException(const char * message)2216*35238bceSAndroid Build Coastguard Worker AllowedRenderFailureException(const char *message) : std::runtime_error(message)
2217*35238bceSAndroid Build Coastguard Worker {
2218*35238bceSAndroid Build Coastguard Worker }
2219*35238bceSAndroid Build Coastguard Worker };
2220*35238bceSAndroid Build Coastguard Worker
2221*35238bceSAndroid Build Coastguard Worker class GridRenderCase : public TestCase
2222*35238bceSAndroid Build Coastguard Worker {
2223*35238bceSAndroid Build Coastguard Worker public:
2224*35238bceSAndroid Build Coastguard Worker enum Flags
2225*35238bceSAndroid Build Coastguard Worker {
2226*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_MAX_SPEC = 0x0001,
2227*35238bceSAndroid Build Coastguard Worker FLAG_TESSELLATION_MAX_IMPLEMENTATION = 0x0002,
2228*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_MAX_SPEC = 0x0004,
2229*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_MAX_IMPLEMENTATION = 0x0008,
2230*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC = 0x0010,
2231*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION = 0x0020,
2232*35238bceSAndroid Build Coastguard Worker
2233*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_SCATTER_INSTANCES = 0x0040,
2234*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_SCATTER_PRIMITIVES = 0x0080,
2235*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_SEPARATE_PRIMITIVES =
2236*35238bceSAndroid Build Coastguard Worker 0x0100, //!< if set, geometry shader outputs separate grid cells and not continuous slices
2237*35238bceSAndroid Build Coastguard Worker FLAG_GEOMETRY_SCATTER_LAYERS = 0x0200,
2238*35238bceSAndroid Build Coastguard Worker
2239*35238bceSAndroid Build Coastguard Worker FLAG_ALLOW_OUT_OF_MEMORY = 0x0400, //!< allow draw command to set GL_OUT_OF_MEMORY
2240*35238bceSAndroid Build Coastguard Worker };
2241*35238bceSAndroid Build Coastguard Worker
2242*35238bceSAndroid Build Coastguard Worker GridRenderCase(Context &context, const char *name, const char *description, int flags);
2243*35238bceSAndroid Build Coastguard Worker ~GridRenderCase(void);
2244*35238bceSAndroid Build Coastguard Worker
2245*35238bceSAndroid Build Coastguard Worker private:
2246*35238bceSAndroid Build Coastguard Worker void init(void);
2247*35238bceSAndroid Build Coastguard Worker void deinit(void);
2248*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
2249*35238bceSAndroid Build Coastguard Worker
2250*35238bceSAndroid Build Coastguard Worker void renderTo(std::vector<tcu::Surface> &dst);
2251*35238bceSAndroid Build Coastguard Worker bool verifyResultLayer(int layerNdx, const tcu::Surface &dst);
2252*35238bceSAndroid Build Coastguard Worker
2253*35238bceSAndroid Build Coastguard Worker std::string getVertexSource(void);
2254*35238bceSAndroid Build Coastguard Worker std::string getFragmentSource(void);
2255*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(int tessLevel);
2256*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(int tessLevel);
2257*35238bceSAndroid Build Coastguard Worker std::string getGeometryShaderSource(int numPrimitives, int numInstances, int tessLevel);
2258*35238bceSAndroid Build Coastguard Worker
2259*35238bceSAndroid Build Coastguard Worker enum
2260*35238bceSAndroid Build Coastguard Worker {
2261*35238bceSAndroid Build Coastguard Worker RENDER_SIZE = 256
2262*35238bceSAndroid Build Coastguard Worker };
2263*35238bceSAndroid Build Coastguard Worker
2264*35238bceSAndroid Build Coastguard Worker std::string m_description;
2265*35238bceSAndroid Build Coastguard Worker
2266*35238bceSAndroid Build Coastguard Worker const int m_flags;
2267*35238bceSAndroid Build Coastguard Worker
2268*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
2269*35238bceSAndroid Build Coastguard Worker uint32_t m_texture;
2270*35238bceSAndroid Build Coastguard Worker int m_numLayers;
2271*35238bceSAndroid Build Coastguard Worker };
2272*35238bceSAndroid Build Coastguard Worker
GridRenderCase(Context & context,const char * name,const char * description,int flags)2273*35238bceSAndroid Build Coastguard Worker GridRenderCase::GridRenderCase(Context &context, const char *name, const char *description, int flags)
2274*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
2275*35238bceSAndroid Build Coastguard Worker , m_description(description)
2276*35238bceSAndroid Build Coastguard Worker , m_flags(flags)
2277*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
2278*35238bceSAndroid Build Coastguard Worker , m_texture(0)
2279*35238bceSAndroid Build Coastguard Worker , m_numLayers(1)
2280*35238bceSAndroid Build Coastguard Worker {
2281*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_TESSELLATION_MAX_SPEC) == 0) || ((m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) == 0));
2282*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_GEOMETRY_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) == 0));
2283*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) == 0) ||
2284*35238bceSAndroid Build Coastguard Worker ((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) == 0));
2285*35238bceSAndroid Build Coastguard Worker DE_ASSERT(((m_flags & (FLAG_GEOMETRY_SCATTER_PRIMITIVES | FLAG_GEOMETRY_SCATTER_LAYERS)) != 0) ==
2286*35238bceSAndroid Build Coastguard Worker ((m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) != 0));
2287*35238bceSAndroid Build Coastguard Worker }
2288*35238bceSAndroid Build Coastguard Worker
~GridRenderCase(void)2289*35238bceSAndroid Build Coastguard Worker GridRenderCase::~GridRenderCase(void)
2290*35238bceSAndroid Build Coastguard Worker {
2291*35238bceSAndroid Build Coastguard Worker deinit();
2292*35238bceSAndroid Build Coastguard Worker }
2293*35238bceSAndroid Build Coastguard Worker
init(void)2294*35238bceSAndroid Build Coastguard Worker void GridRenderCase::init(void)
2295*35238bceSAndroid Build Coastguard Worker {
2296*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2297*35238bceSAndroid Build Coastguard Worker glu::ContextType contextType = m_context.getRenderContext().getType();
2298*35238bceSAndroid Build Coastguard Worker const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
2299*35238bceSAndroid Build Coastguard Worker glu::contextSupports(contextType, glu::ApiType::core(4, 5));
2300*35238bceSAndroid Build Coastguard Worker
2301*35238bceSAndroid Build Coastguard Worker // Requirements
2302*35238bceSAndroid Build Coastguard Worker
2303*35238bceSAndroid Build Coastguard Worker if (!supportsES32orGL45 && (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
2304*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")))
2305*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
2306*35238bceSAndroid Build Coastguard Worker
2307*35238bceSAndroid Build Coastguard Worker if ((m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) == 0)
2308*35238bceSAndroid Build Coastguard Worker {
2309*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < RENDER_SIZE ||
2310*35238bceSAndroid Build Coastguard Worker m_context.getRenderTarget().getHeight() < RENDER_SIZE)
2311*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" +
2312*35238bceSAndroid Build Coastguard Worker de::toString<int>(RENDER_SIZE) + " or larger render target.");
2313*35238bceSAndroid Build Coastguard Worker }
2314*35238bceSAndroid Build Coastguard Worker
2315*35238bceSAndroid Build Coastguard Worker // Log
2316*35238bceSAndroid Build Coastguard Worker
2317*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2318*35238bceSAndroid Build Coastguard Worker << "Testing tessellation and geometry shaders that output a large number of primitives.\n"
2319*35238bceSAndroid Build Coastguard Worker << m_description << tcu::TestLog::EndMessage;
2320*35238bceSAndroid Build Coastguard Worker
2321*35238bceSAndroid Build Coastguard Worker // Render target
2322*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS)
2323*35238bceSAndroid Build Coastguard Worker {
2324*35238bceSAndroid Build Coastguard Worker // set limits
2325*35238bceSAndroid Build Coastguard Worker m_numLayers = 8;
2326*35238bceSAndroid Build Coastguard Worker
2327*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to 2d texture array, numLayers = " << m_numLayers
2328*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2329*35238bceSAndroid Build Coastguard Worker
2330*35238bceSAndroid Build Coastguard Worker gl.genTextures(1, &m_texture);
2331*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
2332*35238bceSAndroid Build Coastguard Worker gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, RENDER_SIZE, RENDER_SIZE, m_numLayers);
2333*35238bceSAndroid Build Coastguard Worker
2334*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2335*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2336*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2337*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2338*35238bceSAndroid Build Coastguard Worker
2339*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen texture");
2340*35238bceSAndroid Build Coastguard Worker }
2341*35238bceSAndroid Build Coastguard Worker
2342*35238bceSAndroid Build Coastguard Worker // Gen program
2343*35238bceSAndroid Build Coastguard Worker {
2344*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
2345*35238bceSAndroid Build Coastguard Worker int tessGenLevel = -1;
2346*35238bceSAndroid Build Coastguard Worker
2347*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource());
2348*35238bceSAndroid Build Coastguard Worker
2349*35238bceSAndroid Build Coastguard Worker // Tessellation limits
2350*35238bceSAndroid Build Coastguard Worker {
2351*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION)
2352*35238bceSAndroid Build Coastguard Worker {
2353*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_TESS_GEN_LEVEL, &tessGenLevel);
2354*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query tessellation limits");
2355*35238bceSAndroid Build Coastguard Worker }
2356*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_TESSELLATION_MAX_SPEC)
2357*35238bceSAndroid Build Coastguard Worker {
2358*35238bceSAndroid Build Coastguard Worker tessGenLevel = 64;
2359*35238bceSAndroid Build Coastguard Worker }
2360*35238bceSAndroid Build Coastguard Worker else
2361*35238bceSAndroid Build Coastguard Worker {
2362*35238bceSAndroid Build Coastguard Worker tessGenLevel = 5;
2363*35238bceSAndroid Build Coastguard Worker }
2364*35238bceSAndroid Build Coastguard Worker
2365*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation level: " << tessGenLevel << ", mode = quad.\n"
2366*35238bceSAndroid Build Coastguard Worker << "\tEach input patch produces " << (tessGenLevel * tessGenLevel) << " ("
2367*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2) << " triangles)\n"
2368*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2369*35238bceSAndroid Build Coastguard Worker
2370*35238bceSAndroid Build Coastguard Worker sources << glu::TessellationControlSource(getTessellationControlSource(tessGenLevel))
2371*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource(tessGenLevel));
2372*35238bceSAndroid Build Coastguard Worker }
2373*35238bceSAndroid Build Coastguard Worker
2374*35238bceSAndroid Build Coastguard Worker // Geometry limits
2375*35238bceSAndroid Build Coastguard Worker {
2376*35238bceSAndroid Build Coastguard Worker int geometryOutputComponents = -1;
2377*35238bceSAndroid Build Coastguard Worker int geometryOutputVertices = -1;
2378*35238bceSAndroid Build Coastguard Worker int geometryTotalOutputComponents = -1;
2379*35238bceSAndroid Build Coastguard Worker int geometryShaderInvocations = -1;
2380*35238bceSAndroid Build Coastguard Worker bool logGeometryLimits = false;
2381*35238bceSAndroid Build Coastguard Worker bool logInvocationLimits = false;
2382*35238bceSAndroid Build Coastguard Worker
2383*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION)
2384*35238bceSAndroid Build Coastguard Worker {
2385*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2386*35238bceSAndroid Build Coastguard Worker << "Using implementation maximum geometry shader output limits."
2387*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2388*35238bceSAndroid Build Coastguard Worker
2389*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &geometryOutputComponents);
2390*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &geometryOutputVertices);
2391*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &geometryTotalOutputComponents);
2392*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry limits");
2393*35238bceSAndroid Build Coastguard Worker
2394*35238bceSAndroid Build Coastguard Worker logGeometryLimits = true;
2395*35238bceSAndroid Build Coastguard Worker }
2396*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_MAX_SPEC)
2397*35238bceSAndroid Build Coastguard Worker {
2398*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2399*35238bceSAndroid Build Coastguard Worker << "Using geometry shader extension minimum maximum output limits."
2400*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2401*35238bceSAndroid Build Coastguard Worker
2402*35238bceSAndroid Build Coastguard Worker geometryOutputComponents = 128;
2403*35238bceSAndroid Build Coastguard Worker geometryOutputVertices = 256;
2404*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents = 1024;
2405*35238bceSAndroid Build Coastguard Worker logGeometryLimits = true;
2406*35238bceSAndroid Build Coastguard Worker }
2407*35238bceSAndroid Build Coastguard Worker else
2408*35238bceSAndroid Build Coastguard Worker {
2409*35238bceSAndroid Build Coastguard Worker geometryOutputComponents = 128;
2410*35238bceSAndroid Build Coastguard Worker geometryOutputVertices = 16;
2411*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents = 1024;
2412*35238bceSAndroid Build Coastguard Worker }
2413*35238bceSAndroid Build Coastguard Worker
2414*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION)
2415*35238bceSAndroid Build Coastguard Worker {
2416*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &geometryShaderInvocations);
2417*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry invocation limits");
2418*35238bceSAndroid Build Coastguard Worker
2419*35238bceSAndroid Build Coastguard Worker logInvocationLimits = true;
2420*35238bceSAndroid Build Coastguard Worker }
2421*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC)
2422*35238bceSAndroid Build Coastguard Worker {
2423*35238bceSAndroid Build Coastguard Worker geometryShaderInvocations = 32;
2424*35238bceSAndroid Build Coastguard Worker logInvocationLimits = true;
2425*35238bceSAndroid Build Coastguard Worker }
2426*35238bceSAndroid Build Coastguard Worker else
2427*35238bceSAndroid Build Coastguard Worker {
2428*35238bceSAndroid Build Coastguard Worker geometryShaderInvocations = 4;
2429*35238bceSAndroid Build Coastguard Worker }
2430*35238bceSAndroid Build Coastguard Worker
2431*35238bceSAndroid Build Coastguard Worker if (logGeometryLimits || logInvocationLimits)
2432*35238bceSAndroid Build Coastguard Worker {
2433*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder msg(&m_testCtx.getLog());
2434*35238bceSAndroid Build Coastguard Worker
2435*35238bceSAndroid Build Coastguard Worker msg << "Geometry shader, targeting following limits:\n";
2436*35238bceSAndroid Build Coastguard Worker
2437*35238bceSAndroid Build Coastguard Worker if (logGeometryLimits)
2438*35238bceSAndroid Build Coastguard Worker msg << "\tGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = " << geometryOutputComponents << "\n"
2439*35238bceSAndroid Build Coastguard Worker << "\tGL_MAX_GEOMETRY_OUTPUT_VERTICES = " << geometryOutputVertices << "\n"
2440*35238bceSAndroid Build Coastguard Worker << "\tGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << geometryTotalOutputComponents << "\n";
2441*35238bceSAndroid Build Coastguard Worker
2442*35238bceSAndroid Build Coastguard Worker if (logInvocationLimits)
2443*35238bceSAndroid Build Coastguard Worker msg << "\tGL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << geometryShaderInvocations;
2444*35238bceSAndroid Build Coastguard Worker
2445*35238bceSAndroid Build Coastguard Worker msg << tcu::TestLog::EndMessage;
2446*35238bceSAndroid Build Coastguard Worker }
2447*35238bceSAndroid Build Coastguard Worker
2448*35238bceSAndroid Build Coastguard Worker {
2449*35238bceSAndroid Build Coastguard Worker const bool separatePrimitives = (m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) != 0;
2450*35238bceSAndroid Build Coastguard Worker const int numComponentsPerVertex = 8; // vec4 pos, vec4 color
2451*35238bceSAndroid Build Coastguard Worker int numVerticesPerInvocation;
2452*35238bceSAndroid Build Coastguard Worker int numPrimitivesPerInvocation;
2453*35238bceSAndroid Build Coastguard Worker int geometryVerticesPerPrimitive;
2454*35238bceSAndroid Build Coastguard Worker int geometryPrimitivesOutPerPrimitive;
2455*35238bceSAndroid Build Coastguard Worker
2456*35238bceSAndroid Build Coastguard Worker if (separatePrimitives)
2457*35238bceSAndroid Build Coastguard Worker {
2458*35238bceSAndroid Build Coastguard Worker const int numComponentLimit = geometryTotalOutputComponents / (4 * numComponentsPerVertex);
2459*35238bceSAndroid Build Coastguard Worker const int numOutputLimit = geometryOutputVertices / 4;
2460*35238bceSAndroid Build Coastguard Worker
2461*35238bceSAndroid Build Coastguard Worker numPrimitivesPerInvocation = de::min(numComponentLimit, numOutputLimit);
2462*35238bceSAndroid Build Coastguard Worker numVerticesPerInvocation = numPrimitivesPerInvocation * 4;
2463*35238bceSAndroid Build Coastguard Worker }
2464*35238bceSAndroid Build Coastguard Worker else
2465*35238bceSAndroid Build Coastguard Worker {
2466*35238bceSAndroid Build Coastguard Worker // If FLAG_GEOMETRY_SEPARATE_PRIMITIVES is not set, geometry shader fills a rectangle area in slices.
2467*35238bceSAndroid Build Coastguard Worker // Each slice is a triangle strip and is generated by a single shader invocation.
2468*35238bceSAndroid Build Coastguard Worker // One slice with 4 segment ends (nodes) and 3 segments:
2469*35238bceSAndroid Build Coastguard Worker // .__.__.__.
2470*35238bceSAndroid Build Coastguard Worker // |\ |\ |\ |
2471*35238bceSAndroid Build Coastguard Worker // |_\|_\|_\|
2472*35238bceSAndroid Build Coastguard Worker
2473*35238bceSAndroid Build Coastguard Worker const int numSliceNodesComponentLimit =
2474*35238bceSAndroid Build Coastguard Worker geometryTotalOutputComponents / (2 * numComponentsPerVertex); // each node 2 vertices
2475*35238bceSAndroid Build Coastguard Worker const int numSliceNodesOutputLimit = geometryOutputVertices / 2; // each node 2 vertices
2476*35238bceSAndroid Build Coastguard Worker const int numSliceNodes = de::min(numSliceNodesComponentLimit, numSliceNodesOutputLimit);
2477*35238bceSAndroid Build Coastguard Worker
2478*35238bceSAndroid Build Coastguard Worker numVerticesPerInvocation = numSliceNodes * 2;
2479*35238bceSAndroid Build Coastguard Worker numPrimitivesPerInvocation = (numSliceNodes - 1) * 2;
2480*35238bceSAndroid Build Coastguard Worker }
2481*35238bceSAndroid Build Coastguard Worker
2482*35238bceSAndroid Build Coastguard Worker geometryVerticesPerPrimitive = numVerticesPerInvocation * geometryShaderInvocations;
2483*35238bceSAndroid Build Coastguard Worker geometryPrimitivesOutPerPrimitive = numPrimitivesPerInvocation * geometryShaderInvocations;
2484*35238bceSAndroid Build Coastguard Worker
2485*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Geometry shader:\n"
2486*35238bceSAndroid Build Coastguard Worker << "\tTotal output vertex count per invocation: " << (numVerticesPerInvocation)
2487*35238bceSAndroid Build Coastguard Worker << "\n"
2488*35238bceSAndroid Build Coastguard Worker << "\tTotal output primitive count per invocation: " << (numPrimitivesPerInvocation)
2489*35238bceSAndroid Build Coastguard Worker << "\n"
2490*35238bceSAndroid Build Coastguard Worker << "\tNumber of invocations per primitive: " << geometryShaderInvocations << "\n"
2491*35238bceSAndroid Build Coastguard Worker << "\tTotal output vertex count per input primitive: "
2492*35238bceSAndroid Build Coastguard Worker << (geometryVerticesPerPrimitive) << "\n"
2493*35238bceSAndroid Build Coastguard Worker << "\tTotal output primitive count per input primitive: "
2494*35238bceSAndroid Build Coastguard Worker << (geometryPrimitivesOutPerPrimitive) << "\n"
2495*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2496*35238bceSAndroid Build Coastguard Worker
2497*35238bceSAndroid Build Coastguard Worker sources << glu::GeometrySource(
2498*35238bceSAndroid Build Coastguard Worker getGeometryShaderSource(numPrimitivesPerInvocation, geometryShaderInvocations, tessGenLevel));
2499*35238bceSAndroid Build Coastguard Worker
2500*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program:\n"
2501*35238bceSAndroid Build Coastguard Worker << "\tTotal program output vertices count per input patch: "
2502*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2 * geometryVerticesPerPrimitive) << "\n"
2503*35238bceSAndroid Build Coastguard Worker << "\tTotal program output primitive count per input patch: "
2504*35238bceSAndroid Build Coastguard Worker << (tessGenLevel * tessGenLevel * 2 * geometryPrimitivesOutPerPrimitive) << "\n"
2505*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2506*35238bceSAndroid Build Coastguard Worker }
2507*35238bceSAndroid Build Coastguard Worker }
2508*35238bceSAndroid Build Coastguard Worker
2509*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources);
2510*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
2511*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
2512*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("failed to build program");
2513*35238bceSAndroid Build Coastguard Worker }
2514*35238bceSAndroid Build Coastguard Worker }
2515*35238bceSAndroid Build Coastguard Worker
deinit(void)2516*35238bceSAndroid Build Coastguard Worker void GridRenderCase::deinit(void)
2517*35238bceSAndroid Build Coastguard Worker {
2518*35238bceSAndroid Build Coastguard Worker delete m_program;
2519*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
2520*35238bceSAndroid Build Coastguard Worker
2521*35238bceSAndroid Build Coastguard Worker if (m_texture)
2522*35238bceSAndroid Build Coastguard Worker {
2523*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture);
2524*35238bceSAndroid Build Coastguard Worker m_texture = 0;
2525*35238bceSAndroid Build Coastguard Worker }
2526*35238bceSAndroid Build Coastguard Worker }
2527*35238bceSAndroid Build Coastguard Worker
iterate(void)2528*35238bceSAndroid Build Coastguard Worker GridRenderCase::IterateResult GridRenderCase::iterate(void)
2529*35238bceSAndroid Build Coastguard Worker {
2530*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Surface> renderedLayers(m_numLayers);
2531*35238bceSAndroid Build Coastguard Worker bool allLayersOk = true;
2532*35238bceSAndroid Build Coastguard Worker
2533*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numLayers; ++ndx)
2534*35238bceSAndroid Build Coastguard Worker renderedLayers[ndx].setSize(RENDER_SIZE, RENDER_SIZE);
2535*35238bceSAndroid Build Coastguard Worker
2536*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2537*35238bceSAndroid Build Coastguard Worker << "Rendering single point at the origin. Expecting yellow and green colored grid-like image. "
2538*35238bceSAndroid Build Coastguard Worker "(High-frequency grid may appear unicolored)."
2539*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2540*35238bceSAndroid Build Coastguard Worker
2541*35238bceSAndroid Build Coastguard Worker try
2542*35238bceSAndroid Build Coastguard Worker {
2543*35238bceSAndroid Build Coastguard Worker renderTo(renderedLayers);
2544*35238bceSAndroid Build Coastguard Worker }
2545*35238bceSAndroid Build Coastguard Worker catch (const AllowedRenderFailureException &ex)
2546*35238bceSAndroid Build Coastguard Worker {
2547*35238bceSAndroid Build Coastguard Worker // Got accepted failure
2548*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Could not render, reason: " << ex.what() << "\n"
2549*35238bceSAndroid Build Coastguard Worker << "Failure is allowed." << tcu::TestLog::EndMessage;
2550*35238bceSAndroid Build Coastguard Worker
2551*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2552*35238bceSAndroid Build Coastguard Worker return STOP;
2553*35238bceSAndroid Build Coastguard Worker }
2554*35238bceSAndroid Build Coastguard Worker
2555*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numLayers; ++ndx)
2556*35238bceSAndroid Build Coastguard Worker allLayersOk &= verifyResultLayer(ndx, renderedLayers[ndx]);
2557*35238bceSAndroid Build Coastguard Worker
2558*35238bceSAndroid Build Coastguard Worker if (allLayersOk)
2559*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2560*35238bceSAndroid Build Coastguard Worker else
2561*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2562*35238bceSAndroid Build Coastguard Worker return STOP;
2563*35238bceSAndroid Build Coastguard Worker }
2564*35238bceSAndroid Build Coastguard Worker
renderTo(std::vector<tcu::Surface> & dst)2565*35238bceSAndroid Build Coastguard Worker void GridRenderCase::renderTo(std::vector<tcu::Surface> &dst)
2566*35238bceSAndroid Build Coastguard Worker {
2567*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2568*35238bceSAndroid Build Coastguard Worker const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
2569*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
2570*35238bceSAndroid Build Coastguard Worker de::MovePtr<glu::Framebuffer> fbo;
2571*35238bceSAndroid Build Coastguard Worker
2572*35238bceSAndroid Build Coastguard Worker if (positionLocation == -1)
2573*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("Attribute a_position location was -1");
2574*35238bceSAndroid Build Coastguard Worker
2575*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, dst.front().getWidth(), dst.front().getHeight());
2576*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2577*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
2578*35238bceSAndroid Build Coastguard Worker
2579*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
2580*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao");
2581*35238bceSAndroid Build Coastguard Worker
2582*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
2583*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
2584*35238bceSAndroid Build Coastguard Worker
2585*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 1);
2586*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
2587*35238bceSAndroid Build Coastguard Worker
2588*35238bceSAndroid Build Coastguard Worker gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f);
2589*35238bceSAndroid Build Coastguard Worker
2590*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS)
2591*35238bceSAndroid Build Coastguard Worker {
2592*35238bceSAndroid Build Coastguard Worker // clear texture contents
2593*35238bceSAndroid Build Coastguard Worker {
2594*35238bceSAndroid Build Coastguard Worker glu::Framebuffer clearFbo(m_context.getRenderContext());
2595*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, *clearFbo);
2596*35238bceSAndroid Build Coastguard Worker
2597*35238bceSAndroid Build Coastguard Worker for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
2598*35238bceSAndroid Build Coastguard Worker {
2599*35238bceSAndroid Build Coastguard Worker gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, layerNdx);
2600*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
2601*35238bceSAndroid Build Coastguard Worker }
2602*35238bceSAndroid Build Coastguard Worker
2603*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear tex contents");
2604*35238bceSAndroid Build Coastguard Worker }
2605*35238bceSAndroid Build Coastguard Worker
2606*35238bceSAndroid Build Coastguard Worker // create and bind layered fbo
2607*35238bceSAndroid Build Coastguard Worker
2608*35238bceSAndroid Build Coastguard Worker fbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
2609*35238bceSAndroid Build Coastguard Worker
2610*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, **fbo);
2611*35238bceSAndroid Build Coastguard Worker gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0);
2612*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo");
2613*35238bceSAndroid Build Coastguard Worker }
2614*35238bceSAndroid Build Coastguard Worker else
2615*35238bceSAndroid Build Coastguard Worker {
2616*35238bceSAndroid Build Coastguard Worker // clear viewport
2617*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
2618*35238bceSAndroid Build Coastguard Worker }
2619*35238bceSAndroid Build Coastguard Worker
2620*35238bceSAndroid Build Coastguard Worker // draw
2621*35238bceSAndroid Build Coastguard Worker {
2622*35238bceSAndroid Build Coastguard Worker glw::GLenum glerror;
2623*35238bceSAndroid Build Coastguard Worker
2624*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 1);
2625*35238bceSAndroid Build Coastguard Worker
2626*35238bceSAndroid Build Coastguard Worker glerror = gl.getError();
2627*35238bceSAndroid Build Coastguard Worker if (glerror == GL_OUT_OF_MEMORY && (m_flags & FLAG_ALLOW_OUT_OF_MEMORY))
2628*35238bceSAndroid Build Coastguard Worker throw AllowedRenderFailureException("got GL_OUT_OF_MEMORY while drawing");
2629*35238bceSAndroid Build Coastguard Worker
2630*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(glerror, "draw patches");
2631*35238bceSAndroid Build Coastguard Worker }
2632*35238bceSAndroid Build Coastguard Worker
2633*35238bceSAndroid Build Coastguard Worker // Read layers
2634*35238bceSAndroid Build Coastguard Worker
2635*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS)
2636*35238bceSAndroid Build Coastguard Worker {
2637*35238bceSAndroid Build Coastguard Worker glu::Framebuffer readFbo(m_context.getRenderContext());
2638*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, *readFbo);
2639*35238bceSAndroid Build Coastguard Worker
2640*35238bceSAndroid Build Coastguard Worker for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx)
2641*35238bceSAndroid Build Coastguard Worker {
2642*35238bceSAndroid Build Coastguard Worker gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, layerNdx);
2643*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst[layerNdx].getAccess());
2644*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
2645*35238bceSAndroid Build Coastguard Worker }
2646*35238bceSAndroid Build Coastguard Worker }
2647*35238bceSAndroid Build Coastguard Worker else
2648*35238bceSAndroid Build Coastguard Worker {
2649*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.front().getAccess());
2650*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
2651*35238bceSAndroid Build Coastguard Worker }
2652*35238bceSAndroid Build Coastguard Worker }
2653*35238bceSAndroid Build Coastguard Worker
verifyResultLayer(int layerNdx,const tcu::Surface & image)2654*35238bceSAndroid Build Coastguard Worker bool GridRenderCase::verifyResultLayer(int layerNdx, const tcu::Surface &image)
2655*35238bceSAndroid Build Coastguard Worker {
2656*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(image.getWidth(), image.getHeight());
2657*35238bceSAndroid Build Coastguard Worker bool foundError = false;
2658*35238bceSAndroid Build Coastguard Worker
2659*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2660*35238bceSAndroid Build Coastguard Worker
2661*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output layer " << layerNdx << tcu::TestLog::EndMessage;
2662*35238bceSAndroid Build Coastguard Worker
2663*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < image.getHeight(); ++y)
2664*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < image.getWidth(); ++x)
2665*35238bceSAndroid Build Coastguard Worker {
2666*35238bceSAndroid Build Coastguard Worker const int threshold = 8;
2667*35238bceSAndroid Build Coastguard Worker const tcu::RGBA color = image.getPixel(x, y);
2668*35238bceSAndroid Build Coastguard Worker
2669*35238bceSAndroid Build Coastguard Worker // Color must be a linear combination of green and yellow
2670*35238bceSAndroid Build Coastguard Worker if (color.getGreen() < 255 - threshold || color.getBlue() > threshold)
2671*35238bceSAndroid Build Coastguard Worker {
2672*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(x, y, tcu::RGBA::red());
2673*35238bceSAndroid Build Coastguard Worker foundError = true;
2674*35238bceSAndroid Build Coastguard Worker }
2675*35238bceSAndroid Build Coastguard Worker }
2676*35238bceSAndroid Build Coastguard Worker
2677*35238bceSAndroid Build Coastguard Worker if (!foundError)
2678*35238bceSAndroid Build Coastguard Worker {
2679*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image valid." << tcu::TestLog::EndMessage
2680*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
2681*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
2682*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
2683*35238bceSAndroid Build Coastguard Worker return true;
2684*35238bceSAndroid Build Coastguard Worker }
2685*35238bceSAndroid Build Coastguard Worker else
2686*35238bceSAndroid Build Coastguard Worker {
2687*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed, found invalid pixels."
2688*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage
2689*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
2690*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
2691*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
2692*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndImageSet;
2693*35238bceSAndroid Build Coastguard Worker return false;
2694*35238bceSAndroid Build Coastguard Worker }
2695*35238bceSAndroid Build Coastguard Worker }
2696*35238bceSAndroid Build Coastguard Worker
getVertexSource(void)2697*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getVertexSource(void)
2698*35238bceSAndroid Build Coastguard Worker {
2699*35238bceSAndroid Build Coastguard Worker return specializeShader(s_positionVertexShader, m_context.getRenderContext().getType());
2700*35238bceSAndroid Build Coastguard Worker }
2701*35238bceSAndroid Build Coastguard Worker
getFragmentSource(void)2702*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getFragmentSource(void)
2703*35238bceSAndroid Build Coastguard Worker {
2704*35238bceSAndroid Build Coastguard Worker const char *source = "${VERSION_DECL}\n"
2705*35238bceSAndroid Build Coastguard Worker "flat in mediump vec4 v_color;\n"
2706*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
2707*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
2708*35238bceSAndroid Build Coastguard Worker "{\n"
2709*35238bceSAndroid Build Coastguard Worker " fragColor = v_color;\n"
2710*35238bceSAndroid Build Coastguard Worker "}\n";
2711*35238bceSAndroid Build Coastguard Worker
2712*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
2713*35238bceSAndroid Build Coastguard Worker }
2714*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(int tessLevel)2715*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getTessellationControlSource(int tessLevel)
2716*35238bceSAndroid Build Coastguard Worker {
2717*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2718*35238bceSAndroid Build Coastguard Worker
2719*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2720*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
2721*35238bceSAndroid Build Coastguard Worker "layout(vertices=1) out;\n"
2722*35238bceSAndroid Build Coastguard Worker "\n"
2723*35238bceSAndroid Build Coastguard Worker "void main()\n"
2724*35238bceSAndroid Build Coastguard Worker "{\n"
2725*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2726*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = "
2727*35238bceSAndroid Build Coastguard Worker << tessLevel
2728*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2729*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = "
2730*35238bceSAndroid Build Coastguard Worker << tessLevel
2731*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2732*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = "
2733*35238bceSAndroid Build Coastguard Worker << tessLevel
2734*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2735*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = "
2736*35238bceSAndroid Build Coastguard Worker << tessLevel
2737*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2738*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = "
2739*35238bceSAndroid Build Coastguard Worker << tessLevel
2740*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2741*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = "
2742*35238bceSAndroid Build Coastguard Worker << tessLevel
2743*35238bceSAndroid Build Coastguard Worker << ".0;\n"
2744*35238bceSAndroid Build Coastguard Worker "}\n";
2745*35238bceSAndroid Build Coastguard Worker
2746*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2747*35238bceSAndroid Build Coastguard Worker }
2748*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(int tessLevel)2749*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getTessellationEvaluationSource(int tessLevel)
2750*35238bceSAndroid Build Coastguard Worker {
2751*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2752*35238bceSAndroid Build Coastguard Worker
2753*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2754*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
2755*35238bceSAndroid Build Coastguard Worker "layout(quads) in;\n"
2756*35238bceSAndroid Build Coastguard Worker "\n"
2757*35238bceSAndroid Build Coastguard Worker "out mediump ivec2 v_tessellationGridPosition;\n"
2758*35238bceSAndroid Build Coastguard Worker "\n"
2759*35238bceSAndroid Build Coastguard Worker "// note: No need to use precise gl_Position since position does not depend on order\n"
2760*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
2761*35238bceSAndroid Build Coastguard Worker "{\n";
2762*35238bceSAndroid Build Coastguard Worker
2763*35238bceSAndroid Build Coastguard Worker if (m_flags & (FLAG_GEOMETRY_SCATTER_INSTANCES | FLAG_GEOMETRY_SCATTER_PRIMITIVES | FLAG_GEOMETRY_SCATTER_LAYERS))
2764*35238bceSAndroid Build Coastguard Worker buf << " // Cover only a small area in a corner. The area will be expanded in geometry shader to cover "
2765*35238bceSAndroid Build Coastguard Worker "whole viewport\n"
2766*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(gl_TessCoord.x * 0.3 - 1.0, gl_TessCoord.y * 0.3 - 1.0, 0.0, 1.0);\n";
2767*35238bceSAndroid Build Coastguard Worker else
2768*35238bceSAndroid Build Coastguard Worker buf << " // Fill the whole viewport\n"
2769*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";
2770*35238bceSAndroid Build Coastguard Worker
2771*35238bceSAndroid Build Coastguard Worker buf << " // Calculate position in tessellation grid\n"
2772*35238bceSAndroid Build Coastguard Worker " v_tessellationGridPosition = ivec2(round(gl_TessCoord.xy * float("
2773*35238bceSAndroid Build Coastguard Worker << tessLevel
2774*35238bceSAndroid Build Coastguard Worker << ")));\n"
2775*35238bceSAndroid Build Coastguard Worker "}\n";
2776*35238bceSAndroid Build Coastguard Worker
2777*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2778*35238bceSAndroid Build Coastguard Worker }
2779*35238bceSAndroid Build Coastguard Worker
getGeometryShaderSource(int numPrimitives,int numInstances,int tessLevel)2780*35238bceSAndroid Build Coastguard Worker std::string GridRenderCase::getGeometryShaderSource(int numPrimitives, int numInstances, int tessLevel)
2781*35238bceSAndroid Build Coastguard Worker {
2782*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2783*35238bceSAndroid Build Coastguard Worker
2784*35238bceSAndroid Build Coastguard Worker buf << "${VERSION_DECL}\n"
2785*35238bceSAndroid Build Coastguard Worker "${EXTENSION_GEOMETRY_SHADER}"
2786*35238bceSAndroid Build Coastguard Worker "layout(triangles, invocations="
2787*35238bceSAndroid Build Coastguard Worker << numInstances
2788*35238bceSAndroid Build Coastguard Worker << ") in;\n"
2789*35238bceSAndroid Build Coastguard Worker "layout(triangle_strip, max_vertices="
2790*35238bceSAndroid Build Coastguard Worker << ((m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) ? (4 * numPrimitives) : (numPrimitives + 2))
2791*35238bceSAndroid Build Coastguard Worker << ") out;\n"
2792*35238bceSAndroid Build Coastguard Worker "\n"
2793*35238bceSAndroid Build Coastguard Worker "in mediump ivec2 v_tessellationGridPosition[];\n"
2794*35238bceSAndroid Build Coastguard Worker "flat out highp vec4 v_color;\n"
2795*35238bceSAndroid Build Coastguard Worker "\n"
2796*35238bceSAndroid Build Coastguard Worker "void main ()\n"
2797*35238bceSAndroid Build Coastguard Worker "{\n"
2798*35238bceSAndroid Build Coastguard Worker " const float equalThreshold = 0.001;\n"
2799*35238bceSAndroid Build Coastguard Worker " const float gapOffset = 0.0001; // subdivision performed by the geometry shader might produce gaps. "
2800*35238bceSAndroid Build Coastguard Worker "Fill potential gaps by enlarging the output slice a little.\n"
2801*35238bceSAndroid Build Coastguard Worker "\n"
2802*35238bceSAndroid Build Coastguard Worker " // Input triangle is generated from an axis-aligned rectangle by splitting it in half\n"
2803*35238bceSAndroid Build Coastguard Worker " // Original rectangle can be found by finding the bounding AABB of the triangle\n"
2804*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"
2805*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"
2806*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"
2807*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"
2808*35238bceSAndroid Build Coastguard Worker "\n"
2809*35238bceSAndroid Build Coastguard Worker " // Location in tessellation grid\n"
2810*35238bceSAndroid Build Coastguard Worker " ivec2 gridPosition = ivec2(min(v_tessellationGridPosition[0], min(v_tessellationGridPosition[1], "
2811*35238bceSAndroid Build Coastguard Worker "v_tessellationGridPosition[2])));\n"
2812*35238bceSAndroid Build Coastguard Worker "\n"
2813*35238bceSAndroid Build Coastguard Worker " // Which triangle of the two that split the grid cell\n"
2814*35238bceSAndroid Build Coastguard Worker " int numVerticesOnBottomEdge = 0;\n"
2815*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < 3; ++ndx)\n"
2816*35238bceSAndroid Build Coastguard Worker " if (abs(gl_in[ndx].gl_Position.y - aabb.w) < equalThreshold)\n"
2817*35238bceSAndroid Build Coastguard Worker " ++numVerticesOnBottomEdge;\n"
2818*35238bceSAndroid Build Coastguard Worker " bool isBottomTriangle = numVerticesOnBottomEdge == 2;\n"
2819*35238bceSAndroid Build Coastguard Worker "\n";
2820*35238bceSAndroid Build Coastguard Worker
2821*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SCATTER_PRIMITIVES)
2822*35238bceSAndroid Build Coastguard Worker {
2823*35238bceSAndroid Build Coastguard Worker // scatter primitives
2824*35238bceSAndroid Build Coastguard Worker buf << " // Draw grid cells\n"
2825*35238bceSAndroid Build Coastguard Worker " int inputTriangleNdx = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n"
2826*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < "
2827*35238bceSAndroid Build Coastguard Worker << numPrimitives
2828*35238bceSAndroid Build Coastguard Worker << "; ++ndx)\n"
2829*35238bceSAndroid Build Coastguard Worker " {\n"
2830*35238bceSAndroid Build Coastguard Worker " ivec2 dstGridSize = ivec2("
2831*35238bceSAndroid Build Coastguard Worker << tessLevel << " * " << numPrimitives << ", 2 * " << tessLevel << " * " << numInstances
2832*35238bceSAndroid Build Coastguard Worker << ");\n"
2833*35238bceSAndroid Build Coastguard Worker " ivec2 dstGridNdx = ivec2("
2834*35238bceSAndroid Build Coastguard Worker << tessLevel << " * ndx + gridPosition.x, " << tessLevel
2835*35238bceSAndroid Build Coastguard Worker << " * inputTriangleNdx + 2 * gridPosition.y + ndx * 127) % dstGridSize;\n"
2836*35238bceSAndroid Build Coastguard Worker " vec4 dstArea;\n"
2837*35238bceSAndroid Build Coastguard Worker " dstArea.x = float(dstGridNdx.x) / float(dstGridSize.x) * 2.0 - 1.0 - gapOffset;\n"
2838*35238bceSAndroid Build Coastguard Worker " dstArea.y = float(dstGridNdx.y) / float(dstGridSize.y) * 2.0 - 1.0 - gapOffset;\n"
2839*35238bceSAndroid Build Coastguard Worker " dstArea.z = float(dstGridNdx.x+1) / float(dstGridSize.x) * 2.0 - 1.0 + gapOffset;\n"
2840*35238bceSAndroid Build Coastguard Worker " dstArea.w = float(dstGridNdx.y+1) / float(dstGridSize.y) * 2.0 - 1.0 + gapOffset;\n"
2841*35238bceSAndroid Build Coastguard Worker "\n"
2842*35238bceSAndroid Build Coastguard Worker " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
2843*35238bceSAndroid Build Coastguard Worker " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
2844*35238bceSAndroid Build Coastguard Worker " vec4 outputColor = (((dstGridNdx.y + dstGridNdx.x) % 2) == 0) ? (green) : (yellow);\n"
2845*35238bceSAndroid Build Coastguard Worker "\n"
2846*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.x, dstArea.y, 0.0, 1.0);\n"
2847*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2848*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2849*35238bceSAndroid Build Coastguard Worker "\n"
2850*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.x, dstArea.w, 0.0, 1.0);\n"
2851*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2852*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2853*35238bceSAndroid Build Coastguard Worker "\n"
2854*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.z, dstArea.y, 0.0, 1.0);\n"
2855*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2856*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2857*35238bceSAndroid Build Coastguard Worker "\n"
2858*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.z, dstArea.w, 0.0, 1.0);\n"
2859*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2860*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2861*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
2862*35238bceSAndroid Build Coastguard Worker " }\n";
2863*35238bceSAndroid Build Coastguard Worker }
2864*35238bceSAndroid Build Coastguard Worker else if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS)
2865*35238bceSAndroid Build Coastguard Worker {
2866*35238bceSAndroid Build Coastguard Worker // Number of subrectangle instances = num layers
2867*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_numLayers == numInstances * 2);
2868*35238bceSAndroid Build Coastguard Worker
2869*35238bceSAndroid Build Coastguard Worker buf << " // Draw grid cells, send each primitive to a separate layer\n"
2870*35238bceSAndroid Build Coastguard Worker " int baseLayer = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n"
2871*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < "
2872*35238bceSAndroid Build Coastguard Worker << numPrimitives
2873*35238bceSAndroid Build Coastguard Worker << "; ++ndx)\n"
2874*35238bceSAndroid Build Coastguard Worker " {\n"
2875*35238bceSAndroid Build Coastguard Worker " ivec2 dstGridSize = ivec2("
2876*35238bceSAndroid Build Coastguard Worker << tessLevel << " * " << numPrimitives << ", " << tessLevel
2877*35238bceSAndroid Build Coastguard Worker << ");\n"
2878*35238bceSAndroid Build Coastguard Worker " ivec2 dstGridNdx = ivec2((gridPosition.x * "
2879*35238bceSAndroid Build Coastguard Worker << numPrimitives
2880*35238bceSAndroid Build Coastguard Worker << " * 7 + ndx)*13, (gridPosition.y * 127 + ndx) * 19) % dstGridSize;\n"
2881*35238bceSAndroid Build Coastguard Worker " vec4 dstArea;\n"
2882*35238bceSAndroid Build Coastguard Worker " dstArea.x = float(dstGridNdx.x) / float(dstGridSize.x) * 2.0 - 1.0 - gapOffset;\n"
2883*35238bceSAndroid Build Coastguard Worker " dstArea.y = float(dstGridNdx.y) / float(dstGridSize.y) * 2.0 - 1.0 - gapOffset;\n"
2884*35238bceSAndroid Build Coastguard Worker " dstArea.z = float(dstGridNdx.x+1) / float(dstGridSize.x) * 2.0 - 1.0 + gapOffset;\n"
2885*35238bceSAndroid Build Coastguard Worker " dstArea.w = float(dstGridNdx.y+1) / float(dstGridSize.y) * 2.0 - 1.0 + gapOffset;\n"
2886*35238bceSAndroid Build Coastguard Worker "\n"
2887*35238bceSAndroid Build Coastguard Worker " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
2888*35238bceSAndroid Build Coastguard Worker " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
2889*35238bceSAndroid Build Coastguard Worker " vec4 outputColor = (((dstGridNdx.y + dstGridNdx.x) % 2) == 0) ? (green) : (yellow);\n"
2890*35238bceSAndroid Build Coastguard Worker "\n"
2891*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.x, dstArea.y, 0.0, 1.0);\n"
2892*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2893*35238bceSAndroid Build Coastguard Worker " gl_Layer = ((baseLayer + ndx) * 11) % "
2894*35238bceSAndroid Build Coastguard Worker << m_numLayers
2895*35238bceSAndroid Build Coastguard Worker << ";\n"
2896*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2897*35238bceSAndroid Build Coastguard Worker "\n"
2898*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.x, dstArea.w, 0.0, 1.0);\n"
2899*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2900*35238bceSAndroid Build Coastguard Worker " gl_Layer = ((baseLayer + ndx) * 11) % "
2901*35238bceSAndroid Build Coastguard Worker << m_numLayers
2902*35238bceSAndroid Build Coastguard Worker << ";\n"
2903*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2904*35238bceSAndroid Build Coastguard Worker "\n"
2905*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.z, dstArea.y, 0.0, 1.0);\n"
2906*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2907*35238bceSAndroid Build Coastguard Worker " gl_Layer = ((baseLayer + ndx) * 11) % "
2908*35238bceSAndroid Build Coastguard Worker << m_numLayers
2909*35238bceSAndroid Build Coastguard Worker << ";\n"
2910*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2911*35238bceSAndroid Build Coastguard Worker "\n"
2912*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(dstArea.z, dstArea.w, 0.0, 1.0);\n"
2913*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2914*35238bceSAndroid Build Coastguard Worker " gl_Layer = ((baseLayer + ndx) * 11) % "
2915*35238bceSAndroid Build Coastguard Worker << m_numLayers
2916*35238bceSAndroid Build Coastguard Worker << ";\n"
2917*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2918*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
2919*35238bceSAndroid Build Coastguard Worker " }\n";
2920*35238bceSAndroid Build Coastguard Worker }
2921*35238bceSAndroid Build Coastguard Worker else
2922*35238bceSAndroid Build Coastguard Worker {
2923*35238bceSAndroid Build Coastguard Worker if (m_flags & FLAG_GEOMETRY_SCATTER_INSTANCES)
2924*35238bceSAndroid Build Coastguard Worker {
2925*35238bceSAndroid Build Coastguard Worker buf << " // Scatter slices\n"
2926*35238bceSAndroid Build Coastguard Worker " int inputTriangleNdx = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n"
2927*35238bceSAndroid Build Coastguard Worker " ivec2 srcSliceNdx = ivec2(gridPosition.x, gridPosition.y * "
2928*35238bceSAndroid Build Coastguard Worker << (numInstances * 2)
2929*35238bceSAndroid Build Coastguard Worker << " + inputTriangleNdx);\n"
2930*35238bceSAndroid Build Coastguard Worker " ivec2 dstSliceNdx = ivec2(7 * srcSliceNdx.x, 127 * srcSliceNdx.y) % ivec2("
2931*35238bceSAndroid Build Coastguard Worker << tessLevel << ", " << tessLevel << " * " << (numInstances * 2)
2932*35238bceSAndroid Build Coastguard Worker << ");\n"
2933*35238bceSAndroid Build Coastguard Worker "\n"
2934*35238bceSAndroid Build Coastguard Worker " // Draw slice to the dstSlice slot\n"
2935*35238bceSAndroid Build Coastguard Worker " vec4 outputSliceArea;\n"
2936*35238bceSAndroid Build Coastguard Worker " outputSliceArea.x = float(dstSliceNdx.x) / float("
2937*35238bceSAndroid Build Coastguard Worker << tessLevel
2938*35238bceSAndroid Build Coastguard Worker << ") * 2.0 - 1.0 - gapOffset;\n"
2939*35238bceSAndroid Build Coastguard Worker " outputSliceArea.y = float(dstSliceNdx.y) / float("
2940*35238bceSAndroid Build Coastguard Worker << (tessLevel * numInstances * 2)
2941*35238bceSAndroid Build Coastguard Worker << ") * 2.0 - 1.0 - gapOffset;\n"
2942*35238bceSAndroid Build Coastguard Worker " outputSliceArea.z = float(dstSliceNdx.x+1) / float("
2943*35238bceSAndroid Build Coastguard Worker << tessLevel
2944*35238bceSAndroid Build Coastguard Worker << ") * 2.0 - 1.0 + gapOffset;\n"
2945*35238bceSAndroid Build Coastguard Worker " outputSliceArea.w = float(dstSliceNdx.y+1) / float("
2946*35238bceSAndroid Build Coastguard Worker << (tessLevel * numInstances * 2) << ") * 2.0 - 1.0 + gapOffset;\n";
2947*35238bceSAndroid Build Coastguard Worker }
2948*35238bceSAndroid Build Coastguard Worker else
2949*35238bceSAndroid Build Coastguard Worker {
2950*35238bceSAndroid Build Coastguard Worker buf << " // Fill the input area with slices\n"
2951*35238bceSAndroid Build Coastguard Worker " // Upper triangle produces slices only to the upper half of the quad and vice-versa\n"
2952*35238bceSAndroid Build Coastguard Worker " float triangleOffset = (isBottomTriangle) ? ((aabb.w + aabb.y) / 2.0) : (aabb.y);\n"
2953*35238bceSAndroid Build Coastguard Worker " // Each slice is a invocation\n"
2954*35238bceSAndroid Build Coastguard Worker " float sliceHeight = (aabb.w - aabb.y) / float(2 * "
2955*35238bceSAndroid Build Coastguard Worker << numInstances
2956*35238bceSAndroid Build Coastguard Worker << ");\n"
2957*35238bceSAndroid Build Coastguard Worker " float invocationOffset = float(gl_InvocationID) * sliceHeight;\n"
2958*35238bceSAndroid Build Coastguard Worker "\n"
2959*35238bceSAndroid Build Coastguard Worker " vec4 outputSliceArea;\n"
2960*35238bceSAndroid Build Coastguard Worker " outputSliceArea.x = aabb.x - gapOffset;\n"
2961*35238bceSAndroid Build Coastguard Worker " outputSliceArea.y = triangleOffset + invocationOffset - gapOffset;\n"
2962*35238bceSAndroid Build Coastguard Worker " outputSliceArea.z = aabb.z + gapOffset;\n"
2963*35238bceSAndroid Build Coastguard Worker " outputSliceArea.w = triangleOffset + invocationOffset + sliceHeight + gapOffset;\n";
2964*35238bceSAndroid Build Coastguard Worker }
2965*35238bceSAndroid Build Coastguard Worker
2966*35238bceSAndroid Build Coastguard Worker buf << "\n"
2967*35238bceSAndroid Build Coastguard Worker " // Draw slice\n"
2968*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < "
2969*35238bceSAndroid Build Coastguard Worker << ((numPrimitives + 2) / 2)
2970*35238bceSAndroid Build Coastguard Worker << "; ++ndx)\n"
2971*35238bceSAndroid Build Coastguard Worker " {\n"
2972*35238bceSAndroid Build Coastguard Worker " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
2973*35238bceSAndroid Build Coastguard Worker " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
2974*35238bceSAndroid Build Coastguard Worker " vec4 outputColor = (((gl_InvocationID + ndx) % 2) == 0) ? (green) : (yellow);\n"
2975*35238bceSAndroid Build Coastguard Worker " float xpos = mix(outputSliceArea.x, outputSliceArea.z, float(ndx) / float("
2976*35238bceSAndroid Build Coastguard Worker << (numPrimitives / 2)
2977*35238bceSAndroid Build Coastguard Worker << "));\n"
2978*35238bceSAndroid Build Coastguard Worker "\n"
2979*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(xpos, outputSliceArea.y, 0.0, 1.0);\n"
2980*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2981*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2982*35238bceSAndroid Build Coastguard Worker "\n"
2983*35238bceSAndroid Build Coastguard Worker " gl_Position = vec4(xpos, outputSliceArea.w, 0.0, 1.0);\n"
2984*35238bceSAndroid Build Coastguard Worker " v_color = outputColor;\n"
2985*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
2986*35238bceSAndroid Build Coastguard Worker " }\n";
2987*35238bceSAndroid Build Coastguard Worker }
2988*35238bceSAndroid Build Coastguard Worker
2989*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2990*35238bceSAndroid Build Coastguard Worker
2991*35238bceSAndroid Build Coastguard Worker return specializeShader(buf.str(), m_context.getRenderContext().getType());
2992*35238bceSAndroid Build Coastguard Worker }
2993*35238bceSAndroid Build Coastguard Worker
2994*35238bceSAndroid Build Coastguard Worker class FeedbackRecordVariableSelectionCase : public TestCase
2995*35238bceSAndroid Build Coastguard Worker {
2996*35238bceSAndroid Build Coastguard Worker public:
2997*35238bceSAndroid Build Coastguard Worker FeedbackRecordVariableSelectionCase(Context &context, const char *name, const char *description);
2998*35238bceSAndroid Build Coastguard Worker ~FeedbackRecordVariableSelectionCase(void);
2999*35238bceSAndroid Build Coastguard Worker
3000*35238bceSAndroid Build Coastguard Worker private:
3001*35238bceSAndroid Build Coastguard Worker void init(void);
3002*35238bceSAndroid Build Coastguard Worker void deinit(void);
3003*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
3004*35238bceSAndroid Build Coastguard Worker
3005*35238bceSAndroid Build Coastguard Worker std::string getVertexSource(void);
3006*35238bceSAndroid Build Coastguard Worker std::string getFragmentSource(void);
3007*35238bceSAndroid Build Coastguard Worker std::string getTessellationControlSource(void);
3008*35238bceSAndroid Build Coastguard Worker std::string getTessellationEvaluationSource(void);
3009*35238bceSAndroid Build Coastguard Worker std::string getGeometrySource(void);
3010*35238bceSAndroid Build Coastguard Worker
3011*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
3012*35238bceSAndroid Build Coastguard Worker uint32_t m_xfbBuf;
3013*35238bceSAndroid Build Coastguard Worker };
3014*35238bceSAndroid Build Coastguard Worker
FeedbackRecordVariableSelectionCase(Context & context,const char * name,const char * description)3015*35238bceSAndroid Build Coastguard Worker FeedbackRecordVariableSelectionCase::FeedbackRecordVariableSelectionCase(Context &context, const char *name,
3016*35238bceSAndroid Build Coastguard Worker const char *description)
3017*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
3018*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
3019*35238bceSAndroid Build Coastguard Worker , m_xfbBuf(0)
3020*35238bceSAndroid Build Coastguard Worker {
3021*35238bceSAndroid Build Coastguard Worker }
3022*35238bceSAndroid Build Coastguard Worker
~FeedbackRecordVariableSelectionCase(void)3023*35238bceSAndroid Build Coastguard Worker FeedbackRecordVariableSelectionCase::~FeedbackRecordVariableSelectionCase(void)
3024*35238bceSAndroid Build Coastguard Worker {
3025*35238bceSAndroid Build Coastguard Worker deinit();
3026*35238bceSAndroid Build Coastguard Worker }
3027*35238bceSAndroid Build Coastguard Worker
init(void)3028*35238bceSAndroid Build Coastguard Worker void FeedbackRecordVariableSelectionCase::init(void)
3029*35238bceSAndroid Build Coastguard Worker {
3030*35238bceSAndroid Build Coastguard Worker const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
3031*35238bceSAndroid Build Coastguard Worker const bool supportsCore40 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0));
3032*35238bceSAndroid Build Coastguard Worker
3033*35238bceSAndroid Build Coastguard Worker if ((!supportsES32 && !supportsCore40) &&
3034*35238bceSAndroid Build Coastguard Worker (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
3035*35238bceSAndroid Build Coastguard Worker !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")))
3036*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
3037*35238bceSAndroid Build Coastguard Worker
3038*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
3039*35238bceSAndroid Build Coastguard Worker << "Declaring multiple output variables with the same name in multiple shader stages. Capturing "
3040*35238bceSAndroid Build Coastguard Worker "the value of the varying using transform feedback."
3041*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3042*35238bceSAndroid Build Coastguard Worker
3043*35238bceSAndroid Build Coastguard Worker // gen feedback buffer fit for 1 triangle (4 components)
3044*35238bceSAndroid Build Coastguard Worker {
3045*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 initialData[3] = {
3046*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f),
3047*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f),
3048*35238bceSAndroid Build Coastguard Worker tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f),
3049*35238bceSAndroid Build Coastguard Worker };
3050*35238bceSAndroid Build Coastguard Worker
3051*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3052*35238bceSAndroid Build Coastguard Worker
3053*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
3054*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message
3055*35238bceSAndroid Build Coastguard Worker << "Creating buffer for transform feedback. Allocating storage for one triangle. Filling with -1.0"
3056*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3057*35238bceSAndroid Build Coastguard Worker
3058*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_xfbBuf);
3059*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfbBuf);
3060*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (int)(sizeof(tcu::Vec4[3])), initialData, GL_DYNAMIC_READ);
3061*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen xfb buf");
3062*35238bceSAndroid Build Coastguard Worker }
3063*35238bceSAndroid Build Coastguard Worker
3064*35238bceSAndroid Build Coastguard Worker // gen shader
3065*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(
3066*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
3067*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::VertexSource(getVertexSource()) << glu::FragmentSource(getFragmentSource())
3068*35238bceSAndroid Build Coastguard Worker << glu::TessellationControlSource(getTessellationControlSource())
3069*35238bceSAndroid Build Coastguard Worker << glu::TessellationEvaluationSource(getTessellationEvaluationSource())
3070*35238bceSAndroid Build Coastguard Worker << glu::GeometrySource(getGeometrySource())
3071*35238bceSAndroid Build Coastguard Worker << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS)
3072*35238bceSAndroid Build Coastguard Worker << glu::TransformFeedbackVarying("tf_feedback"));
3073*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
3074*35238bceSAndroid Build Coastguard Worker
3075*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
3076*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
3077*35238bceSAndroid Build Coastguard Worker }
3078*35238bceSAndroid Build Coastguard Worker
deinit(void)3079*35238bceSAndroid Build Coastguard Worker void FeedbackRecordVariableSelectionCase::deinit(void)
3080*35238bceSAndroid Build Coastguard Worker {
3081*35238bceSAndroid Build Coastguard Worker delete m_program;
3082*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
3083*35238bceSAndroid Build Coastguard Worker
3084*35238bceSAndroid Build Coastguard Worker if (m_xfbBuf)
3085*35238bceSAndroid Build Coastguard Worker {
3086*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_xfbBuf);
3087*35238bceSAndroid Build Coastguard Worker m_xfbBuf = 0;
3088*35238bceSAndroid Build Coastguard Worker }
3089*35238bceSAndroid Build Coastguard Worker }
3090*35238bceSAndroid Build Coastguard Worker
iterate(void)3091*35238bceSAndroid Build Coastguard Worker FeedbackRecordVariableSelectionCase::IterateResult FeedbackRecordVariableSelectionCase::iterate(void)
3092*35238bceSAndroid Build Coastguard Worker {
3093*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3094*35238bceSAndroid Build Coastguard Worker const int posLoc = gl.getAttribLocation(m_program->getProgram(), "a_position");
3095*35238bceSAndroid Build Coastguard Worker const glu::VertexArray vao(m_context.getRenderContext());
3096*35238bceSAndroid Build Coastguard Worker
3097*35238bceSAndroid Build Coastguard Worker if (posLoc == -1)
3098*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("a_position attribute location was -1");
3099*35238bceSAndroid Build Coastguard Worker
3100*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3101*35238bceSAndroid Build Coastguard Worker
3102*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering a patch of size 3." << tcu::TestLog::EndMessage;
3103*35238bceSAndroid Build Coastguard Worker
3104*35238bceSAndroid Build Coastguard Worker // Render and feed back
3105*35238bceSAndroid Build Coastguard Worker
3106*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, 1, 1);
3107*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3108*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
3109*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
3110*35238bceSAndroid Build Coastguard Worker
3111*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
3112*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3113*35238bceSAndroid Build Coastguard Worker
3114*35238bceSAndroid Build Coastguard Worker gl.vertexAttrib4f(posLoc, 0.0f, 0.0f, 0.0f, 1.0f);
3115*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "vertexAttrib4f");
3116*35238bceSAndroid Build Coastguard Worker
3117*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
3118*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
3119*35238bceSAndroid Build Coastguard Worker
3120*35238bceSAndroid Build Coastguard Worker gl.patchParameteri(GL_PATCH_VERTICES, 3);
3121*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
3122*35238bceSAndroid Build Coastguard Worker
3123*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbBuf);
3124*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind xfb buf");
3125*35238bceSAndroid Build Coastguard Worker
3126*35238bceSAndroid Build Coastguard Worker gl.beginTransformFeedback(GL_TRIANGLES);
3127*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "beginTransformFeedback");
3128*35238bceSAndroid Build Coastguard Worker
3129*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_PATCHES, 0, 3);
3130*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
3131*35238bceSAndroid Build Coastguard Worker
3132*35238bceSAndroid Build Coastguard Worker gl.endTransformFeedback();
3133*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "beginTransformFeedback");
3134*35238bceSAndroid Build Coastguard Worker
3135*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
3136*35238bceSAndroid Build Coastguard Worker << "Verifying the value of tf_feedback using transform feedback, expecting (3.0, 3.0, 3.0, 3.0)."
3137*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3138*35238bceSAndroid Build Coastguard Worker
3139*35238bceSAndroid Build Coastguard Worker // Read back result (one triangle)
3140*35238bceSAndroid Build Coastguard Worker {
3141*35238bceSAndroid Build Coastguard Worker tcu::Vec4 feedbackValues[3];
3142*35238bceSAndroid Build Coastguard Worker const void *mapPtr =
3143*35238bceSAndroid Build Coastguard Worker gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, (int)sizeof(feedbackValues), GL_MAP_READ_BIT);
3144*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "mapBufferRange");
3145*35238bceSAndroid Build Coastguard Worker
3146*35238bceSAndroid Build Coastguard Worker if (mapPtr == DE_NULL)
3147*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("mapBufferRange returned null");
3148*35238bceSAndroid Build Coastguard Worker
3149*35238bceSAndroid Build Coastguard Worker deMemcpy(feedbackValues, mapPtr, sizeof(feedbackValues));
3150*35238bceSAndroid Build Coastguard Worker
3151*35238bceSAndroid Build Coastguard Worker if (gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER) != GL_TRUE)
3152*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("unmapBuffer did not return TRUE");
3153*35238bceSAndroid Build Coastguard Worker
3154*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 3; ++ndx)
3155*35238bceSAndroid Build Coastguard Worker {
3156*35238bceSAndroid Build Coastguard Worker if (!tcu::boolAll(tcu::lessThan(tcu::abs(feedbackValues[ndx] - tcu::Vec4(3.0f)), tcu::Vec4(0.001f))))
3157*35238bceSAndroid Build Coastguard Worker {
3158*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Feedback vertex " << ndx
3159*35238bceSAndroid Build Coastguard Worker << ": expected (3.0, 3.0, 3.0, 3.0), got " << feedbackValues[ndx]
3160*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3161*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected feedback results");
3162*35238bceSAndroid Build Coastguard Worker }
3163*35238bceSAndroid Build Coastguard Worker }
3164*35238bceSAndroid Build Coastguard Worker }
3165*35238bceSAndroid Build Coastguard Worker
3166*35238bceSAndroid Build Coastguard Worker return STOP;
3167*35238bceSAndroid Build Coastguard Worker }
3168*35238bceSAndroid Build Coastguard Worker
getVertexSource(void)3169*35238bceSAndroid Build Coastguard Worker std::string FeedbackRecordVariableSelectionCase::getVertexSource(void)
3170*35238bceSAndroid Build Coastguard Worker {
3171*35238bceSAndroid Build Coastguard Worker std::string source = "${VERSION_DECL}\n"
3172*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
3173*35238bceSAndroid Build Coastguard Worker "out highp vec4 tf_feedback;\n"
3174*35238bceSAndroid Build Coastguard Worker "void main()\n"
3175*35238bceSAndroid Build Coastguard Worker "{\n"
3176*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
3177*35238bceSAndroid Build Coastguard Worker " tf_feedback = vec4(1.0, 1.0, 1.0, 1.0);\n"
3178*35238bceSAndroid Build Coastguard Worker "}\n";
3179*35238bceSAndroid Build Coastguard Worker
3180*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
3181*35238bceSAndroid Build Coastguard Worker }
3182*35238bceSAndroid Build Coastguard Worker
getFragmentSource(void)3183*35238bceSAndroid Build Coastguard Worker std::string FeedbackRecordVariableSelectionCase::getFragmentSource(void)
3184*35238bceSAndroid Build Coastguard Worker {
3185*35238bceSAndroid Build Coastguard Worker return specializeShader(s_whiteOutputFragmentShader, m_context.getRenderContext().getType());
3186*35238bceSAndroid Build Coastguard Worker }
3187*35238bceSAndroid Build Coastguard Worker
getTessellationControlSource(void)3188*35238bceSAndroid Build Coastguard Worker std::string FeedbackRecordVariableSelectionCase::getTessellationControlSource(void)
3189*35238bceSAndroid Build Coastguard Worker {
3190*35238bceSAndroid Build Coastguard Worker std::string source = "${VERSION_DECL}\n"
3191*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
3192*35238bceSAndroid Build Coastguard Worker "layout(vertices=3) out;\n"
3193*35238bceSAndroid Build Coastguard Worker "void main()\n"
3194*35238bceSAndroid Build Coastguard Worker "{\n"
3195*35238bceSAndroid Build Coastguard Worker " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3196*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 1.0;\n"
3197*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 1.0;\n"
3198*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 1.0;\n"
3199*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 1.0;\n"
3200*35238bceSAndroid Build Coastguard Worker "}\n";
3201*35238bceSAndroid Build Coastguard Worker
3202*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
3203*35238bceSAndroid Build Coastguard Worker }
3204*35238bceSAndroid Build Coastguard Worker
getTessellationEvaluationSource(void)3205*35238bceSAndroid Build Coastguard Worker std::string FeedbackRecordVariableSelectionCase::getTessellationEvaluationSource(void)
3206*35238bceSAndroid Build Coastguard Worker {
3207*35238bceSAndroid Build Coastguard Worker std::string source = "${VERSION_DECL}\n"
3208*35238bceSAndroid Build Coastguard Worker "${EXTENSION_TESSELATION_SHADER}"
3209*35238bceSAndroid Build Coastguard Worker "layout(triangles) in;\n"
3210*35238bceSAndroid Build Coastguard Worker "out highp vec4 tf_feedback;\n"
3211*35238bceSAndroid Build Coastguard Worker "void main()\n"
3212*35238bceSAndroid Build Coastguard Worker "{\n"
3213*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[0].gl_Position * gl_TessCoord.x + gl_in[1].gl_Position * "
3214*35238bceSAndroid Build Coastguard Worker "gl_TessCoord.y + gl_in[2].gl_Position * gl_TessCoord.z;\n"
3215*35238bceSAndroid Build Coastguard Worker " tf_feedback = vec4(2.0, 2.0, 2.0, 2.0);\n"
3216*35238bceSAndroid Build Coastguard Worker "}\n";
3217*35238bceSAndroid Build Coastguard Worker
3218*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
3219*35238bceSAndroid Build Coastguard Worker }
3220*35238bceSAndroid Build Coastguard Worker
getGeometrySource(void)3221*35238bceSAndroid Build Coastguard Worker std::string FeedbackRecordVariableSelectionCase::getGeometrySource(void)
3222*35238bceSAndroid Build Coastguard Worker {
3223*35238bceSAndroid Build Coastguard Worker std::string source =
3224*35238bceSAndroid Build Coastguard Worker "${VERSION_DECL}\n"
3225*35238bceSAndroid Build Coastguard Worker "${EXTENSION_GEOMETRY_SHADER}"
3226*35238bceSAndroid Build Coastguard Worker "layout (triangles) in;\n"
3227*35238bceSAndroid Build Coastguard Worker "layout (triangle_strip, max_vertices=3) out;\n"
3228*35238bceSAndroid Build Coastguard Worker "out highp vec4 tf_feedback;\n"
3229*35238bceSAndroid Build Coastguard Worker "void main()\n"
3230*35238bceSAndroid Build Coastguard Worker "{\n"
3231*35238bceSAndroid Build Coastguard Worker " for (int ndx = 0; ndx < 3; ++ndx)\n"
3232*35238bceSAndroid Build Coastguard Worker " {\n"
3233*35238bceSAndroid Build Coastguard Worker " gl_Position = gl_in[ndx].gl_Position + vec4(float(ndx), float(ndx)*float(ndx), 0.0, 0.0);\n"
3234*35238bceSAndroid Build Coastguard Worker " tf_feedback = vec4(3.0, 3.0, 3.0, 3.0);\n"
3235*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n"
3236*35238bceSAndroid Build Coastguard Worker " }\n"
3237*35238bceSAndroid Build Coastguard Worker " EndPrimitive();\n"
3238*35238bceSAndroid Build Coastguard Worker "}\n";
3239*35238bceSAndroid Build Coastguard Worker
3240*35238bceSAndroid Build Coastguard Worker return specializeShader(source, m_context.getRenderContext().getType());
3241*35238bceSAndroid Build Coastguard Worker }
3242*35238bceSAndroid Build Coastguard Worker
3243*35238bceSAndroid Build Coastguard Worker } // namespace
3244*35238bceSAndroid Build Coastguard Worker
TessellationGeometryInteractionTests(Context & context,bool isGL45)3245*35238bceSAndroid Build Coastguard Worker TessellationGeometryInteractionTests::TessellationGeometryInteractionTests(Context &context, bool isGL45)
3246*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "tessellation_geometry_interaction", "Tessellation and geometry shader interaction tests")
3247*35238bceSAndroid Build Coastguard Worker , m_isGL45(isGL45)
3248*35238bceSAndroid Build Coastguard Worker {
3249*35238bceSAndroid Build Coastguard Worker }
3250*35238bceSAndroid Build Coastguard Worker
~TessellationGeometryInteractionTests(void)3251*35238bceSAndroid Build Coastguard Worker TessellationGeometryInteractionTests::~TessellationGeometryInteractionTests(void)
3252*35238bceSAndroid Build Coastguard Worker {
3253*35238bceSAndroid Build Coastguard Worker }
3254*35238bceSAndroid Build Coastguard Worker
init(void)3255*35238bceSAndroid Build Coastguard Worker void TessellationGeometryInteractionTests::init(void)
3256*35238bceSAndroid Build Coastguard Worker {
3257*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const renderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Various render tests");
3258*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const feedbackGroup = new tcu::TestCaseGroup(m_testCtx, "feedback", "Test transform feedback");
3259*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const pointSizeGroup = new tcu::TestCaseGroup(m_testCtx, "point_size", "Test point size");
3260*35238bceSAndroid Build Coastguard Worker
3261*35238bceSAndroid Build Coastguard Worker addChild(renderGroup);
3262*35238bceSAndroid Build Coastguard Worker addChild(feedbackGroup);
3263*35238bceSAndroid Build Coastguard Worker addChild(pointSizeGroup);
3264*35238bceSAndroid Build Coastguard Worker
3265*35238bceSAndroid Build Coastguard Worker // .render
3266*35238bceSAndroid Build Coastguard Worker {
3267*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const passthroughGroup = new tcu::TestCaseGroup(
3268*35238bceSAndroid Build Coastguard Worker m_testCtx, "passthrough", "Render various types with either passthrough geometry or tessellation shader");
3269*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const limitGroup =
3270*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "limits", "Render with properties near their limits");
3271*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const scatterGroup =
3272*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "scatter", "Scatter output primitives");
3273*35238bceSAndroid Build Coastguard Worker
3274*35238bceSAndroid Build Coastguard Worker renderGroup->addChild(passthroughGroup);
3275*35238bceSAndroid Build Coastguard Worker renderGroup->addChild(limitGroup);
3276*35238bceSAndroid Build Coastguard Worker renderGroup->addChild(scatterGroup);
3277*35238bceSAndroid Build Coastguard Worker
3278*35238bceSAndroid Build Coastguard Worker // .passthrough
3279*35238bceSAndroid Build Coastguard Worker {
3280*35238bceSAndroid Build Coastguard Worker // tessellate_tris_passthrough_geometry_no_change
3281*35238bceSAndroid Build Coastguard Worker // tessellate_quads_passthrough_geometry_no_change
3282*35238bceSAndroid Build Coastguard Worker // tessellate_isolines_passthrough_geometry_no_change
3283*35238bceSAndroid Build Coastguard Worker passthroughGroup->addChild(new IdentityGeometryShaderCase(
3284*35238bceSAndroid Build Coastguard Worker m_context, "tessellate_tris_passthrough_geometry_no_change",
3285*35238bceSAndroid Build Coastguard Worker "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_TRIANGLES));
3286*35238bceSAndroid Build Coastguard Worker passthroughGroup->addChild(new IdentityGeometryShaderCase(
3287*35238bceSAndroid Build Coastguard Worker m_context, "tessellate_quads_passthrough_geometry_no_change",
3288*35238bceSAndroid Build Coastguard Worker "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_QUADS));
3289*35238bceSAndroid Build Coastguard Worker passthroughGroup->addChild(new IdentityGeometryShaderCase(
3290*35238bceSAndroid Build Coastguard Worker m_context, "tessellate_isolines_passthrough_geometry_no_change",
3291*35238bceSAndroid Build Coastguard Worker "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_ISOLINES));
3292*35238bceSAndroid Build Coastguard Worker
3293*35238bceSAndroid Build Coastguard Worker // passthrough_tessellation_geometry_shade_triangles_no_change
3294*35238bceSAndroid Build Coastguard Worker // passthrough_tessellation_geometry_shade_lines_no_change
3295*35238bceSAndroid Build Coastguard Worker passthroughGroup->addChild(new IdentityTessellationShaderCase(
3296*35238bceSAndroid Build Coastguard Worker m_context, "passthrough_tessellation_geometry_shade_triangles_no_change",
3297*35238bceSAndroid Build Coastguard Worker "Passthrough tessellation shader has no effect", IdentityTessellationShaderCase::CASE_TRIANGLES));
3298*35238bceSAndroid Build Coastguard Worker passthroughGroup->addChild(new IdentityTessellationShaderCase(
3299*35238bceSAndroid Build Coastguard Worker m_context, "passthrough_tessellation_geometry_shade_lines_no_change",
3300*35238bceSAndroid Build Coastguard Worker "Passthrough tessellation shader has no effect", IdentityTessellationShaderCase::CASE_ISOLINES));
3301*35238bceSAndroid Build Coastguard Worker }
3302*35238bceSAndroid Build Coastguard Worker
3303*35238bceSAndroid Build Coastguard Worker // .limits
3304*35238bceSAndroid Build Coastguard Worker {
3305*35238bceSAndroid Build Coastguard Worker static const struct LimitCaseDef
3306*35238bceSAndroid Build Coastguard Worker {
3307*35238bceSAndroid Build Coastguard Worker const char *name;
3308*35238bceSAndroid Build Coastguard Worker const char *desc;
3309*35238bceSAndroid Build Coastguard Worker int flags;
3310*35238bceSAndroid Build Coastguard Worker } cases[] = {
3311*35238bceSAndroid Build Coastguard Worker // Test single limit
3312*35238bceSAndroid Build Coastguard Worker {"output_required_max_tessellation", "Minimum maximum tessellation level",
3313*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_SPEC},
3314*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_tessellation", "Maximum tessellation level supported by the implementation",
3315*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION},
3316*35238bceSAndroid Build Coastguard Worker {"output_required_max_geometry", "Output minimum maximum number of vertices the geometry shader",
3317*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_MAX_SPEC},
3318*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_geometry",
3319*35238bceSAndroid Build Coastguard Worker "Output maximum number of vertices in the geometry shader supported by the implementation",
3320*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION},
3321*35238bceSAndroid Build Coastguard Worker {"output_required_max_invocations", "Minimum maximum number of geometry shader invocations",
3322*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC},
3323*35238bceSAndroid Build Coastguard Worker {"output_implementation_max_invocations",
3324*35238bceSAndroid Build Coastguard Worker "Maximum number of geometry shader invocations supported by the implementation",
3325*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION},
3326*35238bceSAndroid Build Coastguard Worker };
3327*35238bceSAndroid Build Coastguard Worker
3328*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ++ndx)
3329*35238bceSAndroid Build Coastguard Worker limitGroup->addChild(new GridRenderCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].flags));
3330*35238bceSAndroid Build Coastguard Worker }
3331*35238bceSAndroid Build Coastguard Worker
3332*35238bceSAndroid Build Coastguard Worker // .scatter
3333*35238bceSAndroid Build Coastguard Worker {
3334*35238bceSAndroid Build Coastguard Worker scatterGroup->addChild(new GridRenderCase(
3335*35238bceSAndroid Build Coastguard Worker m_context, "geometry_scatter_instances",
3336*35238bceSAndroid Build Coastguard Worker "Each geometry shader instance outputs its primitives far from other instances of the same execution",
3337*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_SCATTER_INSTANCES));
3338*35238bceSAndroid Build Coastguard Worker scatterGroup->addChild(new GridRenderCase(
3339*35238bceSAndroid Build Coastguard Worker m_context, "geometry_scatter_primitives",
3340*35238bceSAndroid Build Coastguard Worker "Each geometry shader instance outputs its primitives far from other primitives of the same instance",
3341*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_SCATTER_PRIMITIVES | GridRenderCase::FLAG_GEOMETRY_SEPARATE_PRIMITIVES));
3342*35238bceSAndroid Build Coastguard Worker scatterGroup->addChild(new GridRenderCase(
3343*35238bceSAndroid Build Coastguard Worker m_context, "geometry_scatter_layers",
3344*35238bceSAndroid Build Coastguard Worker "Each geometry shader instance outputs its primitives to multiple layers and far from other primitives "
3345*35238bceSAndroid Build Coastguard Worker "of the same instance",
3346*35238bceSAndroid Build Coastguard Worker GridRenderCase::FLAG_GEOMETRY_SCATTER_LAYERS | GridRenderCase::FLAG_GEOMETRY_SEPARATE_PRIMITIVES));
3347*35238bceSAndroid Build Coastguard Worker }
3348*35238bceSAndroid Build Coastguard Worker }
3349*35238bceSAndroid Build Coastguard Worker
3350*35238bceSAndroid Build Coastguard Worker // .feedback
3351*35238bceSAndroid Build Coastguard Worker {
3352*35238bceSAndroid Build Coastguard Worker static const struct PrimitiveCaseConfig
3353*35238bceSAndroid Build Coastguard Worker {
3354*35238bceSAndroid Build Coastguard Worker const char *name;
3355*35238bceSAndroid Build Coastguard Worker const char *description;
3356*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TessellationOutputType tessellationOutput;
3357*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TessellationPointMode tessellationPointMode;
3358*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::GeometryOutputType geometryOutputType;
3359*35238bceSAndroid Build Coastguard Worker } caseConfigs[] = {
3360*35238bceSAndroid Build Coastguard Worker // tess output triangles -> geo input triangles, output points
3361*35238bceSAndroid Build Coastguard Worker {"tessellation_output_triangles_geometry_output_points",
3362*35238bceSAndroid Build Coastguard Worker "Tessellation outputs triangles, geometry outputs points",
3363*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_TRIANGLES,
3364*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF, FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS},
3365*35238bceSAndroid Build Coastguard Worker
3366*35238bceSAndroid Build Coastguard Worker // tess output quads <-> geo input triangles, output points
3367*35238bceSAndroid Build Coastguard Worker {"tessellation_output_quads_geometry_output_points", "Tessellation outputs quads, geometry outputs points",
3368*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_QUADS, FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF,
3369*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS},
3370*35238bceSAndroid Build Coastguard Worker
3371*35238bceSAndroid Build Coastguard Worker // tess output isolines <-> geo input lines, output points
3372*35238bceSAndroid Build Coastguard Worker {"tessellation_output_isolines_geometry_output_points",
3373*35238bceSAndroid Build Coastguard Worker "Tessellation outputs isolines, geometry outputs points",
3374*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_ISOLINES,
3375*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF, FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS},
3376*35238bceSAndroid Build Coastguard Worker
3377*35238bceSAndroid Build Coastguard Worker // tess output triangles, point_mode <-> geo input points, output lines
3378*35238bceSAndroid Build Coastguard Worker {"tessellation_output_triangles_point_mode_geometry_output_lines",
3379*35238bceSAndroid Build Coastguard Worker "Tessellation outputs triangles in point mode, geometry outputs lines",
3380*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_TRIANGLES,
3381*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON, FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_LINES},
3382*35238bceSAndroid Build Coastguard Worker
3383*35238bceSAndroid Build Coastguard Worker // tess output quads, point_mode <-> geo input points, output lines
3384*35238bceSAndroid Build Coastguard Worker {"tessellation_output_quads_point_mode_geometry_output_lines",
3385*35238bceSAndroid Build Coastguard Worker "Tessellation outputs quads in point mode, geometry outputs lines",
3386*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_QUADS, FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON,
3387*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_LINES},
3388*35238bceSAndroid Build Coastguard Worker
3389*35238bceSAndroid Build Coastguard Worker // tess output isolines, point_mode <-> geo input points, output triangles
3390*35238bceSAndroid Build Coastguard Worker {"tessellation_output_isolines_point_mode_geometry_output_triangles",
3391*35238bceSAndroid Build Coastguard Worker "Tessellation outputs isolines in point mode, geometry outputs triangles",
3392*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::TESSELLATION_OUT_ISOLINES, FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON,
3393*35238bceSAndroid Build Coastguard Worker FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_TRIANGLES},
3394*35238bceSAndroid Build Coastguard Worker };
3395*35238bceSAndroid Build Coastguard Worker
3396*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(caseConfigs); ++ndx)
3397*35238bceSAndroid Build Coastguard Worker {
3398*35238bceSAndroid Build Coastguard Worker feedbackGroup->addChild(new FeedbackPrimitiveTypeCase(
3399*35238bceSAndroid Build Coastguard Worker m_context, caseConfigs[ndx].name, caseConfigs[ndx].description, caseConfigs[ndx].tessellationOutput,
3400*35238bceSAndroid Build Coastguard Worker caseConfigs[ndx].tessellationPointMode, caseConfigs[ndx].geometryOutputType));
3401*35238bceSAndroid Build Coastguard Worker }
3402*35238bceSAndroid Build Coastguard Worker
3403*35238bceSAndroid Build Coastguard Worker feedbackGroup->addChild(new FeedbackRecordVariableSelectionCase(
3404*35238bceSAndroid Build Coastguard Worker m_context, "record_variable_selection",
3405*35238bceSAndroid Build Coastguard Worker "Record a variable that has been declared as an output variable in multiple shader stages"));
3406*35238bceSAndroid Build Coastguard Worker }
3407*35238bceSAndroid Build Coastguard Worker
3408*35238bceSAndroid Build Coastguard Worker // .point_size
3409*35238bceSAndroid Build Coastguard Worker {
3410*35238bceSAndroid Build Coastguard Worker static const struct PointSizeCaseConfig
3411*35238bceSAndroid Build Coastguard Worker {
3412*35238bceSAndroid Build Coastguard Worker const int caseMask;
3413*35238bceSAndroid Build Coastguard Worker const bool isSupportedInGL; // is this case supported in OpenGL
3414*35238bceSAndroid Build Coastguard Worker } caseConfigs[] = {
3415*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET, true},
3416*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET, true},
3417*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_GEOMETRY_SET, true},
3418*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_CONTROL_SET, false},
3419*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET, true},
3420*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_DONT_SET, false},
3421*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_GEOMETRY_SET, true},
3422*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET |
3423*35238bceSAndroid Build Coastguard Worker PointSizeCase::FLAG_GEOMETRY_SET,
3424*35238bceSAndroid Build Coastguard Worker true},
3425*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_ADD | PointSizeCase::FLAG_GEOMETRY_ADD,
3426*35238bceSAndroid Build Coastguard Worker true},
3427*35238bceSAndroid Build Coastguard Worker {PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET |
3428*35238bceSAndroid Build Coastguard Worker PointSizeCase::FLAG_GEOMETRY_DONT_SET,
3429*35238bceSAndroid Build Coastguard Worker false},
3430*35238bceSAndroid Build Coastguard Worker };
3431*35238bceSAndroid Build Coastguard Worker
3432*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(caseConfigs); ++ndx)
3433*35238bceSAndroid Build Coastguard Worker {
3434*35238bceSAndroid Build Coastguard Worker if (m_isGL45 && !caseConfigs[ndx].isSupportedInGL)
3435*35238bceSAndroid Build Coastguard Worker continue;
3436*35238bceSAndroid Build Coastguard Worker
3437*35238bceSAndroid Build Coastguard Worker const std::string name = PointSizeCase::genTestCaseName(caseConfigs[ndx].caseMask);
3438*35238bceSAndroid Build Coastguard Worker const std::string desc = PointSizeCase::genTestCaseDescription(caseConfigs[ndx].caseMask);
3439*35238bceSAndroid Build Coastguard Worker
3440*35238bceSAndroid Build Coastguard Worker pointSizeGroup->addChild(
3441*35238bceSAndroid Build Coastguard Worker new PointSizeCase(m_context, name.c_str(), desc.c_str(), caseConfigs[ndx].caseMask));
3442*35238bceSAndroid Build Coastguard Worker }
3443*35238bceSAndroid Build Coastguard Worker }
3444*35238bceSAndroid Build Coastguard Worker }
3445*35238bceSAndroid Build Coastguard Worker
3446*35238bceSAndroid Build Coastguard Worker } // namespace Functional
3447*35238bceSAndroid Build Coastguard Worker } // namespace gles31
3448*35238bceSAndroid Build Coastguard Worker } // namespace deqp
3449