xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fGeometryShaderTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 Geometry shader tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fGeometryShaderTests.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "glsStateQueryUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker #include "sglrContext.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "sglrReferenceContext.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "sglrGLContext.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "sglrReferenceUtils.hpp"
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
51*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
52*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker #include <algorithm>
55*35238bceSAndroid Build Coastguard Worker 
56*35238bceSAndroid Build Coastguard Worker using namespace glw;
57*35238bceSAndroid Build Coastguard Worker 
58*35238bceSAndroid Build Coastguard Worker namespace deqp
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker namespace gles31
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker namespace Functional
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker namespace
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker using namespace gls::StateQueryUtil;
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker const int TEST_CANVAS_SIZE = 256;
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker static const char *const s_commonShaderSourceVertex   = "${GLSL_VERSION_DECL}\n"
72*35238bceSAndroid Build Coastguard Worker                                                         "in highp vec4 a_position;\n"
73*35238bceSAndroid Build Coastguard Worker                                                         "in highp vec4 a_color;\n"
74*35238bceSAndroid Build Coastguard Worker                                                         "out highp vec4 v_geom_FragColor;\n"
75*35238bceSAndroid Build Coastguard Worker                                                         "void main (void)\n"
76*35238bceSAndroid Build Coastguard Worker                                                         "{\n"
77*35238bceSAndroid Build Coastguard Worker                                                         "    gl_Position = a_position;\n"
78*35238bceSAndroid Build Coastguard Worker                                                         "    gl_PointSize = 1.0;\n"
79*35238bceSAndroid Build Coastguard Worker                                                         "    v_geom_FragColor = a_color;\n"
80*35238bceSAndroid Build Coastguard Worker                                                         "}\n";
81*35238bceSAndroid Build Coastguard Worker static const char *const s_commonShaderSourceFragment = "${GLSL_VERSION_DECL}\n"
82*35238bceSAndroid Build Coastguard Worker                                                         "layout(location = 0) out mediump vec4 fragColor;\n"
83*35238bceSAndroid Build Coastguard Worker                                                         "in mediump vec4 v_frag_FragColor;\n"
84*35238bceSAndroid Build Coastguard Worker                                                         "void main (void)\n"
85*35238bceSAndroid Build Coastguard Worker                                                         "{\n"
86*35238bceSAndroid Build Coastguard Worker                                                         "    fragColor = v_frag_FragColor;\n"
87*35238bceSAndroid Build Coastguard Worker                                                         "}\n";
88*35238bceSAndroid Build Coastguard Worker static const char *const s_expandShaderSourceGeometryBody =
89*35238bceSAndroid Build Coastguard Worker     "in highp vec4 v_geom_FragColor[];\n"
90*35238bceSAndroid Build Coastguard Worker     "out highp vec4 v_frag_FragColor;\n"
91*35238bceSAndroid Build Coastguard Worker     "\n"
92*35238bceSAndroid Build Coastguard Worker     "void main (void)\n"
93*35238bceSAndroid Build Coastguard Worker     "{\n"
94*35238bceSAndroid Build Coastguard Worker     "    const highp vec4 offset0 = vec4(-0.07, -0.01, 0.0, 0.0);\n"
95*35238bceSAndroid Build Coastguard Worker     "    const highp vec4 offset1 = vec4( 0.03, -0.03, 0.0, 0.0);\n"
96*35238bceSAndroid Build Coastguard Worker     "    const highp vec4 offset2 = vec4(-0.01,  0.08, 0.0, 0.0);\n"
97*35238bceSAndroid Build Coastguard Worker     "          highp vec4 yoffset = float(gl_PrimitiveIDIn) * vec4(0.02, 0.1, 0.0, 0.0);\n"
98*35238bceSAndroid Build Coastguard Worker     "\n"
99*35238bceSAndroid Build Coastguard Worker     "    for (highp int ndx = 0; ndx < gl_in.length(); ndx++)\n"
100*35238bceSAndroid Build Coastguard Worker     "    {\n"
101*35238bceSAndroid Build Coastguard Worker     "        gl_Position = gl_in[ndx].gl_Position + offset0 + yoffset;\n"
102*35238bceSAndroid Build Coastguard Worker     "        gl_PrimitiveID = gl_PrimitiveIDIn;\n"
103*35238bceSAndroid Build Coastguard Worker     "        v_frag_FragColor = v_geom_FragColor[ndx];\n"
104*35238bceSAndroid Build Coastguard Worker     "        EmitVertex();\n"
105*35238bceSAndroid Build Coastguard Worker     "\n"
106*35238bceSAndroid Build Coastguard Worker     "        gl_Position = gl_in[ndx].gl_Position + offset1 + yoffset;\n"
107*35238bceSAndroid Build Coastguard Worker     "        gl_PrimitiveID = gl_PrimitiveIDIn;\n"
108*35238bceSAndroid Build Coastguard Worker     "        v_frag_FragColor = v_geom_FragColor[ndx];\n"
109*35238bceSAndroid Build Coastguard Worker     "        EmitVertex();\n"
110*35238bceSAndroid Build Coastguard Worker     "\n"
111*35238bceSAndroid Build Coastguard Worker     "        gl_Position = gl_in[ndx].gl_Position + offset2 + yoffset;\n"
112*35238bceSAndroid Build Coastguard Worker     "        gl_PrimitiveID = gl_PrimitiveIDIn;\n"
113*35238bceSAndroid Build Coastguard Worker     "        v_frag_FragColor = v_geom_FragColor[ndx];\n"
114*35238bceSAndroid Build Coastguard Worker     "        EmitVertex();\n"
115*35238bceSAndroid Build Coastguard Worker     "        EndPrimitive();\n"
116*35238bceSAndroid Build Coastguard Worker     "    }\n"
117*35238bceSAndroid Build Coastguard Worker     "}\n";
118*35238bceSAndroid Build Coastguard Worker 
specializeShader(const std::string & shaderSource,const glu::ContextType & contextType)119*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(const std::string &shaderSource, const glu::ContextType &contextType)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
122*35238bceSAndroid Build Coastguard Worker                                     glu::contextSupports(contextType, glu::ApiType::core(4, 5));
123*35238bceSAndroid Build Coastguard Worker     std::map<std::string, std::string> args;
124*35238bceSAndroid Build Coastguard Worker     args["GLSL_VERSION_DECL"]        = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(contextType));
125*35238bceSAndroid Build Coastguard Worker     args["GLSL_EXT_GEOMETRY_SHADER"] = supportsES32orGL45 ? "" : "#extension GL_EXT_geometry_shader : require\n";
126*35238bceSAndroid Build Coastguard Worker     args["GLSL_OES_TEXTURE_STORAGE_MULTISAMPLE"] =
127*35238bceSAndroid Build Coastguard Worker         supportsES32orGL45 ? "" : "#extension GL_OES_texture_storage_multisample_2d_array : require\n";
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(shaderSource).specialize(args);
130*35238bceSAndroid Build Coastguard Worker }
131*35238bceSAndroid Build Coastguard Worker 
checkSupport(Context & ctx)132*35238bceSAndroid Build Coastguard Worker static bool checkSupport(Context &ctx)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker     auto contextType = ctx.getRenderContext().getType();
135*35238bceSAndroid Build Coastguard Worker     return contextSupports(contextType, glu::ApiType::es(3, 2)) ||
136*35238bceSAndroid Build Coastguard Worker            contextSupports(contextType, glu::ApiType::core(4, 5)) ||
137*35238bceSAndroid Build Coastguard Worker            ctx.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader");
138*35238bceSAndroid Build Coastguard Worker }
139*35238bceSAndroid Build Coastguard Worker 
inputTypeToGLString(rr::GeometryShaderInputType inputType)140*35238bceSAndroid Build Coastguard Worker std::string inputTypeToGLString(rr::GeometryShaderInputType inputType)
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker     switch (inputType)
143*35238bceSAndroid Build Coastguard Worker     {
144*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_POINTS:
145*35238bceSAndroid Build Coastguard Worker         return "points";
146*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_LINES:
147*35238bceSAndroid Build Coastguard Worker         return "lines";
148*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY:
149*35238bceSAndroid Build Coastguard Worker         return "lines_adjacency";
150*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES:
151*35238bceSAndroid Build Coastguard Worker         return "triangles";
152*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY:
153*35238bceSAndroid Build Coastguard Worker         return "triangles_adjacency";
154*35238bceSAndroid Build Coastguard Worker     default:
155*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
156*35238bceSAndroid Build Coastguard Worker         return "error";
157*35238bceSAndroid Build Coastguard Worker     }
158*35238bceSAndroid Build Coastguard Worker }
159*35238bceSAndroid Build Coastguard Worker 
outputTypeToGLString(rr::GeometryShaderOutputType outputType)160*35238bceSAndroid Build Coastguard Worker std::string outputTypeToGLString(rr::GeometryShaderOutputType outputType)
161*35238bceSAndroid Build Coastguard Worker {
162*35238bceSAndroid Build Coastguard Worker     switch (outputType)
163*35238bceSAndroid Build Coastguard Worker     {
164*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADEROUTPUTTYPE_POINTS:
165*35238bceSAndroid Build Coastguard Worker         return "points";
166*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADEROUTPUTTYPE_LINE_STRIP:
167*35238bceSAndroid Build Coastguard Worker         return "line_strip";
168*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP:
169*35238bceSAndroid Build Coastguard Worker         return "triangle_strip";
170*35238bceSAndroid Build Coastguard Worker     default:
171*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
172*35238bceSAndroid Build Coastguard Worker         return "error";
173*35238bceSAndroid Build Coastguard Worker     }
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker 
primitiveTypeToString(GLenum primitive)176*35238bceSAndroid Build Coastguard Worker std::string primitiveTypeToString(GLenum primitive)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker     switch (primitive)
179*35238bceSAndroid Build Coastguard Worker     {
180*35238bceSAndroid Build Coastguard Worker     case GL_POINTS:
181*35238bceSAndroid Build Coastguard Worker         return "points";
182*35238bceSAndroid Build Coastguard Worker     case GL_LINES:
183*35238bceSAndroid Build Coastguard Worker         return "lines";
184*35238bceSAndroid Build Coastguard Worker     case GL_LINE_LOOP:
185*35238bceSAndroid Build Coastguard Worker         return "line_loop";
186*35238bceSAndroid Build Coastguard Worker     case GL_LINE_STRIP:
187*35238bceSAndroid Build Coastguard Worker         return "line_strip";
188*35238bceSAndroid Build Coastguard Worker     case GL_LINES_ADJACENCY:
189*35238bceSAndroid Build Coastguard Worker         return "lines_adjacency";
190*35238bceSAndroid Build Coastguard Worker     case GL_LINE_STRIP_ADJACENCY:
191*35238bceSAndroid Build Coastguard Worker         return "line_strip_adjacency";
192*35238bceSAndroid Build Coastguard Worker     case GL_TRIANGLES:
193*35238bceSAndroid Build Coastguard Worker         return "triangles";
194*35238bceSAndroid Build Coastguard Worker     case GL_TRIANGLE_STRIP:
195*35238bceSAndroid Build Coastguard Worker         return "triangle_strip";
196*35238bceSAndroid Build Coastguard Worker     case GL_TRIANGLE_FAN:
197*35238bceSAndroid Build Coastguard Worker         return "triangle_fan";
198*35238bceSAndroid Build Coastguard Worker     case GL_TRIANGLES_ADJACENCY:
199*35238bceSAndroid Build Coastguard Worker         return "triangles_adjacency";
200*35238bceSAndroid Build Coastguard Worker     case GL_TRIANGLE_STRIP_ADJACENCY:
201*35238bceSAndroid Build Coastguard Worker         return "triangle_strip_adjacency";
202*35238bceSAndroid Build Coastguard Worker     default:
203*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
204*35238bceSAndroid Build Coastguard Worker         return "error";
205*35238bceSAndroid Build Coastguard Worker     }
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker struct OutputCountPatternSpec
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker     OutputCountPatternSpec(int count);
211*35238bceSAndroid Build Coastguard Worker     OutputCountPatternSpec(int count0, int count1);
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker     std::vector<int> pattern;
214*35238bceSAndroid Build Coastguard Worker };
215*35238bceSAndroid Build Coastguard Worker 
OutputCountPatternSpec(int count)216*35238bceSAndroid Build Coastguard Worker OutputCountPatternSpec::OutputCountPatternSpec(int count)
217*35238bceSAndroid Build Coastguard Worker {
218*35238bceSAndroid Build Coastguard Worker     pattern.push_back(count);
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker 
OutputCountPatternSpec(int count0,int count1)221*35238bceSAndroid Build Coastguard Worker OutputCountPatternSpec::OutputCountPatternSpec(int count0, int count1)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker     pattern.push_back(count0);
224*35238bceSAndroid Build Coastguard Worker     pattern.push_back(count1);
225*35238bceSAndroid Build Coastguard Worker }
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker class VertexExpanderShader : public sglr::ShaderProgram
228*35238bceSAndroid Build Coastguard Worker {
229*35238bceSAndroid Build Coastguard Worker public:
230*35238bceSAndroid Build Coastguard Worker     VertexExpanderShader(const glu::ContextType &contextType, rr::GeometryShaderInputType inputType,
231*35238bceSAndroid Build Coastguard Worker                          rr::GeometryShaderOutputType outputType);
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
234*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
235*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
236*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
237*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker private:
240*35238bceSAndroid Build Coastguard Worker     size_t calcOutputVertices(rr::GeometryShaderInputType inputType) const;
241*35238bceSAndroid Build Coastguard Worker     std::string genGeometrySource(const glu::ContextType &contextType, rr::GeometryShaderInputType inputType,
242*35238bceSAndroid Build Coastguard Worker                                   rr::GeometryShaderOutputType outputType) const;
243*35238bceSAndroid Build Coastguard Worker };
244*35238bceSAndroid Build Coastguard Worker 
VertexExpanderShader(const glu::ContextType & contextType,rr::GeometryShaderInputType inputType,rr::GeometryShaderOutputType outputType)245*35238bceSAndroid Build Coastguard Worker VertexExpanderShader::VertexExpanderShader(const glu::ContextType &contextType, rr::GeometryShaderInputType inputType,
246*35238bceSAndroid Build Coastguard Worker                                            rr::GeometryShaderOutputType outputType)
247*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
248*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
249*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
250*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
251*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
252*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
253*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(specializeShader(s_commonShaderSourceVertex, contextType))
254*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(specializeShader(s_commonShaderSourceFragment, contextType))
255*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(inputType, outputType, calcOutputVertices(inputType))
256*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, inputType, outputType)))
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker }
259*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const260*35238bceSAndroid Build Coastguard Worker void VertexExpanderShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
261*35238bceSAndroid Build Coastguard Worker                                          const int numPackets) const
262*35238bceSAndroid Build Coastguard Worker {
263*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
264*35238bceSAndroid Build Coastguard Worker     {
265*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
266*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
267*35238bceSAndroid Build Coastguard Worker         packets[ndx]->pointSize = 1.0f;
268*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
269*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
270*35238bceSAndroid Build Coastguard Worker     }
271*35238bceSAndroid Build Coastguard Worker }
272*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const273*35238bceSAndroid Build Coastguard Worker void VertexExpanderShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
274*35238bceSAndroid Build Coastguard Worker                                           const rr::FragmentShadingContext &context) const
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
277*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
278*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
279*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
280*35238bceSAndroid Build Coastguard Worker }
281*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const282*35238bceSAndroid Build Coastguard Worker void VertexExpanderShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
283*35238bceSAndroid Build Coastguard Worker                                            const rr::PrimitivePacket *packets, const int numPackets,
284*35238bceSAndroid Build Coastguard Worker                                            int invocationID) const
285*35238bceSAndroid Build Coastguard Worker {
286*35238bceSAndroid Build Coastguard Worker     DE_UNREF(invocationID);
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
289*35238bceSAndroid Build Coastguard Worker         for (int verticeNdx = 0; verticeNdx < verticesIn; ++verticeNdx)
290*35238bceSAndroid Build Coastguard Worker         {
291*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 offsets[] = {tcu::Vec4(-0.07f, -0.01f, 0.0f, 0.0f), tcu::Vec4(0.03f, -0.03f, 0.0f, 0.0f),
292*35238bceSAndroid Build Coastguard Worker                                          tcu::Vec4(-0.01f, 0.08f, 0.0f, 0.0f)};
293*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 yoffset   = float(packets[ndx].primitiveIDIn) * tcu::Vec4(0.02f, 0.1f, 0, 0);
294*35238bceSAndroid Build Coastguard Worker 
295*35238bceSAndroid Build Coastguard Worker             // Create new primitive at every input vertice
296*35238bceSAndroid Build Coastguard Worker             const rr::VertexPacket *vertex = packets[ndx].vertices[verticeNdx];
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + offsets[0] + yoffset, vertex->pointSize, vertex->outputs,
299*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
300*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + offsets[1] + yoffset, vertex->pointSize, vertex->outputs,
301*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
302*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + offsets[2] + yoffset, vertex->pointSize, vertex->outputs,
303*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
304*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
305*35238bceSAndroid Build Coastguard Worker         }
306*35238bceSAndroid Build Coastguard Worker }
307*35238bceSAndroid Build Coastguard Worker 
calcOutputVertices(rr::GeometryShaderInputType inputType) const308*35238bceSAndroid Build Coastguard Worker size_t VertexExpanderShader::calcOutputVertices(rr::GeometryShaderInputType inputType) const
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker     switch (inputType)
311*35238bceSAndroid Build Coastguard Worker     {
312*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_POINTS:
313*35238bceSAndroid Build Coastguard Worker         return 1 * 3;
314*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_LINES:
315*35238bceSAndroid Build Coastguard Worker         return 2 * 3;
316*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY:
317*35238bceSAndroid Build Coastguard Worker         return 4 * 3;
318*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES:
319*35238bceSAndroid Build Coastguard Worker         return 3 * 3;
320*35238bceSAndroid Build Coastguard Worker     case rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY:
321*35238bceSAndroid Build Coastguard Worker         return 6 * 3;
322*35238bceSAndroid Build Coastguard Worker     default:
323*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
324*35238bceSAndroid Build Coastguard Worker         return 0;
325*35238bceSAndroid Build Coastguard Worker     }
326*35238bceSAndroid Build Coastguard Worker }
327*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,rr::GeometryShaderInputType inputType,rr::GeometryShaderOutputType outputType) const328*35238bceSAndroid Build Coastguard Worker std::string VertexExpanderShader::genGeometrySource(const glu::ContextType &contextType,
329*35238bceSAndroid Build Coastguard Worker                                                     rr::GeometryShaderInputType inputType,
330*35238bceSAndroid Build Coastguard Worker                                                     rr::GeometryShaderOutputType outputType) const
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     std::ostringstream str;
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_VERSION_DECL}\n";
335*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_EXT_GEOMETRY_SHADER}";
336*35238bceSAndroid Build Coastguard Worker     str << "layout(" << inputTypeToGLString(inputType) << ") in;\n";
337*35238bceSAndroid Build Coastguard Worker     str << "layout(" << outputTypeToGLString(outputType) << ", max_vertices = " << calcOutputVertices(inputType)
338*35238bceSAndroid Build Coastguard Worker         << ") out;";
339*35238bceSAndroid Build Coastguard Worker     str << "\n";
340*35238bceSAndroid Build Coastguard Worker     str << s_expandShaderSourceGeometryBody;
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker     return specializeShader(str.str(), contextType);
343*35238bceSAndroid Build Coastguard Worker }
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker class VertexEmitterShader : public sglr::ShaderProgram
346*35238bceSAndroid Build Coastguard Worker {
347*35238bceSAndroid Build Coastguard Worker public:
348*35238bceSAndroid Build Coastguard Worker     VertexEmitterShader(const glu::ContextType &contextType, int emitCountA, int endCountA, int emitCountB,
349*35238bceSAndroid Build Coastguard Worker                         int endCountB, rr::GeometryShaderOutputType outputType);
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
352*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
353*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
354*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
355*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker private:
358*35238bceSAndroid Build Coastguard Worker     std::string genGeometrySource(const glu::ContextType &contextType, int emitCountA, int endCountA, int emitCountB,
359*35238bceSAndroid Build Coastguard Worker                                   int endCountB, rr::GeometryShaderOutputType outputType) const;
360*35238bceSAndroid Build Coastguard Worker 
361*35238bceSAndroid Build Coastguard Worker     int m_emitCountA;
362*35238bceSAndroid Build Coastguard Worker     int m_endCountA;
363*35238bceSAndroid Build Coastguard Worker     int m_emitCountB;
364*35238bceSAndroid Build Coastguard Worker     int m_endCountB;
365*35238bceSAndroid Build Coastguard Worker };
366*35238bceSAndroid Build Coastguard Worker 
VertexEmitterShader(const glu::ContextType & contextType,int emitCountA,int endCountA,int emitCountB,int endCountB,rr::GeometryShaderOutputType outputType)367*35238bceSAndroid Build Coastguard Worker VertexEmitterShader::VertexEmitterShader(const glu::ContextType &contextType, int emitCountA, int endCountA,
368*35238bceSAndroid Build Coastguard Worker                                          int emitCountB, int endCountB, rr::GeometryShaderOutputType outputType)
369*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
370*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
371*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
372*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
373*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
374*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
375*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(specializeShader(s_commonShaderSourceVertex, contextType))
376*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(specializeShader(s_commonShaderSourceFragment, contextType))
377*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_POINTS, outputType,
378*35238bceSAndroid Build Coastguard Worker                                                                    emitCountA + emitCountB)
379*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, emitCountA, endCountA,
380*35238bceSAndroid Build Coastguard Worker                                                                           emitCountB, endCountB, outputType)))
381*35238bceSAndroid Build Coastguard Worker     , m_emitCountA(emitCountA)
382*35238bceSAndroid Build Coastguard Worker     , m_endCountA(endCountA)
383*35238bceSAndroid Build Coastguard Worker     , m_emitCountB(emitCountB)
384*35238bceSAndroid Build Coastguard Worker     , m_endCountB(endCountB)
385*35238bceSAndroid Build Coastguard Worker {
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const388*35238bceSAndroid Build Coastguard Worker void VertexEmitterShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
389*35238bceSAndroid Build Coastguard Worker                                         const int numPackets) const
390*35238bceSAndroid Build Coastguard Worker {
391*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
392*35238bceSAndroid Build Coastguard Worker     {
393*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
394*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
395*35238bceSAndroid Build Coastguard Worker         packets[ndx]->pointSize = 1.0f;
396*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
397*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
398*35238bceSAndroid Build Coastguard Worker     }
399*35238bceSAndroid Build Coastguard Worker }
400*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const401*35238bceSAndroid Build Coastguard Worker void VertexEmitterShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
402*35238bceSAndroid Build Coastguard Worker                                          const rr::FragmentShadingContext &context) const
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
405*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
406*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
407*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
408*35238bceSAndroid Build Coastguard Worker }
409*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const410*35238bceSAndroid Build Coastguard Worker void VertexEmitterShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
411*35238bceSAndroid Build Coastguard Worker                                           const rr::PrimitivePacket *packets, const int numPackets,
412*35238bceSAndroid Build Coastguard Worker                                           int invocationID) const
413*35238bceSAndroid Build Coastguard Worker {
414*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
415*35238bceSAndroid Build Coastguard Worker     DE_UNREF(invocationID);
416*35238bceSAndroid Build Coastguard Worker 
417*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
418*35238bceSAndroid Build Coastguard Worker     {
419*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 positions[] = {
420*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(-0.5f, 0.5f, 0.0f, 0.0f), tcu::Vec4(0.0f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
421*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.7f, -0.2f, 0.0f, 0.0f), tcu::Vec4(0.2f, 0.2f, 0.0f, 0.0f), tcu::Vec4(0.4f, -0.3f, 0.0f, 0.0f),
422*35238bceSAndroid Build Coastguard Worker         };
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker         // Create new primitive at this point
425*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[ndx].vertices[0];
426*35238bceSAndroid Build Coastguard Worker 
427*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < m_emitCountA; ++i)
428*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + positions[i], vertex->pointSize, vertex->outputs,
429*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
430*35238bceSAndroid Build Coastguard Worker 
431*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < m_endCountA; ++i)
432*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < m_emitCountB; ++i)
435*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + positions[m_emitCountA + i], vertex->pointSize, vertex->outputs,
436*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < m_endCountB; ++i)
439*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
440*35238bceSAndroid Build Coastguard Worker     }
441*35238bceSAndroid Build Coastguard Worker }
442*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,int emitCountA,int endCountA,int emitCountB,int endCountB,rr::GeometryShaderOutputType outputType) const443*35238bceSAndroid Build Coastguard Worker std::string VertexEmitterShader::genGeometrySource(const glu::ContextType &contextType, int emitCountA, int endCountA,
444*35238bceSAndroid Build Coastguard Worker                                                    int emitCountB, int endCountB,
445*35238bceSAndroid Build Coastguard Worker                                                    rr::GeometryShaderOutputType outputType) const
446*35238bceSAndroid Build Coastguard Worker {
447*35238bceSAndroid Build Coastguard Worker     std::ostringstream str;
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_VERSION_DECL}\n";
450*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_EXT_GEOMETRY_SHADER}";
451*35238bceSAndroid Build Coastguard Worker     str << "layout(points) in;\n";
452*35238bceSAndroid Build Coastguard Worker     str << "layout(" << outputTypeToGLString(outputType) << ", max_vertices = " << (emitCountA + emitCountB)
453*35238bceSAndroid Build Coastguard Worker         << ") out;";
454*35238bceSAndroid Build Coastguard Worker     str << "\n";
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker     str << "in highp vec4 v_geom_FragColor[];\n"
457*35238bceSAndroid Build Coastguard Worker            "out highp vec4 v_frag_FragColor;\n"
458*35238bceSAndroid Build Coastguard Worker            "\n"
459*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
460*35238bceSAndroid Build Coastguard Worker            "{\n"
461*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position0 = vec4(-0.5,  0.5, 0.0, 0.0);\n"
462*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position1 = vec4( 0.0,  0.1, 0.0, 0.0);\n"
463*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position2 = vec4( 0.5,  0.5, 0.0, 0.0);\n"
464*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position3 = vec4( 0.7, -0.2, 0.0, 0.0);\n"
465*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position4 = vec4( 0.2,  0.2, 0.0, 0.0);\n"
466*35238bceSAndroid Build Coastguard Worker            "    const highp vec4 position5 = vec4( 0.4, -0.3, 0.0, 0.0);\n"
467*35238bceSAndroid Build Coastguard Worker            "\n";
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < emitCountA; ++i)
470*35238bceSAndroid Build Coastguard Worker         str << "    gl_Position = gl_in[0].gl_Position + position" << i
471*35238bceSAndroid Build Coastguard Worker             << ";\n"
472*35238bceSAndroid Build Coastguard Worker                "    gl_PrimitiveID = gl_PrimitiveIDIn;\n"
473*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = v_geom_FragColor[0];\n"
474*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
475*35238bceSAndroid Build Coastguard Worker                "\n";
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < endCountA; ++i)
478*35238bceSAndroid Build Coastguard Worker         str << "    EndPrimitive();\n";
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < emitCountB; ++i)
481*35238bceSAndroid Build Coastguard Worker         str << "    gl_Position = gl_in[0].gl_Position + position" << (emitCountA + i)
482*35238bceSAndroid Build Coastguard Worker             << ";\n"
483*35238bceSAndroid Build Coastguard Worker                "    gl_PrimitiveID = gl_PrimitiveIDIn;\n"
484*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = v_geom_FragColor[0];\n"
485*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
486*35238bceSAndroid Build Coastguard Worker                "\n";
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < endCountB; ++i)
489*35238bceSAndroid Build Coastguard Worker         str << "    EndPrimitive();\n";
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker     str << "}\n";
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker     return specializeShader(str.str(), contextType);
494*35238bceSAndroid Build Coastguard Worker }
495*35238bceSAndroid Build Coastguard Worker 
496*35238bceSAndroid Build Coastguard Worker class VertexVaryingShader : public sglr::ShaderProgram
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker public:
499*35238bceSAndroid Build Coastguard Worker     VertexVaryingShader(const glu::ContextType &contextType, int vertexOut, int geometryOut);
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
502*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
503*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
504*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
505*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
506*35238bceSAndroid Build Coastguard Worker 
507*35238bceSAndroid Build Coastguard Worker private:
508*35238bceSAndroid Build Coastguard Worker     static sglr::pdec::ShaderProgramDeclaration genProgramDeclaration(const glu::ContextType &contextType,
509*35238bceSAndroid Build Coastguard Worker                                                                       int vertexOut, int geometryOut);
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker     const int m_vertexOut;
512*35238bceSAndroid Build Coastguard Worker     const int m_geometryOut;
513*35238bceSAndroid Build Coastguard Worker };
514*35238bceSAndroid Build Coastguard Worker 
VertexVaryingShader(const glu::ContextType & contextType,int vertexOut,int geometryOut)515*35238bceSAndroid Build Coastguard Worker VertexVaryingShader::VertexVaryingShader(const glu::ContextType &contextType, int vertexOut, int geometryOut)
516*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(genProgramDeclaration(contextType, vertexOut, geometryOut))
517*35238bceSAndroid Build Coastguard Worker     , m_vertexOut(vertexOut)
518*35238bceSAndroid Build Coastguard Worker     , m_geometryOut(geometryOut)
519*35238bceSAndroid Build Coastguard Worker {
520*35238bceSAndroid Build Coastguard Worker }
521*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const522*35238bceSAndroid Build Coastguard Worker void VertexVaryingShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
523*35238bceSAndroid Build Coastguard Worker                                         const int numPackets) const
524*35238bceSAndroid Build Coastguard Worker {
525*35238bceSAndroid Build Coastguard Worker     // vertex shader is no-op
526*35238bceSAndroid Build Coastguard Worker     if (m_vertexOut == -1)
527*35238bceSAndroid Build Coastguard Worker         return;
528*35238bceSAndroid Build Coastguard Worker 
529*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
530*35238bceSAndroid Build Coastguard Worker     {
531*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 color =
532*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
533*35238bceSAndroid Build Coastguard Worker 
534*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
535*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
536*35238bceSAndroid Build Coastguard Worker         packets[ndx]->pointSize = 1.0f;
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker         switch (m_vertexOut)
539*35238bceSAndroid Build Coastguard Worker         {
540*35238bceSAndroid Build Coastguard Worker         case 0:
541*35238bceSAndroid Build Coastguard Worker             break;
542*35238bceSAndroid Build Coastguard Worker 
543*35238bceSAndroid Build Coastguard Worker         case 1:
544*35238bceSAndroid Build Coastguard Worker             packets[ndx]->outputs[0] = color;
545*35238bceSAndroid Build Coastguard Worker             break;
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker         case 2:
548*35238bceSAndroid Build Coastguard Worker             packets[ndx]->outputs[0] = color * 0.5f;
549*35238bceSAndroid Build Coastguard Worker             packets[ndx]->outputs[1] = color.swizzle(2, 1, 0, 3) * 0.5f;
550*35238bceSAndroid Build Coastguard Worker             break;
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker         default:
553*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
554*35238bceSAndroid Build Coastguard Worker         }
555*35238bceSAndroid Build Coastguard Worker     }
556*35238bceSAndroid Build Coastguard Worker }
557*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const558*35238bceSAndroid Build Coastguard Worker void VertexVaryingShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
559*35238bceSAndroid Build Coastguard Worker                                          const rr::FragmentShadingContext &context) const
560*35238bceSAndroid Build Coastguard Worker {
561*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
562*35238bceSAndroid Build Coastguard Worker     {
563*35238bceSAndroid Build Coastguard Worker         switch (m_geometryOut)
564*35238bceSAndroid Build Coastguard Worker         {
565*35238bceSAndroid Build Coastguard Worker         case 0:
566*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
567*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
568*35238bceSAndroid Build Coastguard Worker             break;
569*35238bceSAndroid Build Coastguard Worker 
570*35238bceSAndroid Build Coastguard Worker         case 1:
571*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
572*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
573*35238bceSAndroid Build Coastguard Worker                                         rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx));
574*35238bceSAndroid Build Coastguard Worker             break;
575*35238bceSAndroid Build Coastguard Worker 
576*35238bceSAndroid Build Coastguard Worker         case 2:
577*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
578*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(
579*35238bceSAndroid Build Coastguard Worker                     context, packetNdx, fragNdx, 0,
580*35238bceSAndroid Build Coastguard Worker                     rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx) +
581*35238bceSAndroid Build Coastguard Worker                         rr::readTriangleVarying<float>(packets[packetNdx], context, 1, fragNdx).swizzle(1, 0, 2, 3));
582*35238bceSAndroid Build Coastguard Worker             break;
583*35238bceSAndroid Build Coastguard Worker 
584*35238bceSAndroid Build Coastguard Worker         default:
585*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
586*35238bceSAndroid Build Coastguard Worker         }
587*35238bceSAndroid Build Coastguard Worker     }
588*35238bceSAndroid Build Coastguard Worker }
589*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const590*35238bceSAndroid Build Coastguard Worker void VertexVaryingShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
591*35238bceSAndroid Build Coastguard Worker                                           const rr::PrimitivePacket *packets, const int numPackets,
592*35238bceSAndroid Build Coastguard Worker                                           int invocationID) const
593*35238bceSAndroid Build Coastguard Worker {
594*35238bceSAndroid Build Coastguard Worker     DE_UNREF(invocationID);
595*35238bceSAndroid Build Coastguard Worker 
596*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexOffset(-0.2f, -0.2f, 0, 0);
597*35238bceSAndroid Build Coastguard Worker 
598*35238bceSAndroid Build Coastguard Worker     if (m_vertexOut == -1)
599*35238bceSAndroid Build Coastguard Worker     {
600*35238bceSAndroid Build Coastguard Worker         // vertex is a no-op
601*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 inputColor = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
602*35238bceSAndroid Build Coastguard Worker         rr::GenericVec4 outputs[2];
603*35238bceSAndroid Build Coastguard Worker 
604*35238bceSAndroid Build Coastguard Worker         // output color
605*35238bceSAndroid Build Coastguard Worker         switch (m_geometryOut)
606*35238bceSAndroid Build Coastguard Worker         {
607*35238bceSAndroid Build Coastguard Worker         case 0:
608*35238bceSAndroid Build Coastguard Worker             break;
609*35238bceSAndroid Build Coastguard Worker 
610*35238bceSAndroid Build Coastguard Worker         case 1:
611*35238bceSAndroid Build Coastguard Worker             outputs[0] = inputColor;
612*35238bceSAndroid Build Coastguard Worker             break;
613*35238bceSAndroid Build Coastguard Worker 
614*35238bceSAndroid Build Coastguard Worker         case 2:
615*35238bceSAndroid Build Coastguard Worker             outputs[0] = inputColor * 0.5f;
616*35238bceSAndroid Build Coastguard Worker             outputs[1] = inputColor.swizzle(1, 0, 2, 3) * 0.5f;
617*35238bceSAndroid Build Coastguard Worker             break;
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker         default:
620*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
621*35238bceSAndroid Build Coastguard Worker         }
622*35238bceSAndroid Build Coastguard Worker 
623*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < numPackets; ++ndx)
624*35238bceSAndroid Build Coastguard Worker         {
625*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f) + vertexOffset, 1.0f, outputs,
626*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
627*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) + vertexOffset, 1.0f, outputs,
628*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
629*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f) + vertexOffset, 1.0f, outputs,
630*35238bceSAndroid Build Coastguard Worker                               packets[ndx].primitiveIDIn);
631*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
632*35238bceSAndroid Build Coastguard Worker         }
633*35238bceSAndroid Build Coastguard Worker     }
634*35238bceSAndroid Build Coastguard Worker     else
635*35238bceSAndroid Build Coastguard Worker     {
636*35238bceSAndroid Build Coastguard Worker         // vertex is not a no-op
637*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < numPackets; ++ndx)
638*35238bceSAndroid Build Coastguard Worker         {
639*35238bceSAndroid Build Coastguard Worker             for (int verticeNdx = 0; verticeNdx < verticesIn; ++verticeNdx)
640*35238bceSAndroid Build Coastguard Worker             {
641*35238bceSAndroid Build Coastguard Worker                 tcu::Vec4 inputColor;
642*35238bceSAndroid Build Coastguard Worker                 rr::GenericVec4 outputs[2];
643*35238bceSAndroid Build Coastguard Worker 
644*35238bceSAndroid Build Coastguard Worker                 // input color
645*35238bceSAndroid Build Coastguard Worker                 switch (m_vertexOut)
646*35238bceSAndroid Build Coastguard Worker                 {
647*35238bceSAndroid Build Coastguard Worker                 case 0:
648*35238bceSAndroid Build Coastguard Worker                     inputColor = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
649*35238bceSAndroid Build Coastguard Worker                     break;
650*35238bceSAndroid Build Coastguard Worker 
651*35238bceSAndroid Build Coastguard Worker                 case 1:
652*35238bceSAndroid Build Coastguard Worker                     inputColor = packets[ndx].vertices[verticeNdx]->outputs[0].get<float>();
653*35238bceSAndroid Build Coastguard Worker                     break;
654*35238bceSAndroid Build Coastguard Worker 
655*35238bceSAndroid Build Coastguard Worker                 case 2:
656*35238bceSAndroid Build Coastguard Worker                     inputColor =
657*35238bceSAndroid Build Coastguard Worker                         (packets[ndx].vertices[verticeNdx]->outputs[0].get<float>() * 0.5f) +
658*35238bceSAndroid Build Coastguard Worker                         (packets[ndx].vertices[verticeNdx]->outputs[1].get<float>().swizzle(2, 1, 0, 3) * 0.5f);
659*35238bceSAndroid Build Coastguard Worker                     break;
660*35238bceSAndroid Build Coastguard Worker 
661*35238bceSAndroid Build Coastguard Worker                 default:
662*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
663*35238bceSAndroid Build Coastguard Worker                 }
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker                 // output color
666*35238bceSAndroid Build Coastguard Worker                 switch (m_geometryOut)
667*35238bceSAndroid Build Coastguard Worker                 {
668*35238bceSAndroid Build Coastguard Worker                 case 0:
669*35238bceSAndroid Build Coastguard Worker                     break;
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker                 case 1:
672*35238bceSAndroid Build Coastguard Worker                     outputs[0] = inputColor;
673*35238bceSAndroid Build Coastguard Worker                     break;
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker                 case 2:
676*35238bceSAndroid Build Coastguard Worker                     outputs[0] = inputColor * 0.5f;
677*35238bceSAndroid Build Coastguard Worker                     outputs[1] = inputColor.swizzle(1, 0, 2, 3) * 0.5f;
678*35238bceSAndroid Build Coastguard Worker                     break;
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker                 default:
681*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
682*35238bceSAndroid Build Coastguard Worker                 }
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker                 output.EmitVertex(packets[ndx].vertices[verticeNdx]->position + vertexOffset,
685*35238bceSAndroid Build Coastguard Worker                                   packets[ndx].vertices[verticeNdx]->pointSize, outputs, packets[ndx].primitiveIDIn);
686*35238bceSAndroid Build Coastguard Worker             }
687*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
688*35238bceSAndroid Build Coastguard Worker         }
689*35238bceSAndroid Build Coastguard Worker     }
690*35238bceSAndroid Build Coastguard Worker }
691*35238bceSAndroid Build Coastguard Worker 
genProgramDeclaration(const glu::ContextType & contextType,int vertexOut,int geometryOut)692*35238bceSAndroid Build Coastguard Worker sglr::pdec::ShaderProgramDeclaration VertexVaryingShader::genProgramDeclaration(const glu::ContextType &contextType,
693*35238bceSAndroid Build Coastguard Worker                                                                                 int vertexOut, int geometryOut)
694*35238bceSAndroid Build Coastguard Worker {
695*35238bceSAndroid Build Coastguard Worker     sglr::pdec::ShaderProgramDeclaration decl;
696*35238bceSAndroid Build Coastguard Worker     std::ostringstream vertexSource;
697*35238bceSAndroid Build Coastguard Worker     std::ostringstream fragmentSource;
698*35238bceSAndroid Build Coastguard Worker     std::ostringstream geometrySource;
699*35238bceSAndroid Build Coastguard Worker 
700*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
701*35238bceSAndroid Build Coastguard Worker          << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT);
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < vertexOut; ++i)
704*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT);
705*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < geometryOut; ++i)
706*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT);
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
709*35238bceSAndroid Build Coastguard Worker          << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES,
710*35238bceSAndroid Build Coastguard Worker                                                   rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP, 3);
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker     // vertexSource
713*35238bceSAndroid Build Coastguard Worker 
714*35238bceSAndroid Build Coastguard Worker     vertexSource << "${GLSL_VERSION_DECL}\n"
715*35238bceSAndroid Build Coastguard Worker                     "in highp vec4 a_position;\n"
716*35238bceSAndroid Build Coastguard Worker                     "in highp vec4 a_color;\n";
717*35238bceSAndroid Build Coastguard Worker 
718*35238bceSAndroid Build Coastguard Worker     // no-op case?
719*35238bceSAndroid Build Coastguard Worker     if (vertexOut == -1)
720*35238bceSAndroid Build Coastguard Worker     {
721*35238bceSAndroid Build Coastguard Worker         vertexSource << "void main (void)\n"
722*35238bceSAndroid Build Coastguard Worker                         "{\n"
723*35238bceSAndroid Build Coastguard Worker                         "}\n";
724*35238bceSAndroid Build Coastguard Worker     }
725*35238bceSAndroid Build Coastguard Worker     else
726*35238bceSAndroid Build Coastguard Worker     {
727*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < vertexOut; ++i)
728*35238bceSAndroid Build Coastguard Worker             vertexSource << "out highp vec4 v_geom_" << i << ";\n";
729*35238bceSAndroid Build Coastguard Worker 
730*35238bceSAndroid Build Coastguard Worker         vertexSource << "void main (void)\n"
731*35238bceSAndroid Build Coastguard Worker                         "{\n"
732*35238bceSAndroid Build Coastguard Worker                         "\tgl_Position = a_position;\n"
733*35238bceSAndroid Build Coastguard Worker                         "\tgl_PointSize = 1.0;\n";
734*35238bceSAndroid Build Coastguard Worker         switch (vertexOut)
735*35238bceSAndroid Build Coastguard Worker         {
736*35238bceSAndroid Build Coastguard Worker         case 0:
737*35238bceSAndroid Build Coastguard Worker             break;
738*35238bceSAndroid Build Coastguard Worker 
739*35238bceSAndroid Build Coastguard Worker         case 1:
740*35238bceSAndroid Build Coastguard Worker             vertexSource << "\tv_geom_0 = a_color;\n";
741*35238bceSAndroid Build Coastguard Worker             break;
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker         case 2:
744*35238bceSAndroid Build Coastguard Worker             vertexSource << "\tv_geom_0 = a_color * 0.5;\n";
745*35238bceSAndroid Build Coastguard Worker             vertexSource << "\tv_geom_1 = a_color.zyxw * 0.5;\n";
746*35238bceSAndroid Build Coastguard Worker             break;
747*35238bceSAndroid Build Coastguard Worker 
748*35238bceSAndroid Build Coastguard Worker         default:
749*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
750*35238bceSAndroid Build Coastguard Worker         }
751*35238bceSAndroid Build Coastguard Worker         vertexSource << "}\n";
752*35238bceSAndroid Build Coastguard Worker     }
753*35238bceSAndroid Build Coastguard Worker 
754*35238bceSAndroid Build Coastguard Worker     // fragmentSource
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker     fragmentSource << "${GLSL_VERSION_DECL}\n"
757*35238bceSAndroid Build Coastguard Worker                       "layout(location = 0) out mediump vec4 fragColor;\n";
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < geometryOut; ++i)
760*35238bceSAndroid Build Coastguard Worker         fragmentSource << "in mediump vec4 v_frag_" << i << ";\n";
761*35238bceSAndroid Build Coastguard Worker 
762*35238bceSAndroid Build Coastguard Worker     fragmentSource << "void main (void)\n"
763*35238bceSAndroid Build Coastguard Worker                       "{\n";
764*35238bceSAndroid Build Coastguard Worker     switch (geometryOut)
765*35238bceSAndroid Build Coastguard Worker     {
766*35238bceSAndroid Build Coastguard Worker     case 0:
767*35238bceSAndroid Build Coastguard Worker         fragmentSource << "\tfragColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
768*35238bceSAndroid Build Coastguard Worker         break;
769*35238bceSAndroid Build Coastguard Worker 
770*35238bceSAndroid Build Coastguard Worker     case 1:
771*35238bceSAndroid Build Coastguard Worker         fragmentSource << "\tfragColor = v_frag_0;\n";
772*35238bceSAndroid Build Coastguard Worker         break;
773*35238bceSAndroid Build Coastguard Worker 
774*35238bceSAndroid Build Coastguard Worker     case 2:
775*35238bceSAndroid Build Coastguard Worker         fragmentSource << "\tfragColor = v_frag_0 + v_frag_1.yxzw;\n";
776*35238bceSAndroid Build Coastguard Worker         break;
777*35238bceSAndroid Build Coastguard Worker 
778*35238bceSAndroid Build Coastguard Worker     default:
779*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
780*35238bceSAndroid Build Coastguard Worker     }
781*35238bceSAndroid Build Coastguard Worker     fragmentSource << "}\n";
782*35238bceSAndroid Build Coastguard Worker 
783*35238bceSAndroid Build Coastguard Worker     // geometrySource
784*35238bceSAndroid Build Coastguard Worker 
785*35238bceSAndroid Build Coastguard Worker     geometrySource << "${GLSL_VERSION_DECL}\n"
786*35238bceSAndroid Build Coastguard Worker                       "${GLSL_EXT_GEOMETRY_SHADER}"
787*35238bceSAndroid Build Coastguard Worker                       "layout(triangles) in;\n"
788*35238bceSAndroid Build Coastguard Worker                       "layout(triangle_strip, max_vertices = 3) out;\n";
789*35238bceSAndroid Build Coastguard Worker 
790*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < vertexOut; ++i)
791*35238bceSAndroid Build Coastguard Worker         geometrySource << "in highp vec4 v_geom_" << i << "[];\n";
792*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < geometryOut; ++i)
793*35238bceSAndroid Build Coastguard Worker         geometrySource << "out highp vec4 v_frag_" << i << ";\n";
794*35238bceSAndroid Build Coastguard Worker 
795*35238bceSAndroid Build Coastguard Worker     geometrySource << "void main (void)\n"
796*35238bceSAndroid Build Coastguard Worker                       "{\n"
797*35238bceSAndroid Build Coastguard Worker                       "\thighp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n"
798*35238bceSAndroid Build Coastguard Worker                       "\thighp vec4 inputColor;\n\n";
799*35238bceSAndroid Build Coastguard Worker 
800*35238bceSAndroid Build Coastguard Worker     for (int vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
801*35238bceSAndroid Build Coastguard Worker     {
802*35238bceSAndroid Build Coastguard Worker         if (vertexOut == -1)
803*35238bceSAndroid Build Coastguard Worker         {
804*35238bceSAndroid Build Coastguard Worker             // vertex is a no-op
805*35238bceSAndroid Build Coastguard Worker             geometrySource << "\tinputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
806*35238bceSAndroid Build Coastguard Worker                               "\tgl_Position = vec4("
807*35238bceSAndroid Build Coastguard Worker                            << ((vertexNdx == 0) ? ("0.0, 0.0") : ((vertexNdx == 1) ? ("1.0, 0.0") : ("1.0, 1.0")))
808*35238bceSAndroid Build Coastguard Worker                            << ", 0.0, 1.0) + offset;\n"
809*35238bceSAndroid Build Coastguard Worker                               "\tgl_PrimitiveID = gl_PrimitiveIDIn;\n";
810*35238bceSAndroid Build Coastguard Worker         }
811*35238bceSAndroid Build Coastguard Worker         else
812*35238bceSAndroid Build Coastguard Worker         {
813*35238bceSAndroid Build Coastguard Worker             switch (vertexOut)
814*35238bceSAndroid Build Coastguard Worker             {
815*35238bceSAndroid Build Coastguard Worker             case 0:
816*35238bceSAndroid Build Coastguard Worker                 geometrySource << "\tinputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
817*35238bceSAndroid Build Coastguard Worker                 break;
818*35238bceSAndroid Build Coastguard Worker 
819*35238bceSAndroid Build Coastguard Worker             case 1:
820*35238bceSAndroid Build Coastguard Worker                 geometrySource << "\tinputColor = v_geom_0[" << vertexNdx << "];\n";
821*35238bceSAndroid Build Coastguard Worker                 break;
822*35238bceSAndroid Build Coastguard Worker 
823*35238bceSAndroid Build Coastguard Worker             case 2:
824*35238bceSAndroid Build Coastguard Worker                 geometrySource << "\tinputColor = v_geom_0[" << vertexNdx << "] * 0.5 + v_geom_1[" << vertexNdx
825*35238bceSAndroid Build Coastguard Worker                                << "].zyxw * 0.5;\n";
826*35238bceSAndroid Build Coastguard Worker                 break;
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker             default:
829*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
830*35238bceSAndroid Build Coastguard Worker             }
831*35238bceSAndroid Build Coastguard Worker             geometrySource << "\tgl_Position = gl_in[" << vertexNdx
832*35238bceSAndroid Build Coastguard Worker                            << "].gl_Position + offset;\n"
833*35238bceSAndroid Build Coastguard Worker                               "\tgl_PrimitiveID = gl_PrimitiveIDIn;\n";
834*35238bceSAndroid Build Coastguard Worker         }
835*35238bceSAndroid Build Coastguard Worker 
836*35238bceSAndroid Build Coastguard Worker         switch (geometryOut)
837*35238bceSAndroid Build Coastguard Worker         {
838*35238bceSAndroid Build Coastguard Worker         case 0:
839*35238bceSAndroid Build Coastguard Worker             break;
840*35238bceSAndroid Build Coastguard Worker 
841*35238bceSAndroid Build Coastguard Worker         case 1:
842*35238bceSAndroid Build Coastguard Worker             geometrySource << "\tv_frag_0 = inputColor;\n";
843*35238bceSAndroid Build Coastguard Worker             break;
844*35238bceSAndroid Build Coastguard Worker 
845*35238bceSAndroid Build Coastguard Worker         case 2:
846*35238bceSAndroid Build Coastguard Worker             geometrySource << "\tv_frag_0 = inputColor * 0.5;\n";
847*35238bceSAndroid Build Coastguard Worker             geometrySource << "\tv_frag_1 = inputColor.yxzw * 0.5;\n";
848*35238bceSAndroid Build Coastguard Worker             break;
849*35238bceSAndroid Build Coastguard Worker 
850*35238bceSAndroid Build Coastguard Worker         default:
851*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
852*35238bceSAndroid Build Coastguard Worker         }
853*35238bceSAndroid Build Coastguard Worker 
854*35238bceSAndroid Build Coastguard Worker         geometrySource << "\tEmitVertex();\n\n";
855*35238bceSAndroid Build Coastguard Worker     }
856*35238bceSAndroid Build Coastguard Worker 
857*35238bceSAndroid Build Coastguard Worker     geometrySource << "\tEndPrimitive();\n"
858*35238bceSAndroid Build Coastguard Worker                       "}\n";
859*35238bceSAndroid Build Coastguard Worker 
860*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::VertexSource(specializeShader(vertexSource.str(), contextType))
861*35238bceSAndroid Build Coastguard Worker          << sglr::pdec::FragmentSource(specializeShader(fragmentSource.str(), contextType))
862*35238bceSAndroid Build Coastguard Worker          << sglr::pdec::GeometrySource(specializeShader(geometrySource.str(), contextType));
863*35238bceSAndroid Build Coastguard Worker     return decl;
864*35238bceSAndroid Build Coastguard Worker }
865*35238bceSAndroid Build Coastguard Worker 
866*35238bceSAndroid Build Coastguard Worker class OutputCountShader : public sglr::ShaderProgram
867*35238bceSAndroid Build Coastguard Worker {
868*35238bceSAndroid Build Coastguard Worker public:
869*35238bceSAndroid Build Coastguard Worker     OutputCountShader(const glu::ContextType &contextType, const OutputCountPatternSpec &spec);
870*35238bceSAndroid Build Coastguard Worker 
871*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
872*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
873*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
874*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
875*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
876*35238bceSAndroid Build Coastguard Worker 
877*35238bceSAndroid Build Coastguard Worker private:
878*35238bceSAndroid Build Coastguard Worker     std::string genGeometrySource(const glu::ContextType &contextType, const OutputCountPatternSpec &spec) const;
879*35238bceSAndroid Build Coastguard Worker     size_t getPatternEmitCount(const OutputCountPatternSpec &spec) const;
880*35238bceSAndroid Build Coastguard Worker 
881*35238bceSAndroid Build Coastguard Worker     const int m_patternLength;
882*35238bceSAndroid Build Coastguard Worker     const int m_patternMaxEmitCount;
883*35238bceSAndroid Build Coastguard Worker     const OutputCountPatternSpec m_spec;
884*35238bceSAndroid Build Coastguard Worker };
885*35238bceSAndroid Build Coastguard Worker 
OutputCountShader(const glu::ContextType & contextType,const OutputCountPatternSpec & spec)886*35238bceSAndroid Build Coastguard Worker OutputCountShader::OutputCountShader(const glu::ContextType &contextType, const OutputCountPatternSpec &spec)
887*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
888*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
889*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
890*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
891*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
892*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
893*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(specializeShader(s_commonShaderSourceVertex, contextType))
894*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(specializeShader(s_commonShaderSourceFragment, contextType))
895*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_POINTS,
896*35238bceSAndroid Build Coastguard Worker                                                                    rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP,
897*35238bceSAndroid Build Coastguard Worker                                                                    getPatternEmitCount(spec))
898*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, spec)))
899*35238bceSAndroid Build Coastguard Worker     , m_patternLength((int)spec.pattern.size())
900*35238bceSAndroid Build Coastguard Worker     , m_patternMaxEmitCount((int)getPatternEmitCount(spec))
901*35238bceSAndroid Build Coastguard Worker     , m_spec(spec)
902*35238bceSAndroid Build Coastguard Worker {
903*35238bceSAndroid Build Coastguard Worker }
904*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const905*35238bceSAndroid Build Coastguard Worker void OutputCountShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
906*35238bceSAndroid Build Coastguard Worker                                       const int numPackets) const
907*35238bceSAndroid Build Coastguard Worker {
908*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
909*35238bceSAndroid Build Coastguard Worker     {
910*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
911*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
912*35238bceSAndroid Build Coastguard Worker         packets[ndx]->pointSize = 1.0f;
913*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
914*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
915*35238bceSAndroid Build Coastguard Worker     }
916*35238bceSAndroid Build Coastguard Worker }
917*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const918*35238bceSAndroid Build Coastguard Worker void OutputCountShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
919*35238bceSAndroid Build Coastguard Worker                                        const rr::FragmentShadingContext &context) const
920*35238bceSAndroid Build Coastguard Worker {
921*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
922*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
923*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
924*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
925*35238bceSAndroid Build Coastguard Worker }
926*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const927*35238bceSAndroid Build Coastguard Worker void OutputCountShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
928*35238bceSAndroid Build Coastguard Worker                                         const int numPackets, int invocationID) const
929*35238bceSAndroid Build Coastguard Worker {
930*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
931*35238bceSAndroid Build Coastguard Worker     DE_UNREF(invocationID);
932*35238bceSAndroid Build Coastguard Worker 
933*35238bceSAndroid Build Coastguard Worker     const float rowHeight = 2.0f / (float)m_patternLength;
934*35238bceSAndroid Build Coastguard Worker     const float colWidth  = 2.0f / (float)m_patternMaxEmitCount;
935*35238bceSAndroid Build Coastguard Worker 
936*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
937*35238bceSAndroid Build Coastguard Worker     {
938*35238bceSAndroid Build Coastguard Worker         // Create triangle strip at this point
939*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[packetNdx].vertices[0];
940*35238bceSAndroid Build Coastguard Worker         const int emitCount            = m_spec.pattern[packets[packetNdx].primitiveIDIn];
941*35238bceSAndroid Build Coastguard Worker 
942*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < emitCount / 2; ++ndx)
943*35238bceSAndroid Build Coastguard Worker         {
944*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(2 * (float)ndx * colWidth, 0.0, 0.0, 0.0), vertex->pointSize,
945*35238bceSAndroid Build Coastguard Worker                               vertex->outputs, packets[packetNdx].primitiveIDIn);
946*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(2 * (float)ndx * colWidth, rowHeight, 0.0, 0.0),
947*35238bceSAndroid Build Coastguard Worker                               vertex->pointSize, vertex->outputs, packets[packetNdx].primitiveIDIn);
948*35238bceSAndroid Build Coastguard Worker         }
949*35238bceSAndroid Build Coastguard Worker         output.EndPrimitive();
950*35238bceSAndroid Build Coastguard Worker     }
951*35238bceSAndroid Build Coastguard Worker }
952*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,const OutputCountPatternSpec & spec) const953*35238bceSAndroid Build Coastguard Worker std::string OutputCountShader::genGeometrySource(const glu::ContextType &contextType,
954*35238bceSAndroid Build Coastguard Worker                                                  const OutputCountPatternSpec &spec) const
955*35238bceSAndroid Build Coastguard Worker {
956*35238bceSAndroid Build Coastguard Worker     std::ostringstream str;
957*35238bceSAndroid Build Coastguard Worker 
958*35238bceSAndroid Build Coastguard Worker     // draw row with a triangle strip, always make rectangles
959*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)spec.pattern.size(); ++ndx)
960*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(spec.pattern[ndx] % 2 == 0);
961*35238bceSAndroid Build Coastguard Worker 
962*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_VERSION_DECL}\n";
963*35238bceSAndroid Build Coastguard Worker     str << "${GLSL_EXT_GEOMETRY_SHADER}";
964*35238bceSAndroid Build Coastguard Worker     str << "layout(points) in;\n";
965*35238bceSAndroid Build Coastguard Worker     str << "layout(triangle_strip, max_vertices = " << getPatternEmitCount(spec) << ") out;";
966*35238bceSAndroid Build Coastguard Worker     str << "\n";
967*35238bceSAndroid Build Coastguard Worker 
968*35238bceSAndroid Build Coastguard Worker     str << "in highp vec4 v_geom_FragColor[];\n"
969*35238bceSAndroid Build Coastguard Worker            "out highp vec4 v_frag_FragColor;\n"
970*35238bceSAndroid Build Coastguard Worker            "\n"
971*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
972*35238bceSAndroid Build Coastguard Worker            "{\n"
973*35238bceSAndroid Build Coastguard Worker            "    const highp float rowHeight = 2.0 / float("
974*35238bceSAndroid Build Coastguard Worker         << spec.pattern.size()
975*35238bceSAndroid Build Coastguard Worker         << ");\n"
976*35238bceSAndroid Build Coastguard Worker            "    const highp float colWidth = 2.0 / float("
977*35238bceSAndroid Build Coastguard Worker         << getPatternEmitCount(spec)
978*35238bceSAndroid Build Coastguard Worker         << ");\n"
979*35238bceSAndroid Build Coastguard Worker            "\n";
980*35238bceSAndroid Build Coastguard Worker 
981*35238bceSAndroid Build Coastguard Worker     str << "    highp int emitCount = ";
982*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)spec.pattern.size() - 1; ++ndx)
983*35238bceSAndroid Build Coastguard Worker         str << "(gl_PrimitiveIDIn == " << ndx << ") ? (" << spec.pattern[ndx] << ") : (";
984*35238bceSAndroid Build Coastguard Worker     str << spec.pattern[(int)spec.pattern.size() - 1] << ((spec.pattern.size() == 1) ? ("") : (")")) << ";\n";
985*35238bceSAndroid Build Coastguard Worker 
986*35238bceSAndroid Build Coastguard Worker     str << "    for (highp int ndx = 0; ndx < emitCount / 2; ndx++)\n"
987*35238bceSAndroid Build Coastguard Worker            "    {\n"
988*35238bceSAndroid Build Coastguard Worker            "        gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, 0.0, 0.0, 0.0);\n"
989*35238bceSAndroid Build Coastguard Worker            "        v_frag_FragColor = v_geom_FragColor[0];\n"
990*35238bceSAndroid Build Coastguard Worker            "        EmitVertex();\n"
991*35238bceSAndroid Build Coastguard Worker            "\n"
992*35238bceSAndroid Build Coastguard Worker            "        gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, rowHeight, 0.0, 0.0);\n"
993*35238bceSAndroid Build Coastguard Worker            "        v_frag_FragColor = v_geom_FragColor[0];\n"
994*35238bceSAndroid Build Coastguard Worker            "        EmitVertex();\n"
995*35238bceSAndroid Build Coastguard Worker            "    }\n"
996*35238bceSAndroid Build Coastguard Worker            "}\n";
997*35238bceSAndroid Build Coastguard Worker 
998*35238bceSAndroid Build Coastguard Worker     return specializeShader(str.str(), contextType);
999*35238bceSAndroid Build Coastguard Worker }
1000*35238bceSAndroid Build Coastguard Worker 
getPatternEmitCount(const OutputCountPatternSpec & spec) const1001*35238bceSAndroid Build Coastguard Worker size_t OutputCountShader::getPatternEmitCount(const OutputCountPatternSpec &spec) const
1002*35238bceSAndroid Build Coastguard Worker {
1003*35238bceSAndroid Build Coastguard Worker     return *std::max_element(spec.pattern.begin(), spec.pattern.end());
1004*35238bceSAndroid Build Coastguard Worker }
1005*35238bceSAndroid Build Coastguard Worker 
1006*35238bceSAndroid Build Coastguard Worker class BuiltinVariableShader : public sglr::ShaderProgram
1007*35238bceSAndroid Build Coastguard Worker {
1008*35238bceSAndroid Build Coastguard Worker public:
1009*35238bceSAndroid Build Coastguard Worker     enum VariableTest
1010*35238bceSAndroid Build Coastguard Worker     {
1011*35238bceSAndroid Build Coastguard Worker         TEST_POINT_SIZE = 0,
1012*35238bceSAndroid Build Coastguard Worker         TEST_PRIMITIVE_ID_IN,
1013*35238bceSAndroid Build Coastguard Worker         TEST_PRIMITIVE_ID,
1014*35238bceSAndroid Build Coastguard Worker 
1015*35238bceSAndroid Build Coastguard Worker         TEST_LAST
1016*35238bceSAndroid Build Coastguard Worker     };
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker     BuiltinVariableShader(const glu::ContextType &contextType, VariableTest test);
1019*35238bceSAndroid Build Coastguard Worker 
1020*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
1021*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1022*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
1023*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
1024*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
1025*35238bceSAndroid Build Coastguard Worker 
1026*35238bceSAndroid Build Coastguard Worker     static const char *getTestAttributeName(VariableTest test);
1027*35238bceSAndroid Build Coastguard Worker 
1028*35238bceSAndroid Build Coastguard Worker private:
1029*35238bceSAndroid Build Coastguard Worker     std::string genGeometrySource(const glu::ContextType &contextType, VariableTest test) const;
1030*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(const glu::ContextType &contextType, VariableTest test) const;
1031*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(const glu::ContextType &contextType, VariableTest test) const;
1032*35238bceSAndroid Build Coastguard Worker 
1033*35238bceSAndroid Build Coastguard Worker     const VariableTest m_test;
1034*35238bceSAndroid Build Coastguard Worker };
1035*35238bceSAndroid Build Coastguard Worker 
BuiltinVariableShader(const glu::ContextType & contextType,VariableTest test)1036*35238bceSAndroid Build Coastguard Worker BuiltinVariableShader::BuiltinVariableShader(const glu::ContextType &contextType, VariableTest test)
1037*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
1038*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
1039*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute(getTestAttributeName(test), rr::GENERICVECTYPE_FLOAT)
1040*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
1041*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
1042*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
1043*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(genVertexSource(contextType, test))
1044*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(genFragmentSource(contextType, test))
1045*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_POINTS,
1046*35238bceSAndroid Build Coastguard Worker                                                                    ((test == TEST_POINT_SIZE) ?
1047*35238bceSAndroid Build Coastguard Worker                                                                         (rr::GEOMETRYSHADEROUTPUTTYPE_POINTS) :
1048*35238bceSAndroid Build Coastguard Worker                                                                         (rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP)),
1049*35238bceSAndroid Build Coastguard Worker                                                                    ((test == TEST_POINT_SIZE) ? (1) : (3)))
1050*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, test)))
1051*35238bceSAndroid Build Coastguard Worker     , m_test(test)
1052*35238bceSAndroid Build Coastguard Worker {
1053*35238bceSAndroid Build Coastguard Worker }
1054*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const1055*35238bceSAndroid Build Coastguard Worker void BuiltinVariableShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
1056*35238bceSAndroid Build Coastguard Worker                                           const int numPackets) const
1057*35238bceSAndroid Build Coastguard Worker {
1058*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
1059*35238bceSAndroid Build Coastguard Worker     {
1060*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
1061*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1062*35238bceSAndroid Build Coastguard Worker         packets[ndx]->pointSize = 1.0f;
1063*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
1064*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1065*35238bceSAndroid Build Coastguard Worker     }
1066*35238bceSAndroid Build Coastguard Worker }
1067*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const1068*35238bceSAndroid Build Coastguard Worker void BuiltinVariableShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1069*35238bceSAndroid Build Coastguard Worker                                            const rr::FragmentShadingContext &context) const
1070*35238bceSAndroid Build Coastguard Worker {
1071*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 red       = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1072*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green     = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1073*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 blue      = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
1074*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow    = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
1075*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 colors[4] = {yellow, red, green, blue};
1076*35238bceSAndroid Build Coastguard Worker 
1077*35238bceSAndroid Build Coastguard Worker     if (m_test == TEST_POINT_SIZE || m_test == TEST_PRIMITIVE_ID_IN)
1078*35238bceSAndroid Build Coastguard Worker     {
1079*35238bceSAndroid Build Coastguard Worker         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1080*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1081*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
1082*35238bceSAndroid Build Coastguard Worker                                         rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
1083*35238bceSAndroid Build Coastguard Worker     }
1084*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_PRIMITIVE_ID)
1085*35238bceSAndroid Build Coastguard Worker     {
1086*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 color = colors[context.primitiveID % 4];
1087*35238bceSAndroid Build Coastguard Worker 
1088*35238bceSAndroid Build Coastguard Worker         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1089*35238bceSAndroid Build Coastguard Worker             for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1090*35238bceSAndroid Build Coastguard Worker                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
1091*35238bceSAndroid Build Coastguard Worker     }
1092*35238bceSAndroid Build Coastguard Worker     else
1093*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1094*35238bceSAndroid Build Coastguard Worker }
1095*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const1096*35238bceSAndroid Build Coastguard Worker void BuiltinVariableShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
1097*35238bceSAndroid Build Coastguard Worker                                             const rr::PrimitivePacket *packets, const int numPackets,
1098*35238bceSAndroid Build Coastguard Worker                                             int invocationID) const
1099*35238bceSAndroid Build Coastguard Worker {
1100*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
1101*35238bceSAndroid Build Coastguard Worker     DE_UNREF(invocationID);
1102*35238bceSAndroid Build Coastguard Worker 
1103*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 red       = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1104*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green     = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1105*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 blue      = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
1106*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow    = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
1107*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 colors[4] = {red, green, blue, yellow};
1108*35238bceSAndroid Build Coastguard Worker 
1109*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1110*35238bceSAndroid Build Coastguard Worker     {
1111*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[packetNdx].vertices[0];
1112*35238bceSAndroid Build Coastguard Worker 
1113*35238bceSAndroid Build Coastguard Worker         if (m_test == TEST_POINT_SIZE)
1114*35238bceSAndroid Build Coastguard Worker         {
1115*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 fragColor;
1116*35238bceSAndroid Build Coastguard Worker             const float pointSize = vertex->outputs[0].get<float>().x() + 1.0f;
1117*35238bceSAndroid Build Coastguard Worker 
1118*35238bceSAndroid Build Coastguard Worker             fragColor = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1119*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position, pointSize, &fragColor, packets[packetNdx].primitiveIDIn);
1120*35238bceSAndroid Build Coastguard Worker         }
1121*35238bceSAndroid Build Coastguard Worker         else if (m_test == TEST_PRIMITIVE_ID_IN)
1122*35238bceSAndroid Build Coastguard Worker         {
1123*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 fragColor;
1124*35238bceSAndroid Build Coastguard Worker             fragColor = colors[packets[packetNdx].primitiveIDIn % 4];
1125*35238bceSAndroid Build Coastguard Worker 
1126*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(0.05f, 0.0f, 0.0f, 0.0f), 1.0f, &fragColor,
1127*35238bceSAndroid Build Coastguard Worker                               packets[packetNdx].primitiveIDIn);
1128*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position - tcu::Vec4(0.05f, 0.0f, 0.0f, 0.0f), 1.0f, &fragColor,
1129*35238bceSAndroid Build Coastguard Worker                               packets[packetNdx].primitiveIDIn);
1130*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(0.0f, 0.05f, 0.0f, 0.0f), 1.0f, &fragColor,
1131*35238bceSAndroid Build Coastguard Worker                               packets[packetNdx].primitiveIDIn);
1132*35238bceSAndroid Build Coastguard Worker         }
1133*35238bceSAndroid Build Coastguard Worker         else if (m_test == TEST_PRIMITIVE_ID)
1134*35238bceSAndroid Build Coastguard Worker         {
1135*35238bceSAndroid Build Coastguard Worker             const int primitiveID = (int)deFloatFloor(vertex->outputs[0].get<float>().x()) + 3;
1136*35238bceSAndroid Build Coastguard Worker 
1137*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(0.05f, 0.0f, 0.0f, 0.0f), 1.0f, vertex->outputs,
1138*35238bceSAndroid Build Coastguard Worker                               primitiveID);
1139*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position - tcu::Vec4(0.05f, 0.0f, 0.0f, 0.0f), 1.0f, vertex->outputs,
1140*35238bceSAndroid Build Coastguard Worker                               primitiveID);
1141*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(vertex->position + tcu::Vec4(0.0f, 0.05f, 0.0f, 0.0f), 1.0f, vertex->outputs,
1142*35238bceSAndroid Build Coastguard Worker                               primitiveID);
1143*35238bceSAndroid Build Coastguard Worker         }
1144*35238bceSAndroid Build Coastguard Worker         else
1145*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1146*35238bceSAndroid Build Coastguard Worker 
1147*35238bceSAndroid Build Coastguard Worker         output.EndPrimitive();
1148*35238bceSAndroid Build Coastguard Worker     }
1149*35238bceSAndroid Build Coastguard Worker }
1150*35238bceSAndroid Build Coastguard Worker 
getTestAttributeName(VariableTest test)1151*35238bceSAndroid Build Coastguard Worker const char *BuiltinVariableShader::getTestAttributeName(VariableTest test)
1152*35238bceSAndroid Build Coastguard Worker {
1153*35238bceSAndroid Build Coastguard Worker     switch (test)
1154*35238bceSAndroid Build Coastguard Worker     {
1155*35238bceSAndroid Build Coastguard Worker     case TEST_POINT_SIZE:
1156*35238bceSAndroid Build Coastguard Worker         return "a_pointSize";
1157*35238bceSAndroid Build Coastguard Worker     case TEST_PRIMITIVE_ID_IN:
1158*35238bceSAndroid Build Coastguard Worker         return "";
1159*35238bceSAndroid Build Coastguard Worker     case TEST_PRIMITIVE_ID:
1160*35238bceSAndroid Build Coastguard Worker         return "a_primitiveID";
1161*35238bceSAndroid Build Coastguard Worker     default:
1162*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1163*35238bceSAndroid Build Coastguard Worker         return "";
1164*35238bceSAndroid Build Coastguard Worker     }
1165*35238bceSAndroid Build Coastguard Worker }
1166*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,VariableTest test) const1167*35238bceSAndroid Build Coastguard Worker std::string BuiltinVariableShader::genGeometrySource(const glu::ContextType &contextType, VariableTest test) const
1168*35238bceSAndroid Build Coastguard Worker {
1169*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1170*35238bceSAndroid Build Coastguard Worker 
1171*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1172*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXT_GEOMETRY_SHADER}";
1173*35238bceSAndroid Build Coastguard Worker 
1174*35238bceSAndroid Build Coastguard Worker     const bool supportsGL45 = glu::contextSupports(contextType, glu::ApiType::core(4, 5));
1175*35238bceSAndroid Build Coastguard Worker 
1176*35238bceSAndroid Build Coastguard Worker     /* GL_EXT_geometry_point_size not available on desktop GLSL. */
1177*35238bceSAndroid Build Coastguard Worker     if (!supportsGL45 && test == TEST_POINT_SIZE)
1178*35238bceSAndroid Build Coastguard Worker         buf << "#extension GL_EXT_geometry_point_size : require\n";
1179*35238bceSAndroid Build Coastguard Worker 
1180*35238bceSAndroid Build Coastguard Worker     buf << "layout(points) in;\n";
1181*35238bceSAndroid Build Coastguard Worker 
1182*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1183*35238bceSAndroid Build Coastguard Worker         buf << "layout(points, max_vertices = 1) out;\n";
1184*35238bceSAndroid Build Coastguard Worker     else
1185*35238bceSAndroid Build Coastguard Worker         buf << "layout(triangle_strip, max_vertices = 3) out;\n";
1186*35238bceSAndroid Build Coastguard Worker 
1187*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1188*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 v_geom_pointSize[];\n";
1189*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1190*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 v_geom_primitiveID[];\n";
1191*35238bceSAndroid Build Coastguard Worker 
1192*35238bceSAndroid Build Coastguard Worker     if (test != TEST_PRIMITIVE_ID)
1193*35238bceSAndroid Build Coastguard Worker         buf << "out highp vec4 v_frag_FragColor;\n";
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker     buf << "\n"
1196*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1197*35238bceSAndroid Build Coastguard Worker            "{\n";
1198*35238bceSAndroid Build Coastguard Worker 
1199*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1200*35238bceSAndroid Build Coastguard Worker     {
1201*35238bceSAndroid Build Coastguard Worker         buf << "    gl_Position = gl_in[0].gl_Position;\n"
1202*35238bceSAndroid Build Coastguard Worker                "    gl_PointSize = v_geom_pointSize[0].x + 1.0;\n"
1203*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1204*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
1205*35238bceSAndroid Build Coastguard Worker     }
1206*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID_IN)
1207*35238bceSAndroid Build Coastguard Worker     {
1208*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1209*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1210*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1211*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1212*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
1213*35238bceSAndroid Build Coastguard Worker                "\n"
1214*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(0.05, 0.0, 0.0, 0.0);\n"
1215*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1216*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1217*35238bceSAndroid Build Coastguard Worker                "\n"
1218*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position - vec4(0.05, 0.0, 0.0, 0.0);\n"
1219*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1220*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1221*35238bceSAndroid Build Coastguard Worker                "\n"
1222*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.05, 0.0, 0.0);\n"
1223*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1224*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
1225*35238bceSAndroid Build Coastguard Worker     }
1226*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1227*35238bceSAndroid Build Coastguard Worker     {
1228*35238bceSAndroid Build Coastguard Worker         buf << "    gl_Position = gl_in[0].gl_Position + vec4(0.05, 0.0, 0.0, 0.0);\n"
1229*35238bceSAndroid Build Coastguard Worker                "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1230*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1231*35238bceSAndroid Build Coastguard Worker                "\n"
1232*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position - vec4(0.05, 0.0, 0.0, 0.0);\n"
1233*35238bceSAndroid Build Coastguard Worker                "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1234*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1235*35238bceSAndroid Build Coastguard Worker                "\n"
1236*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.05, 0.0, 0.0);\n"
1237*35238bceSAndroid Build Coastguard Worker                "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1238*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1239*35238bceSAndroid Build Coastguard Worker                "\n";
1240*35238bceSAndroid Build Coastguard Worker     }
1241*35238bceSAndroid Build Coastguard Worker     else
1242*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1243*35238bceSAndroid Build Coastguard Worker 
1244*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1245*35238bceSAndroid Build Coastguard Worker 
1246*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1247*35238bceSAndroid Build Coastguard Worker }
1248*35238bceSAndroid Build Coastguard Worker 
genVertexSource(const glu::ContextType & contextType,VariableTest test) const1249*35238bceSAndroid Build Coastguard Worker std::string BuiltinVariableShader::genVertexSource(const glu::ContextType &contextType, VariableTest test) const
1250*35238bceSAndroid Build Coastguard Worker {
1251*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1252*35238bceSAndroid Build Coastguard Worker 
1253*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1254*35238bceSAndroid Build Coastguard Worker            "in highp vec4 a_position;\n";
1255*35238bceSAndroid Build Coastguard Worker 
1256*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1257*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 a_pointSize;\n";
1258*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1259*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 a_primitiveID;\n";
1260*35238bceSAndroid Build Coastguard Worker 
1261*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1262*35238bceSAndroid Build Coastguard Worker         buf << "out highp vec4 v_geom_pointSize;\n";
1263*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1264*35238bceSAndroid Build Coastguard Worker         buf << "out highp vec4 v_geom_primitiveID;\n";
1265*35238bceSAndroid Build Coastguard Worker 
1266*35238bceSAndroid Build Coastguard Worker     buf << "void main (void)\n"
1267*35238bceSAndroid Build Coastguard Worker            "{\n"
1268*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_position;\n"
1269*35238bceSAndroid Build Coastguard Worker            "    gl_PointSize = 1.0;\n";
1270*35238bceSAndroid Build Coastguard Worker 
1271*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE)
1272*35238bceSAndroid Build Coastguard Worker         buf << "    v_geom_pointSize = a_pointSize;\n";
1273*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1274*35238bceSAndroid Build Coastguard Worker         buf << "    v_geom_primitiveID = a_primitiveID;\n";
1275*35238bceSAndroid Build Coastguard Worker 
1276*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1277*35238bceSAndroid Build Coastguard Worker 
1278*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1279*35238bceSAndroid Build Coastguard Worker }
1280*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(const glu::ContextType & contextType,VariableTest test) const1281*35238bceSAndroid Build Coastguard Worker std::string BuiltinVariableShader::genFragmentSource(const glu::ContextType &contextType, VariableTest test) const
1282*35238bceSAndroid Build Coastguard Worker {
1283*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1284*35238bceSAndroid Build Coastguard Worker 
1285*35238bceSAndroid Build Coastguard Worker     if (test == TEST_POINT_SIZE || test == TEST_PRIMITIVE_ID_IN)
1286*35238bceSAndroid Build Coastguard Worker         return specializeShader(s_commonShaderSourceFragment, contextType);
1287*35238bceSAndroid Build Coastguard Worker     else if (test == TEST_PRIMITIVE_ID)
1288*35238bceSAndroid Build Coastguard Worker     {
1289*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_VERSION_DECL}\n"
1290*35238bceSAndroid Build Coastguard Worker                "${GLSL_EXT_GEOMETRY_SHADER}"
1291*35238bceSAndroid Build Coastguard Worker                "layout(location = 0) out mediump vec4 fragColor;\n"
1292*35238bceSAndroid Build Coastguard Worker                "void main (void)\n"
1293*35238bceSAndroid Build Coastguard Worker                "{\n"
1294*35238bceSAndroid Build Coastguard Worker                "    const mediump vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1295*35238bceSAndroid Build Coastguard Worker                "    const mediump vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1296*35238bceSAndroid Build Coastguard Worker                "    const mediump vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1297*35238bceSAndroid Build Coastguard Worker                "    const mediump vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1298*35238bceSAndroid Build Coastguard Worker                "    const mediump vec4 colors[4] = vec4[4](yellow, red, green, blue);\n"
1299*35238bceSAndroid Build Coastguard Worker                "    fragColor = colors[gl_PrimitiveID % 4];\n"
1300*35238bceSAndroid Build Coastguard Worker                "}\n";
1301*35238bceSAndroid Build Coastguard Worker 
1302*35238bceSAndroid Build Coastguard Worker         return specializeShader(buf.str(), contextType);
1303*35238bceSAndroid Build Coastguard Worker     }
1304*35238bceSAndroid Build Coastguard Worker     else
1305*35238bceSAndroid Build Coastguard Worker     {
1306*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1307*35238bceSAndroid Build Coastguard Worker         return "";
1308*35238bceSAndroid Build Coastguard Worker     }
1309*35238bceSAndroid Build Coastguard Worker }
1310*35238bceSAndroid Build Coastguard Worker 
1311*35238bceSAndroid Build Coastguard Worker class VaryingOutputCountShader : public sglr::ShaderProgram
1312*35238bceSAndroid Build Coastguard Worker {
1313*35238bceSAndroid Build Coastguard Worker public:
1314*35238bceSAndroid Build Coastguard Worker     enum VaryingSource
1315*35238bceSAndroid Build Coastguard Worker     {
1316*35238bceSAndroid Build Coastguard Worker         READ_ATTRIBUTE = 0,
1317*35238bceSAndroid Build Coastguard Worker         READ_UNIFORM,
1318*35238bceSAndroid Build Coastguard Worker         READ_TEXTURE,
1319*35238bceSAndroid Build Coastguard Worker 
1320*35238bceSAndroid Build Coastguard Worker         READ_LAST
1321*35238bceSAndroid Build Coastguard Worker     };
1322*35238bceSAndroid Build Coastguard Worker 
1323*35238bceSAndroid Build Coastguard Worker     enum
1324*35238bceSAndroid Build Coastguard Worker     {
1325*35238bceSAndroid Build Coastguard Worker         EMIT_COUNT_VERTEX_0 = 6,
1326*35238bceSAndroid Build Coastguard Worker         EMIT_COUNT_VERTEX_1 = 0,
1327*35238bceSAndroid Build Coastguard Worker         EMIT_COUNT_VERTEX_2 = -1,
1328*35238bceSAndroid Build Coastguard Worker         EMIT_COUNT_VERTEX_3 = 10,
1329*35238bceSAndroid Build Coastguard Worker     };
1330*35238bceSAndroid Build Coastguard Worker 
1331*35238bceSAndroid Build Coastguard Worker     VaryingOutputCountShader(const glu::ContextType &contextType, VaryingSource source, int maxEmitCount,
1332*35238bceSAndroid Build Coastguard Worker                              bool instanced);
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
1335*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1336*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
1337*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
1338*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
1339*35238bceSAndroid Build Coastguard Worker 
1340*35238bceSAndroid Build Coastguard Worker     static const char *getAttributeName(VaryingSource test);
1341*35238bceSAndroid Build Coastguard Worker 
1342*35238bceSAndroid Build Coastguard Worker private:
1343*35238bceSAndroid Build Coastguard Worker     static std::string genGeometrySource(const glu::ContextType &contextType, VaryingSource test, int maxEmitCount,
1344*35238bceSAndroid Build Coastguard Worker                                          bool instanced);
1345*35238bceSAndroid Build Coastguard Worker     static std::string genVertexSource(const glu::ContextType &contextType, VaryingSource test);
1346*35238bceSAndroid Build Coastguard Worker 
1347*35238bceSAndroid Build Coastguard Worker     const VaryingSource m_test;
1348*35238bceSAndroid Build Coastguard Worker     const sglr::UniformSlot &m_sampler;
1349*35238bceSAndroid Build Coastguard Worker     const sglr::UniformSlot &m_emitCount;
1350*35238bceSAndroid Build Coastguard Worker     const int m_maxEmitCount;
1351*35238bceSAndroid Build Coastguard Worker     const bool m_instanced;
1352*35238bceSAndroid Build Coastguard Worker };
1353*35238bceSAndroid Build Coastguard Worker 
VaryingOutputCountShader(const glu::ContextType & contextType,VaryingSource source,int maxEmitCount,bool instanced)1354*35238bceSAndroid Build Coastguard Worker VaryingOutputCountShader::VaryingOutputCountShader(const glu::ContextType &contextType, VaryingSource source,
1355*35238bceSAndroid Build Coastguard Worker                                                    int maxEmitCount, bool instanced)
1356*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(
1357*35238bceSAndroid Build Coastguard Worker           sglr::pdec::ShaderProgramDeclaration()
1358*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::Uniform("u_sampler", glu::TYPE_SAMPLER_2D)
1359*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::Uniform("u_emitCount", glu::TYPE_INT_VEC4)
1360*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
1361*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::VertexAttribute(getAttributeName(source), rr::GENERICVECTYPE_FLOAT)
1362*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
1363*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
1364*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
1365*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::VertexSource(genVertexSource(contextType, source))
1366*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::FragmentSource(specializeShader(s_commonShaderSourceFragment, contextType))
1367*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_POINTS,
1368*35238bceSAndroid Build Coastguard Worker                                                    rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP, maxEmitCount,
1369*35238bceSAndroid Build Coastguard Worker                                                    (instanced) ? (4) : (1))
1370*35238bceSAndroid Build Coastguard Worker           << sglr::pdec::GeometrySource(genGeometrySource(contextType, source, maxEmitCount, instanced)))
1371*35238bceSAndroid Build Coastguard Worker     , m_test(source)
1372*35238bceSAndroid Build Coastguard Worker     , m_sampler(getUniformByName("u_sampler"))
1373*35238bceSAndroid Build Coastguard Worker     , m_emitCount(getUniformByName("u_emitCount"))
1374*35238bceSAndroid Build Coastguard Worker     , m_maxEmitCount(maxEmitCount)
1375*35238bceSAndroid Build Coastguard Worker     , m_instanced(instanced)
1376*35238bceSAndroid Build Coastguard Worker {
1377*35238bceSAndroid Build Coastguard Worker }
1378*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const1379*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
1380*35238bceSAndroid Build Coastguard Worker                                              const int numPackets) const
1381*35238bceSAndroid Build Coastguard Worker {
1382*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
1383*35238bceSAndroid Build Coastguard Worker     {
1384*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
1385*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1386*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
1387*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1388*35238bceSAndroid Build Coastguard Worker     }
1389*35238bceSAndroid Build Coastguard Worker }
1390*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const1391*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1392*35238bceSAndroid Build Coastguard Worker                                               const rr::FragmentShadingContext &context) const
1393*35238bceSAndroid Build Coastguard Worker {
1394*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1395*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1396*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
1397*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
1398*35238bceSAndroid Build Coastguard Worker }
1399*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const1400*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
1401*35238bceSAndroid Build Coastguard Worker                                                const rr::PrimitivePacket *packets, const int numPackets,
1402*35238bceSAndroid Build Coastguard Worker                                                int invocationID) const
1403*35238bceSAndroid Build Coastguard Worker {
1404*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
1405*35238bceSAndroid Build Coastguard Worker 
1406*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 red       = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1407*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green     = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1408*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 blue      = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
1409*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow    = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
1410*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 colors[4] = {red, green, blue, yellow};
1411*35238bceSAndroid Build Coastguard Worker 
1412*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1413*35238bceSAndroid Build Coastguard Worker     {
1414*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[packetNdx].vertices[0];
1415*35238bceSAndroid Build Coastguard Worker         int emitCount                  = 0;
1416*35238bceSAndroid Build Coastguard Worker         tcu::Vec4 color                = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1417*35238bceSAndroid Build Coastguard Worker 
1418*35238bceSAndroid Build Coastguard Worker         if (m_test == READ_ATTRIBUTE)
1419*35238bceSAndroid Build Coastguard Worker         {
1420*35238bceSAndroid Build Coastguard Worker             emitCount = (int)vertex->outputs[0].get<float>()[(m_instanced) ? (invocationID) : (0)];
1421*35238bceSAndroid Build Coastguard Worker             color     = tcu::Vec4((emitCount < 10) ? (0.0f) : (1.0f), (emitCount > 10) ? (0.0f) : (1.0f), 1.0f, 1.0f);
1422*35238bceSAndroid Build Coastguard Worker         }
1423*35238bceSAndroid Build Coastguard Worker         else if (m_test == READ_UNIFORM)
1424*35238bceSAndroid Build Coastguard Worker         {
1425*35238bceSAndroid Build Coastguard Worker             const int primitiveNdx = (m_instanced) ? (invocationID) : ((int)vertex->outputs[0].get<float>().x());
1426*35238bceSAndroid Build Coastguard Worker 
1427*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(primitiveNdx >= 0);
1428*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(primitiveNdx < 4);
1429*35238bceSAndroid Build Coastguard Worker 
1430*35238bceSAndroid Build Coastguard Worker             emitCount = m_emitCount.value.i4[primitiveNdx];
1431*35238bceSAndroid Build Coastguard Worker             color     = colors[primitiveNdx];
1432*35238bceSAndroid Build Coastguard Worker         }
1433*35238bceSAndroid Build Coastguard Worker         else if (m_test == READ_TEXTURE)
1434*35238bceSAndroid Build Coastguard Worker         {
1435*35238bceSAndroid Build Coastguard Worker             const int primitiveNdx   = (m_instanced) ? (invocationID) : ((int)vertex->outputs[0].get<float>().x());
1436*35238bceSAndroid Build Coastguard Worker             const tcu::Vec2 texCoord = tcu::Vec2(1.0f / 8.0f + (float)primitiveNdx / 4.0f, 0.5f);
1437*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 texColor = m_sampler.sampler.tex2D->sample(texCoord.x(), texCoord.y(), 0.0f);
1438*35238bceSAndroid Build Coastguard Worker 
1439*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(primitiveNdx >= 0);
1440*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(primitiveNdx < 4);
1441*35238bceSAndroid Build Coastguard Worker 
1442*35238bceSAndroid Build Coastguard Worker             color     = colors[primitiveNdx];
1443*35238bceSAndroid Build Coastguard Worker             emitCount = 0;
1444*35238bceSAndroid Build Coastguard Worker 
1445*35238bceSAndroid Build Coastguard Worker             if (texColor.x() > 0.0f)
1446*35238bceSAndroid Build Coastguard Worker                 emitCount += (EMIT_COUNT_VERTEX_0 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_0);
1447*35238bceSAndroid Build Coastguard Worker             if (texColor.y() > 0.0f)
1448*35238bceSAndroid Build Coastguard Worker                 emitCount += (EMIT_COUNT_VERTEX_1 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_1);
1449*35238bceSAndroid Build Coastguard Worker             if (texColor.z() > 0.0f)
1450*35238bceSAndroid Build Coastguard Worker                 emitCount += (EMIT_COUNT_VERTEX_2 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_2);
1451*35238bceSAndroid Build Coastguard Worker             if (texColor.w() > 0.0f)
1452*35238bceSAndroid Build Coastguard Worker                 emitCount += (EMIT_COUNT_VERTEX_3 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_3);
1453*35238bceSAndroid Build Coastguard Worker         }
1454*35238bceSAndroid Build Coastguard Worker         else
1455*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1456*35238bceSAndroid Build Coastguard Worker 
1457*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)emitCount / 2; ++ndx)
1458*35238bceSAndroid Build Coastguard Worker         {
1459*35238bceSAndroid Build Coastguard Worker             const float angle = (float(ndx) + 0.5f) / float(emitCount / 2) * 3.142f;
1460*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 basePosition =
1461*35238bceSAndroid Build Coastguard Worker                 (m_instanced) ?
1462*35238bceSAndroid Build Coastguard Worker                     (vertex->position +
1463*35238bceSAndroid Build Coastguard Worker                      tcu::Vec4(deFloatCos(float(invocationID)), deFloatSin(float(invocationID)), 0.0f, 0.0f) * 0.5f) :
1464*35238bceSAndroid Build Coastguard Worker                     (vertex->position);
1465*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 position0 =
1466*35238bceSAndroid Build Coastguard Worker                 basePosition + tcu::Vec4(deFloatCos(angle), deFloatSin(angle), 0.0f, 0.0f) * 0.15f;
1467*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 position1 =
1468*35238bceSAndroid Build Coastguard Worker                 basePosition + tcu::Vec4(deFloatCos(angle), -deFloatSin(angle), 0.0f, 0.0f) * 0.15f;
1469*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 fragColor;
1470*35238bceSAndroid Build Coastguard Worker 
1471*35238bceSAndroid Build Coastguard Worker             fragColor = color;
1472*35238bceSAndroid Build Coastguard Worker 
1473*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(position0, 0.0f, &fragColor, packets[packetNdx].primitiveIDIn);
1474*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(position1, 0.0f, &fragColor, packets[packetNdx].primitiveIDIn);
1475*35238bceSAndroid Build Coastguard Worker         }
1476*35238bceSAndroid Build Coastguard Worker 
1477*35238bceSAndroid Build Coastguard Worker         output.EndPrimitive();
1478*35238bceSAndroid Build Coastguard Worker     }
1479*35238bceSAndroid Build Coastguard Worker }
1480*35238bceSAndroid Build Coastguard Worker 
getAttributeName(VaryingSource test)1481*35238bceSAndroid Build Coastguard Worker const char *VaryingOutputCountShader::getAttributeName(VaryingSource test)
1482*35238bceSAndroid Build Coastguard Worker {
1483*35238bceSAndroid Build Coastguard Worker     switch (test)
1484*35238bceSAndroid Build Coastguard Worker     {
1485*35238bceSAndroid Build Coastguard Worker     case READ_ATTRIBUTE:
1486*35238bceSAndroid Build Coastguard Worker         return "a_emitCount";
1487*35238bceSAndroid Build Coastguard Worker     case READ_UNIFORM:
1488*35238bceSAndroid Build Coastguard Worker         return "a_vertexNdx";
1489*35238bceSAndroid Build Coastguard Worker     case READ_TEXTURE:
1490*35238bceSAndroid Build Coastguard Worker         return "a_vertexNdx";
1491*35238bceSAndroid Build Coastguard Worker     default:
1492*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1493*35238bceSAndroid Build Coastguard Worker         return "";
1494*35238bceSAndroid Build Coastguard Worker     }
1495*35238bceSAndroid Build Coastguard Worker }
1496*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,VaryingSource test,int maxEmitCount,bool instanced)1497*35238bceSAndroid Build Coastguard Worker std::string VaryingOutputCountShader::genGeometrySource(const glu::ContextType &contextType, VaryingSource test,
1498*35238bceSAndroid Build Coastguard Worker                                                         int maxEmitCount, bool instanced)
1499*35238bceSAndroid Build Coastguard Worker {
1500*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1501*35238bceSAndroid Build Coastguard Worker 
1502*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1503*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXT_GEOMETRY_SHADER}"
1504*35238bceSAndroid Build Coastguard Worker            "layout(points"
1505*35238bceSAndroid Build Coastguard Worker         << ((instanced) ? (",invocations=4") : (""))
1506*35238bceSAndroid Build Coastguard Worker         << ") in;\n"
1507*35238bceSAndroid Build Coastguard Worker            "layout(triangle_strip, max_vertices = "
1508*35238bceSAndroid Build Coastguard Worker         << maxEmitCount << ") out;\n";
1509*35238bceSAndroid Build Coastguard Worker 
1510*35238bceSAndroid Build Coastguard Worker     if (test == READ_ATTRIBUTE)
1511*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 v_geom_emitCount[];\n";
1512*35238bceSAndroid Build Coastguard Worker     else if (test == READ_UNIFORM)
1513*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 v_geom_vertexNdx[];\n"
1514*35238bceSAndroid Build Coastguard Worker                "uniform highp ivec4 u_emitCount;\n";
1515*35238bceSAndroid Build Coastguard Worker     else
1516*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 v_geom_vertexNdx[];\n"
1517*35238bceSAndroid Build Coastguard Worker                "uniform highp sampler2D u_sampler;\n";
1518*35238bceSAndroid Build Coastguard Worker 
1519*35238bceSAndroid Build Coastguard Worker     buf << "out highp vec4 v_frag_FragColor;\n"
1520*35238bceSAndroid Build Coastguard Worker            "\n"
1521*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1522*35238bceSAndroid Build Coastguard Worker            "{\n";
1523*35238bceSAndroid Build Coastguard Worker 
1524*35238bceSAndroid Build Coastguard Worker     // emit count
1525*35238bceSAndroid Build Coastguard Worker 
1526*35238bceSAndroid Build Coastguard Worker     if (test == READ_ATTRIBUTE)
1527*35238bceSAndroid Build Coastguard Worker     {
1528*35238bceSAndroid Build Coastguard Worker         buf << "    highp vec4 attrEmitCounts = v_geom_emitCount[0];\n"
1529*35238bceSAndroid Build Coastguard Worker                "    mediump int emitCount = int(attrEmitCounts["
1530*35238bceSAndroid Build Coastguard Worker             << ((instanced) ? ("gl_InvocationID") : ("0")) << "]);\n";
1531*35238bceSAndroid Build Coastguard Worker     }
1532*35238bceSAndroid Build Coastguard Worker     else if (test == READ_UNIFORM)
1533*35238bceSAndroid Build Coastguard Worker     {
1534*35238bceSAndroid Build Coastguard Worker         buf << "    mediump int primitiveNdx = " << ((instanced) ? ("gl_InvocationID") : ("int(v_geom_vertexNdx[0].x)"))
1535*35238bceSAndroid Build Coastguard Worker             << ";\n"
1536*35238bceSAndroid Build Coastguard Worker                "    mediump int emitCount = u_emitCount[primitiveNdx];\n";
1537*35238bceSAndroid Build Coastguard Worker     }
1538*35238bceSAndroid Build Coastguard Worker     else if (test == READ_TEXTURE)
1539*35238bceSAndroid Build Coastguard Worker     {
1540*35238bceSAndroid Build Coastguard Worker         buf << "    highp float primitiveNdx = "
1541*35238bceSAndroid Build Coastguard Worker             << ((instanced) ? ("float(gl_InvocationID)") : ("v_geom_vertexNdx[0].x"))
1542*35238bceSAndroid Build Coastguard Worker             << ";\n"
1543*35238bceSAndroid Build Coastguard Worker                "    highp vec2 texCoord = vec2(1.0 / 8.0 + primitiveNdx / 4.0, 0.5);\n"
1544*35238bceSAndroid Build Coastguard Worker                "    highp vec4 texColor = texture(u_sampler, texCoord);\n"
1545*35238bceSAndroid Build Coastguard Worker                "    mediump int emitCount = 0;\n"
1546*35238bceSAndroid Build Coastguard Worker                "    if (texColor.x > 0.0)\n"
1547*35238bceSAndroid Build Coastguard Worker                "        emitCount += "
1548*35238bceSAndroid Build Coastguard Worker             << ((EMIT_COUNT_VERTEX_0 == -1) ? (maxEmitCount) : (EMIT_COUNT_VERTEX_0))
1549*35238bceSAndroid Build Coastguard Worker             << ";\n"
1550*35238bceSAndroid Build Coastguard Worker                "    if (texColor.y > 0.0)\n"
1551*35238bceSAndroid Build Coastguard Worker                "        emitCount += "
1552*35238bceSAndroid Build Coastguard Worker             << ((EMIT_COUNT_VERTEX_1 == -1) ? (maxEmitCount) : (EMIT_COUNT_VERTEX_1))
1553*35238bceSAndroid Build Coastguard Worker             << ";\n"
1554*35238bceSAndroid Build Coastguard Worker                "    if (texColor.z > 0.0)\n"
1555*35238bceSAndroid Build Coastguard Worker                "        emitCount += "
1556*35238bceSAndroid Build Coastguard Worker             << ((EMIT_COUNT_VERTEX_2 == -1) ? (maxEmitCount) : (EMIT_COUNT_VERTEX_2))
1557*35238bceSAndroid Build Coastguard Worker             << ";\n"
1558*35238bceSAndroid Build Coastguard Worker                "    if (texColor.w > 0.0)\n"
1559*35238bceSAndroid Build Coastguard Worker                "        emitCount += "
1560*35238bceSAndroid Build Coastguard Worker             << ((EMIT_COUNT_VERTEX_3 == -1) ? (maxEmitCount) : (EMIT_COUNT_VERTEX_3)) << ";\n";
1561*35238bceSAndroid Build Coastguard Worker     }
1562*35238bceSAndroid Build Coastguard Worker     else
1563*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1564*35238bceSAndroid Build Coastguard Worker 
1565*35238bceSAndroid Build Coastguard Worker     // color
1566*35238bceSAndroid Build Coastguard Worker 
1567*35238bceSAndroid Build Coastguard Worker     if (test == READ_ATTRIBUTE)
1568*35238bceSAndroid Build Coastguard Worker     {
1569*35238bceSAndroid Build Coastguard Worker         // We don't want color to be compile time constant
1570*35238bceSAndroid Build Coastguard Worker         buf << "    highp vec4 color = vec4((emitCount < 10) ? (0.0) : (1.0), (emitCount > 10) ? (0.0) : (1.0), 1.0, "
1571*35238bceSAndroid Build Coastguard Worker                "1.0);\n";
1572*35238bceSAndroid Build Coastguard Worker     }
1573*35238bceSAndroid Build Coastguard Worker     else if (test == READ_UNIFORM || test == READ_TEXTURE)
1574*35238bceSAndroid Build Coastguard Worker     {
1575*35238bceSAndroid Build Coastguard Worker         buf << "\n"
1576*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1577*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1578*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1579*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1580*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
1581*35238bceSAndroid Build Coastguard Worker                "    highp vec4 color = colors[int(primitiveNdx)];\n";
1582*35238bceSAndroid Build Coastguard Worker     }
1583*35238bceSAndroid Build Coastguard Worker     else
1584*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1585*35238bceSAndroid Build Coastguard Worker 
1586*35238bceSAndroid Build Coastguard Worker     buf << "\n"
1587*35238bceSAndroid Build Coastguard Worker            "    highp vec4 basePos = "
1588*35238bceSAndroid Build Coastguard Worker         << ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), "
1589*35238bceSAndroid Build Coastguard Worker                            "sin(float(gl_InvocationID)), 0.0, 0.0)") :
1590*35238bceSAndroid Build Coastguard Worker                           ("gl_in[0].gl_Position"))
1591*35238bceSAndroid Build Coastguard Worker         << ";\n"
1592*35238bceSAndroid Build Coastguard Worker            "    for (mediump int i = 0; i < emitCount / 2; i++)\n"
1593*35238bceSAndroid Build Coastguard Worker            "    {\n"
1594*35238bceSAndroid Build Coastguard Worker            "        highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
1595*35238bceSAndroid Build Coastguard Worker            "        gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
1596*35238bceSAndroid Build Coastguard Worker            "        v_frag_FragColor = color;\n"
1597*35238bceSAndroid Build Coastguard Worker            "        EmitVertex();\n"
1598*35238bceSAndroid Build Coastguard Worker            "        gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
1599*35238bceSAndroid Build Coastguard Worker            "        v_frag_FragColor = color;\n"
1600*35238bceSAndroid Build Coastguard Worker            "        EmitVertex();\n"
1601*35238bceSAndroid Build Coastguard Worker            "    }"
1602*35238bceSAndroid Build Coastguard Worker            "}\n";
1603*35238bceSAndroid Build Coastguard Worker 
1604*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1605*35238bceSAndroid Build Coastguard Worker }
1606*35238bceSAndroid Build Coastguard Worker 
genVertexSource(const glu::ContextType & contextType,VaryingSource test)1607*35238bceSAndroid Build Coastguard Worker std::string VaryingOutputCountShader::genVertexSource(const glu::ContextType &contextType, VaryingSource test)
1608*35238bceSAndroid Build Coastguard Worker {
1609*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1610*35238bceSAndroid Build Coastguard Worker 
1611*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1612*35238bceSAndroid Build Coastguard Worker            "in highp vec4 a_position;\n";
1613*35238bceSAndroid Build Coastguard Worker 
1614*35238bceSAndroid Build Coastguard Worker     if (test == READ_ATTRIBUTE)
1615*35238bceSAndroid Build Coastguard Worker     {
1616*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 a_emitCount;\n";
1617*35238bceSAndroid Build Coastguard Worker         buf << "out highp vec4 v_geom_emitCount;\n";
1618*35238bceSAndroid Build Coastguard Worker     }
1619*35238bceSAndroid Build Coastguard Worker     else if (test == READ_UNIFORM || test == READ_TEXTURE)
1620*35238bceSAndroid Build Coastguard Worker     {
1621*35238bceSAndroid Build Coastguard Worker         buf << "in highp vec4 a_vertexNdx;\n";
1622*35238bceSAndroid Build Coastguard Worker         buf << "out highp vec4 v_geom_vertexNdx;\n";
1623*35238bceSAndroid Build Coastguard Worker     }
1624*35238bceSAndroid Build Coastguard Worker 
1625*35238bceSAndroid Build Coastguard Worker     buf << "void main (void)\n"
1626*35238bceSAndroid Build Coastguard Worker            "{\n"
1627*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_position;\n";
1628*35238bceSAndroid Build Coastguard Worker 
1629*35238bceSAndroid Build Coastguard Worker     if (test == READ_ATTRIBUTE)
1630*35238bceSAndroid Build Coastguard Worker         buf << "    v_geom_emitCount = a_emitCount;\n";
1631*35238bceSAndroid Build Coastguard Worker     else if (test == READ_UNIFORM || test == READ_TEXTURE)
1632*35238bceSAndroid Build Coastguard Worker         buf << "    v_geom_vertexNdx = a_vertexNdx;\n";
1633*35238bceSAndroid Build Coastguard Worker 
1634*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1635*35238bceSAndroid Build Coastguard Worker 
1636*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1637*35238bceSAndroid Build Coastguard Worker }
1638*35238bceSAndroid Build Coastguard Worker 
1639*35238bceSAndroid Build Coastguard Worker class InvocationCountShader : public sglr::ShaderProgram
1640*35238bceSAndroid Build Coastguard Worker {
1641*35238bceSAndroid Build Coastguard Worker public:
1642*35238bceSAndroid Build Coastguard Worker     enum OutputCase
1643*35238bceSAndroid Build Coastguard Worker     {
1644*35238bceSAndroid Build Coastguard Worker         CASE_FIXED_OUTPUT_COUNTS = 0,
1645*35238bceSAndroid Build Coastguard Worker         CASE_DIFFERENT_OUTPUT_COUNTS,
1646*35238bceSAndroid Build Coastguard Worker 
1647*35238bceSAndroid Build Coastguard Worker         CASE_LAST
1648*35238bceSAndroid Build Coastguard Worker     };
1649*35238bceSAndroid Build Coastguard Worker 
1650*35238bceSAndroid Build Coastguard Worker     InvocationCountShader(const glu::ContextType &contextType, int numInvocations, OutputCase testCase);
1651*35238bceSAndroid Build Coastguard Worker 
1652*35238bceSAndroid Build Coastguard Worker private:
1653*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
1654*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1655*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
1656*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
1657*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
1658*35238bceSAndroid Build Coastguard Worker 
1659*35238bceSAndroid Build Coastguard Worker     static std::string genGeometrySource(const glu::ContextType &contextType, int numInvocations, OutputCase testCase);
1660*35238bceSAndroid Build Coastguard Worker     static size_t getNumVertices(int numInvocations, OutputCase testCase);
1661*35238bceSAndroid Build Coastguard Worker 
1662*35238bceSAndroid Build Coastguard Worker     const int m_numInvocations;
1663*35238bceSAndroid Build Coastguard Worker     const OutputCase m_testCase;
1664*35238bceSAndroid Build Coastguard Worker };
1665*35238bceSAndroid Build Coastguard Worker 
InvocationCountShader(const glu::ContextType & contextType,int numInvocations,OutputCase testCase)1666*35238bceSAndroid Build Coastguard Worker InvocationCountShader::InvocationCountShader(const glu::ContextType &contextType, int numInvocations,
1667*35238bceSAndroid Build Coastguard Worker                                              OutputCase testCase)
1668*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
1669*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
1670*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
1671*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToGeometryVarying(rr::GENERICVECTYPE_FLOAT)
1672*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
1673*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
1674*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(specializeShader(s_commonShaderSourceVertex, contextType))
1675*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(specializeShader(s_commonShaderSourceFragment, contextType))
1676*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(
1677*35238bceSAndroid Build Coastguard Worker                                  rr::GEOMETRYSHADERINPUTTYPE_POINTS, rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP,
1678*35238bceSAndroid Build Coastguard Worker                                  getNumVertices(numInvocations, testCase), numInvocations)
1679*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, numInvocations, testCase)))
1680*35238bceSAndroid Build Coastguard Worker     , m_numInvocations(numInvocations)
1681*35238bceSAndroid Build Coastguard Worker     , m_testCase(testCase)
1682*35238bceSAndroid Build Coastguard Worker {
1683*35238bceSAndroid Build Coastguard Worker }
1684*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const1685*35238bceSAndroid Build Coastguard Worker void InvocationCountShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
1686*35238bceSAndroid Build Coastguard Worker                                           const int numPackets) const
1687*35238bceSAndroid Build Coastguard Worker {
1688*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
1689*35238bceSAndroid Build Coastguard Worker     {
1690*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
1691*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1692*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
1693*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1694*35238bceSAndroid Build Coastguard Worker     }
1695*35238bceSAndroid Build Coastguard Worker }
1696*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const1697*35238bceSAndroid Build Coastguard Worker void InvocationCountShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1698*35238bceSAndroid Build Coastguard Worker                                            const rr::FragmentShadingContext &context) const
1699*35238bceSAndroid Build Coastguard Worker {
1700*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1701*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1702*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
1703*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx));
1704*35238bceSAndroid Build Coastguard Worker }
1705*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const1706*35238bceSAndroid Build Coastguard Worker void InvocationCountShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
1707*35238bceSAndroid Build Coastguard Worker                                             const rr::PrimitivePacket *packets, const int numPackets,
1708*35238bceSAndroid Build Coastguard Worker                                             int invocationID) const
1709*35238bceSAndroid Build Coastguard Worker {
1710*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
1711*35238bceSAndroid Build Coastguard Worker 
1712*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1713*35238bceSAndroid Build Coastguard Worker     {
1714*35238bceSAndroid Build Coastguard Worker         const float l_angle  = float(invocationID) / float(m_numInvocations) * 5.5f;
1715*35238bceSAndroid Build Coastguard Worker         const float l_radius = 0.6f;
1716*35238bceSAndroid Build Coastguard Worker 
1717*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[packetNdx].vertices[0];
1718*35238bceSAndroid Build Coastguard Worker 
1719*35238bceSAndroid Build Coastguard Worker         if (m_testCase == CASE_FIXED_OUTPUT_COUNTS)
1720*35238bceSAndroid Build Coastguard Worker         {
1721*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 position0 =
1722*35238bceSAndroid Build Coastguard Worker                 vertex->position +
1723*35238bceSAndroid Build Coastguard Worker                 tcu::Vec4(deFloatCos(l_angle) * (l_radius - 0.1f), deFloatSin(l_angle) * (l_radius - 0.1f), 0.0f, 0.0f);
1724*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 position1 = vertex->position + tcu::Vec4(deFloatCos(l_angle + 0.1f) * l_radius,
1725*35238bceSAndroid Build Coastguard Worker                                                                      deFloatSin(l_angle + 0.1f) * l_radius, 0.0f, 0.0f);
1726*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 position2 = vertex->position + tcu::Vec4(deFloatCos(l_angle - 0.1f) * l_radius,
1727*35238bceSAndroid Build Coastguard Worker                                                                      deFloatSin(l_angle - 0.1f) * l_radius, 0.0f, 0.0f);
1728*35238bceSAndroid Build Coastguard Worker 
1729*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 tipColor;
1730*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 baseColor;
1731*35238bceSAndroid Build Coastguard Worker 
1732*35238bceSAndroid Build Coastguard Worker             tipColor  = tcu::Vec4(1.0, 1.0, 0.0, 1.0) * packets[packetNdx].vertices[0]->outputs[0].get<float>();
1733*35238bceSAndroid Build Coastguard Worker             baseColor = tcu::Vec4(1.0, 0.0, 0.0, 1.0) * packets[packetNdx].vertices[0]->outputs[0].get<float>();
1734*35238bceSAndroid Build Coastguard Worker 
1735*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(position0, 0.0f, &tipColor, packets[packetNdx].primitiveIDIn);
1736*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(position1, 0.0f, &baseColor, packets[packetNdx].primitiveIDIn);
1737*35238bceSAndroid Build Coastguard Worker             output.EmitVertex(position2, 0.0f, &baseColor, packets[packetNdx].primitiveIDIn);
1738*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
1739*35238bceSAndroid Build Coastguard Worker         }
1740*35238bceSAndroid Build Coastguard Worker         else if (m_testCase == CASE_DIFFERENT_OUTPUT_COUNTS)
1741*35238bceSAndroid Build Coastguard Worker         {
1742*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 color =
1743*35238bceSAndroid Build Coastguard Worker                 tcu::Vec4(float(invocationID % 2), (((invocationID / 2) % 2) == 0) ? (1.0f) : (0.0f), 1.0f, 1.0f);
1744*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 basePosition = vertex->position + tcu::Vec4(deFloatCos(l_angle) * l_radius,
1745*35238bceSAndroid Build Coastguard Worker                                                                         deFloatSin(l_angle) * l_radius, 0.0f, 0.0f);
1746*35238bceSAndroid Build Coastguard Worker             const int numNgonVtx         = invocationID + 3;
1747*35238bceSAndroid Build Coastguard Worker 
1748*35238bceSAndroid Build Coastguard Worker             rr::GenericVec4 outColor;
1749*35238bceSAndroid Build Coastguard Worker             outColor = color;
1750*35238bceSAndroid Build Coastguard Worker 
1751*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx + 1 < numNgonVtx; ndx += 2)
1752*35238bceSAndroid Build Coastguard Worker             {
1753*35238bceSAndroid Build Coastguard Worker                 const float subAngle = (float(ndx) + 1.0f) / float(numNgonVtx) * 3.141f;
1754*35238bceSAndroid Build Coastguard Worker 
1755*35238bceSAndroid Build Coastguard Worker                 output.EmitVertex(basePosition +
1756*35238bceSAndroid Build Coastguard Worker                                       tcu::Vec4(deFloatCos(subAngle) * 0.1f, deFloatSin(subAngle) * 0.1f, 0.0f, 0.0f),
1757*35238bceSAndroid Build Coastguard Worker                                   0.0f, &outColor, packets[packetNdx].primitiveIDIn);
1758*35238bceSAndroid Build Coastguard Worker                 output.EmitVertex(basePosition +
1759*35238bceSAndroid Build Coastguard Worker                                       tcu::Vec4(deFloatCos(subAngle) * 0.1f, deFloatSin(subAngle) * -0.1f, 0.0f, 0.0f),
1760*35238bceSAndroid Build Coastguard Worker                                   0.0f, &outColor, packets[packetNdx].primitiveIDIn);
1761*35238bceSAndroid Build Coastguard Worker             }
1762*35238bceSAndroid Build Coastguard Worker 
1763*35238bceSAndroid Build Coastguard Worker             if ((numNgonVtx % 2) == 1)
1764*35238bceSAndroid Build Coastguard Worker                 output.EmitVertex(basePosition + tcu::Vec4(-0.1f, 0.0f, 0.0f, 0.0f), 0.0f, &outColor,
1765*35238bceSAndroid Build Coastguard Worker                                   packets[packetNdx].primitiveIDIn);
1766*35238bceSAndroid Build Coastguard Worker 
1767*35238bceSAndroid Build Coastguard Worker             output.EndPrimitive();
1768*35238bceSAndroid Build Coastguard Worker         }
1769*35238bceSAndroid Build Coastguard Worker     }
1770*35238bceSAndroid Build Coastguard Worker }
1771*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,int numInvocations,OutputCase testCase)1772*35238bceSAndroid Build Coastguard Worker std::string InvocationCountShader::genGeometrySource(const glu::ContextType &contextType, int numInvocations,
1773*35238bceSAndroid Build Coastguard Worker                                                      OutputCase testCase)
1774*35238bceSAndroid Build Coastguard Worker {
1775*35238bceSAndroid Build Coastguard Worker     const int maxVertices = (int)getNumVertices(numInvocations, testCase);
1776*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1777*35238bceSAndroid Build Coastguard Worker 
1778*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1779*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXT_GEOMETRY_SHADER}"
1780*35238bceSAndroid Build Coastguard Worker            "layout(points, invocations = "
1781*35238bceSAndroid Build Coastguard Worker         << numInvocations
1782*35238bceSAndroid Build Coastguard Worker         << ") in;\n"
1783*35238bceSAndroid Build Coastguard Worker            "layout(triangle_strip, max_vertices = "
1784*35238bceSAndroid Build Coastguard Worker         << maxVertices
1785*35238bceSAndroid Build Coastguard Worker         << ") out;\n"
1786*35238bceSAndroid Build Coastguard Worker            "\n"
1787*35238bceSAndroid Build Coastguard Worker            "in highp vec4 v_geom_FragColor[];\n"
1788*35238bceSAndroid Build Coastguard Worker            "out highp vec4 v_frag_FragColor;\n"
1789*35238bceSAndroid Build Coastguard Worker            "\n"
1790*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1791*35238bceSAndroid Build Coastguard Worker            "{\n"
1792*35238bceSAndroid Build Coastguard Worker            "    highp float l_angle = float(gl_InvocationID) / float("
1793*35238bceSAndroid Build Coastguard Worker         << numInvocations
1794*35238bceSAndroid Build Coastguard Worker         << ") * 5.5;\n"
1795*35238bceSAndroid Build Coastguard Worker            "    highp float l_radius = 0.6;\n"
1796*35238bceSAndroid Build Coastguard Worker            "\n";
1797*35238bceSAndroid Build Coastguard Worker 
1798*35238bceSAndroid Build Coastguard Worker     if (testCase == CASE_FIXED_OUTPUT_COUNTS)
1799*35238bceSAndroid Build Coastguard Worker     {
1800*35238bceSAndroid Build Coastguard Worker         buf << "    v_frag_FragColor = vec4(1.0, 1.0, 0.0, 1.0) * v_geom_FragColor[0];\n"
1801*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(cos(l_angle) * (l_radius - 0.1), sin(l_angle) * "
1802*35238bceSAndroid Build Coastguard Worker                "(l_radius - 0.1), 0.0, 0.0);\n"
1803*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1804*35238bceSAndroid Build Coastguard Worker                "\n"
1805*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * v_geom_FragColor[0];\n"
1806*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(cos(l_angle+0.1) * l_radius, sin(l_angle+0.1) * "
1807*35238bceSAndroid Build Coastguard Worker                "l_radius, 0.0, 0.0);\n"
1808*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
1809*35238bceSAndroid Build Coastguard Worker                "\n"
1810*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * v_geom_FragColor[0];\n"
1811*35238bceSAndroid Build Coastguard Worker                "    gl_Position = gl_in[0].gl_Position + vec4(cos(l_angle-0.1) * l_radius, sin(l_angle-0.1) * "
1812*35238bceSAndroid Build Coastguard Worker                "l_radius, 0.0, 0.0);\n"
1813*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
1814*35238bceSAndroid Build Coastguard Worker     }
1815*35238bceSAndroid Build Coastguard Worker     else if (testCase == CASE_DIFFERENT_OUTPUT_COUNTS)
1816*35238bceSAndroid Build Coastguard Worker     {
1817*35238bceSAndroid Build Coastguard Worker         buf << "    highp vec4 l_color = vec4(float(gl_InvocationID % 2), (((gl_InvocationID / 2) % 2) == 0) ? (1.0) : "
1818*35238bceSAndroid Build Coastguard Worker                "(0.0), 1.0, 1.0);\n"
1819*35238bceSAndroid Build Coastguard Worker                "    highp vec4 basePosition = gl_in[0].gl_Position + vec4(cos(l_angle) * l_radius, sin(l_angle) * "
1820*35238bceSAndroid Build Coastguard Worker                "l_radius, 0.0, 0.0);\n"
1821*35238bceSAndroid Build Coastguard Worker                "    mediump int numNgonVtx = gl_InvocationID + 3;\n"
1822*35238bceSAndroid Build Coastguard Worker                "\n"
1823*35238bceSAndroid Build Coastguard Worker                "    for (int ndx = 0; ndx + 1 < numNgonVtx; ndx += 2)\n"
1824*35238bceSAndroid Build Coastguard Worker                "    {\n"
1825*35238bceSAndroid Build Coastguard Worker                "        highp float sub_angle = (float(ndx) + 1.0) / float(numNgonVtx) * 3.141;\n"
1826*35238bceSAndroid Build Coastguard Worker                "\n"
1827*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = l_color;\n"
1828*35238bceSAndroid Build Coastguard Worker                "        gl_Position = basePosition + vec4(cos(sub_angle) * 0.1, sin(sub_angle) * 0.1, 0.0, 0.0);\n"
1829*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n"
1830*35238bceSAndroid Build Coastguard Worker                "\n"
1831*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = l_color;\n"
1832*35238bceSAndroid Build Coastguard Worker                "        gl_Position = basePosition + vec4(cos(sub_angle) * 0.1, sin(sub_angle) * -0.1, 0.0, 0.0);\n"
1833*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n"
1834*35238bceSAndroid Build Coastguard Worker                "    }\n"
1835*35238bceSAndroid Build Coastguard Worker                "    if ((numNgonVtx % 2) == 1)\n"
1836*35238bceSAndroid Build Coastguard Worker                "    {\n"
1837*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = l_color;\n"
1838*35238bceSAndroid Build Coastguard Worker                "        gl_Position = basePosition + vec4(-0.1, 0.0, 0.0, 0.0);\n"
1839*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n"
1840*35238bceSAndroid Build Coastguard Worker                "    }\n";
1841*35238bceSAndroid Build Coastguard Worker     }
1842*35238bceSAndroid Build Coastguard Worker     else
1843*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1844*35238bceSAndroid Build Coastguard Worker 
1845*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1846*35238bceSAndroid Build Coastguard Worker 
1847*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1848*35238bceSAndroid Build Coastguard Worker }
1849*35238bceSAndroid Build Coastguard Worker 
getNumVertices(int numInvocations,OutputCase testCase)1850*35238bceSAndroid Build Coastguard Worker size_t InvocationCountShader::getNumVertices(int numInvocations, OutputCase testCase)
1851*35238bceSAndroid Build Coastguard Worker {
1852*35238bceSAndroid Build Coastguard Worker     switch (testCase)
1853*35238bceSAndroid Build Coastguard Worker     {
1854*35238bceSAndroid Build Coastguard Worker     case CASE_FIXED_OUTPUT_COUNTS:
1855*35238bceSAndroid Build Coastguard Worker         return 3;
1856*35238bceSAndroid Build Coastguard Worker     case CASE_DIFFERENT_OUTPUT_COUNTS:
1857*35238bceSAndroid Build Coastguard Worker         return (size_t)(2 + numInvocations);
1858*35238bceSAndroid Build Coastguard Worker     default:
1859*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1860*35238bceSAndroid Build Coastguard Worker         return 0;
1861*35238bceSAndroid Build Coastguard Worker     }
1862*35238bceSAndroid Build Coastguard Worker }
1863*35238bceSAndroid Build Coastguard Worker 
1864*35238bceSAndroid Build Coastguard Worker class InstancedExpansionShader : public sglr::ShaderProgram
1865*35238bceSAndroid Build Coastguard Worker {
1866*35238bceSAndroid Build Coastguard Worker public:
1867*35238bceSAndroid Build Coastguard Worker     InstancedExpansionShader(const glu::ContextType &contextType, int numInvocations);
1868*35238bceSAndroid Build Coastguard Worker 
1869*35238bceSAndroid Build Coastguard Worker private:
1870*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
1871*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1872*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
1873*35238bceSAndroid Build Coastguard Worker     void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets,
1874*35238bceSAndroid Build Coastguard Worker                          const int numPackets, int invocationID) const;
1875*35238bceSAndroid Build Coastguard Worker 
1876*35238bceSAndroid Build Coastguard Worker     static std::string genVertexSource(const glu::ContextType &contextType);
1877*35238bceSAndroid Build Coastguard Worker     static std::string genFragmentSource(const glu::ContextType &contextType);
1878*35238bceSAndroid Build Coastguard Worker     static std::string genGeometrySource(const glu::ContextType &contextType, int numInvocations);
1879*35238bceSAndroid Build Coastguard Worker 
1880*35238bceSAndroid Build Coastguard Worker     const int m_numInvocations;
1881*35238bceSAndroid Build Coastguard Worker };
1882*35238bceSAndroid Build Coastguard Worker 
InstancedExpansionShader(const glu::ContextType & contextType,int numInvocations)1883*35238bceSAndroid Build Coastguard Worker InstancedExpansionShader::InstancedExpansionShader(const glu::ContextType &contextType, int numInvocations)
1884*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
1885*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
1886*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_offset", rr::GENERICVECTYPE_FLOAT)
1887*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
1888*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource(genVertexSource(contextType))
1889*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource(genFragmentSource(contextType))
1890*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometryShaderDeclaration(rr::GEOMETRYSHADERINPUTTYPE_POINTS,
1891*35238bceSAndroid Build Coastguard Worker                                                                    rr::GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP, 4,
1892*35238bceSAndroid Build Coastguard Worker                                                                    numInvocations)
1893*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::GeometrySource(genGeometrySource(contextType, numInvocations)))
1894*35238bceSAndroid Build Coastguard Worker     , m_numInvocations(numInvocations)
1895*35238bceSAndroid Build Coastguard Worker {
1896*35238bceSAndroid Build Coastguard Worker }
1897*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const1898*35238bceSAndroid Build Coastguard Worker void InstancedExpansionShader::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
1899*35238bceSAndroid Build Coastguard Worker                                              const int numPackets) const
1900*35238bceSAndroid Build Coastguard Worker {
1901*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
1902*35238bceSAndroid Build Coastguard Worker     {
1903*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
1904*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx) +
1905*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
1906*35238bceSAndroid Build Coastguard Worker     }
1907*35238bceSAndroid Build Coastguard Worker }
1908*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const1909*35238bceSAndroid Build Coastguard Worker void InstancedExpansionShader::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1910*35238bceSAndroid Build Coastguard Worker                                               const rr::FragmentShadingContext &context) const
1911*35238bceSAndroid Build Coastguard Worker {
1912*35238bceSAndroid Build Coastguard Worker     DE_UNREF(packets);
1913*35238bceSAndroid Build Coastguard Worker 
1914*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1915*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1916*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1917*35238bceSAndroid Build Coastguard Worker }
1918*35238bceSAndroid Build Coastguard Worker 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const1919*35238bceSAndroid Build Coastguard Worker void InstancedExpansionShader::shadePrimitives(rr::GeometryEmitter &output, int verticesIn,
1920*35238bceSAndroid Build Coastguard Worker                                                const rr::PrimitivePacket *packets, const int numPackets,
1921*35238bceSAndroid Build Coastguard Worker                                                int invocationID) const
1922*35238bceSAndroid Build Coastguard Worker {
1923*35238bceSAndroid Build Coastguard Worker     DE_UNREF(verticesIn);
1924*35238bceSAndroid Build Coastguard Worker 
1925*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1926*35238bceSAndroid Build Coastguard Worker     {
1927*35238bceSAndroid Build Coastguard Worker         const rr::VertexPacket *vertex = packets[packetNdx].vertices[0];
1928*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 basePosition   = vertex->position;
1929*35238bceSAndroid Build Coastguard Worker         const float phase              = float(invocationID) / float(m_numInvocations) * 6.3f;
1930*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 centerPosition =
1931*35238bceSAndroid Build Coastguard Worker             basePosition + tcu::Vec4(deFloatCos(phase), deFloatSin(phase), 0.0f, 0.0f) * 0.1f;
1932*35238bceSAndroid Build Coastguard Worker 
1933*35238bceSAndroid Build Coastguard Worker         output.EmitVertex(centerPosition + tcu::Vec4(0.0f, -0.1f, 0.0f, 0.0f), 0.0f, DE_NULL,
1934*35238bceSAndroid Build Coastguard Worker                           packets[packetNdx].primitiveIDIn);
1935*35238bceSAndroid Build Coastguard Worker         output.EmitVertex(centerPosition + tcu::Vec4(-0.05f, 0.0f, 0.0f, 0.0f), 0.0f, DE_NULL,
1936*35238bceSAndroid Build Coastguard Worker                           packets[packetNdx].primitiveIDIn);
1937*35238bceSAndroid Build Coastguard Worker         output.EmitVertex(centerPosition + tcu::Vec4(0.05f, 0.0f, 0.0f, 0.0f), 0.0f, DE_NULL,
1938*35238bceSAndroid Build Coastguard Worker                           packets[packetNdx].primitiveIDIn);
1939*35238bceSAndroid Build Coastguard Worker         output.EndPrimitive();
1940*35238bceSAndroid Build Coastguard Worker     }
1941*35238bceSAndroid Build Coastguard Worker }
1942*35238bceSAndroid Build Coastguard Worker 
genVertexSource(const glu::ContextType & contextType)1943*35238bceSAndroid Build Coastguard Worker std::string InstancedExpansionShader::genVertexSource(const glu::ContextType &contextType)
1944*35238bceSAndroid Build Coastguard Worker {
1945*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1946*35238bceSAndroid Build Coastguard Worker 
1947*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1948*35238bceSAndroid Build Coastguard Worker            "in highp vec4 a_position;\n"
1949*35238bceSAndroid Build Coastguard Worker            "in highp vec4 a_offset;\n"
1950*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1951*35238bceSAndroid Build Coastguard Worker            "{\n"
1952*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_position + a_offset;\n"
1953*35238bceSAndroid Build Coastguard Worker            "}\n";
1954*35238bceSAndroid Build Coastguard Worker 
1955*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1956*35238bceSAndroid Build Coastguard Worker }
1957*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(const glu::ContextType & contextType)1958*35238bceSAndroid Build Coastguard Worker std::string InstancedExpansionShader::genFragmentSource(const glu::ContextType &contextType)
1959*35238bceSAndroid Build Coastguard Worker {
1960*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1961*35238bceSAndroid Build Coastguard Worker 
1962*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1963*35238bceSAndroid Build Coastguard Worker            "layout(location = 0) out mediump vec4 fragColor;\n"
1964*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1965*35238bceSAndroid Build Coastguard Worker            "{\n"
1966*35238bceSAndroid Build Coastguard Worker            "    fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1967*35238bceSAndroid Build Coastguard Worker            "}\n";
1968*35238bceSAndroid Build Coastguard Worker 
1969*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
1970*35238bceSAndroid Build Coastguard Worker }
1971*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType,int numInvocations)1972*35238bceSAndroid Build Coastguard Worker std::string InstancedExpansionShader::genGeometrySource(const glu::ContextType &contextType, int numInvocations)
1973*35238bceSAndroid Build Coastguard Worker {
1974*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1975*35238bceSAndroid Build Coastguard Worker 
1976*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
1977*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXT_GEOMETRY_SHADER}"
1978*35238bceSAndroid Build Coastguard Worker            "layout(points,invocations="
1979*35238bceSAndroid Build Coastguard Worker         << numInvocations
1980*35238bceSAndroid Build Coastguard Worker         << ") in;\n"
1981*35238bceSAndroid Build Coastguard Worker            "layout(triangle_strip, max_vertices = 3) out;\n"
1982*35238bceSAndroid Build Coastguard Worker            "\n"
1983*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
1984*35238bceSAndroid Build Coastguard Worker            "{\n"
1985*35238bceSAndroid Build Coastguard Worker            "    highp vec4 basePosition = gl_in[0].gl_Position;\n"
1986*35238bceSAndroid Build Coastguard Worker            "    highp float phase = float(gl_InvocationID) / float("
1987*35238bceSAndroid Build Coastguard Worker         << numInvocations
1988*35238bceSAndroid Build Coastguard Worker         << ") * 6.3;\n"
1989*35238bceSAndroid Build Coastguard Worker            "    highp vec4 centerPosition = basePosition + 0.1 * vec4(cos(phase), sin(phase), 0.0, 0.0);\n"
1990*35238bceSAndroid Build Coastguard Worker            "\n"
1991*35238bceSAndroid Build Coastguard Worker            "    gl_Position = centerPosition + vec4( 0.00, -0.1, 0.0, 0.0);\n"
1992*35238bceSAndroid Build Coastguard Worker            "    EmitVertex();\n"
1993*35238bceSAndroid Build Coastguard Worker            "    gl_Position = centerPosition + vec4(-0.05,  0.0, 0.0, 0.0);\n"
1994*35238bceSAndroid Build Coastguard Worker            "    EmitVertex();\n"
1995*35238bceSAndroid Build Coastguard Worker            "    gl_Position = centerPosition + vec4( 0.05,  0.0, 0.0, 0.0);\n"
1996*35238bceSAndroid Build Coastguard Worker            "    EmitVertex();\n"
1997*35238bceSAndroid Build Coastguard Worker            "}\n";
1998*35238bceSAndroid Build Coastguard Worker 
1999*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
2000*35238bceSAndroid Build Coastguard Worker }
2001*35238bceSAndroid Build Coastguard Worker 
2002*35238bceSAndroid Build Coastguard Worker class GeometryShaderRenderTest : public TestCase
2003*35238bceSAndroid Build Coastguard Worker {
2004*35238bceSAndroid Build Coastguard Worker public:
2005*35238bceSAndroid Build Coastguard Worker     enum Flag
2006*35238bceSAndroid Build Coastguard Worker     {
2007*35238bceSAndroid Build Coastguard Worker         FLAG_DRAW_INSTANCED    = 1,
2008*35238bceSAndroid Build Coastguard Worker         FLAG_USE_INDICES       = 2,
2009*35238bceSAndroid Build Coastguard Worker         FLAG_USE_RESTART_INDEX = 4,
2010*35238bceSAndroid Build Coastguard Worker     };
2011*35238bceSAndroid Build Coastguard Worker 
2012*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest(Context &context, const char *name, const char *desc, GLenum inputPrimitives,
2013*35238bceSAndroid Build Coastguard Worker                              GLenum outputPrimitives, const char *dataAttributeName, int flags = 0);
2014*35238bceSAndroid Build Coastguard Worker     virtual ~GeometryShaderRenderTest(void);
2015*35238bceSAndroid Build Coastguard Worker 
2016*35238bceSAndroid Build Coastguard Worker     void init(void);
2017*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2018*35238bceSAndroid Build Coastguard Worker 
2019*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2020*35238bceSAndroid Build Coastguard Worker     bool compare(void);
2021*35238bceSAndroid Build Coastguard Worker 
2022*35238bceSAndroid Build Coastguard Worker     virtual sglr::ShaderProgram &getProgram(void) = 0;
2023*35238bceSAndroid Build Coastguard Worker 
2024*35238bceSAndroid Build Coastguard Worker protected:
2025*35238bceSAndroid Build Coastguard Worker     virtual void genVertexAttribData(void);
2026*35238bceSAndroid Build Coastguard Worker     void renderWithContext(sglr::Context &ctx, sglr::ShaderProgram &program, tcu::Surface &dstSurface);
2027*35238bceSAndroid Build Coastguard Worker     virtual void preRender(sglr::Context &ctx, GLuint programID);
2028*35238bceSAndroid Build Coastguard Worker     virtual void postRender(sglr::Context &ctx, GLuint programID);
2029*35238bceSAndroid Build Coastguard Worker 
2030*35238bceSAndroid Build Coastguard Worker     int m_numDrawVertices;
2031*35238bceSAndroid Build Coastguard Worker     int m_numDrawInstances;
2032*35238bceSAndroid Build Coastguard Worker     int m_vertexAttrDivisor;
2033*35238bceSAndroid Build Coastguard Worker 
2034*35238bceSAndroid Build Coastguard Worker     const GLenum m_inputPrimitives;
2035*35238bceSAndroid Build Coastguard Worker     const GLenum m_outputPrimitives;
2036*35238bceSAndroid Build Coastguard Worker     const char *const m_dataAttributeName;
2037*35238bceSAndroid Build Coastguard Worker     const int m_flags;
2038*35238bceSAndroid Build Coastguard Worker 
2039*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 m_viewportSize;
2040*35238bceSAndroid Build Coastguard Worker     int m_interationCount;
2041*35238bceSAndroid Build Coastguard Worker 
2042*35238bceSAndroid Build Coastguard Worker     tcu::Surface *m_glResult;
2043*35238bceSAndroid Build Coastguard Worker     tcu::Surface *m_refResult;
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker     sglr::ReferenceContextBuffers *m_refBuffers;
2046*35238bceSAndroid Build Coastguard Worker     sglr::ReferenceContext *m_refContext;
2047*35238bceSAndroid Build Coastguard Worker     sglr::Context *m_glContext;
2048*35238bceSAndroid Build Coastguard Worker 
2049*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> m_vertexPosData;
2050*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> m_vertexAttrData;
2051*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> m_indices;
2052*35238bceSAndroid Build Coastguard Worker };
2053*35238bceSAndroid Build Coastguard Worker 
GeometryShaderRenderTest(Context & context,const char * name,const char * desc,GLenum inputPrimitives,GLenum outputPrimitives,const char * dataAttributeName,int flags)2054*35238bceSAndroid Build Coastguard Worker GeometryShaderRenderTest::GeometryShaderRenderTest(Context &context, const char *name, const char *desc,
2055*35238bceSAndroid Build Coastguard Worker                                                    GLenum inputPrimitives, GLenum outputPrimitives,
2056*35238bceSAndroid Build Coastguard Worker                                                    const char *dataAttributeName, int flags)
2057*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2058*35238bceSAndroid Build Coastguard Worker     , m_numDrawVertices(0)
2059*35238bceSAndroid Build Coastguard Worker     , m_numDrawInstances(0)
2060*35238bceSAndroid Build Coastguard Worker     , m_vertexAttrDivisor(0)
2061*35238bceSAndroid Build Coastguard Worker     , m_inputPrimitives(inputPrimitives)
2062*35238bceSAndroid Build Coastguard Worker     , m_outputPrimitives(outputPrimitives)
2063*35238bceSAndroid Build Coastguard Worker     , m_dataAttributeName(dataAttributeName)
2064*35238bceSAndroid Build Coastguard Worker     , m_flags(flags)
2065*35238bceSAndroid Build Coastguard Worker     , m_viewportSize(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE)
2066*35238bceSAndroid Build Coastguard Worker     , m_interationCount(0)
2067*35238bceSAndroid Build Coastguard Worker     , m_glResult(DE_NULL)
2068*35238bceSAndroid Build Coastguard Worker     , m_refResult(DE_NULL)
2069*35238bceSAndroid Build Coastguard Worker     , m_refBuffers(DE_NULL)
2070*35238bceSAndroid Build Coastguard Worker     , m_refContext(DE_NULL)
2071*35238bceSAndroid Build Coastguard Worker     , m_glContext(DE_NULL)
2072*35238bceSAndroid Build Coastguard Worker {
2073*35238bceSAndroid Build Coastguard Worker     // Disallow instanced drawElements
2074*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(((m_flags & FLAG_DRAW_INSTANCED) == 0) || ((m_flags & FLAG_USE_INDICES) == 0));
2075*35238bceSAndroid Build Coastguard Worker     // Disallow restart without indices
2076*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!(((m_flags & FLAG_USE_RESTART_INDEX) != 0) && ((m_flags & FLAG_USE_INDICES) == 0)));
2077*35238bceSAndroid Build Coastguard Worker }
2078*35238bceSAndroid Build Coastguard Worker 
~GeometryShaderRenderTest(void)2079*35238bceSAndroid Build Coastguard Worker GeometryShaderRenderTest::~GeometryShaderRenderTest(void)
2080*35238bceSAndroid Build Coastguard Worker {
2081*35238bceSAndroid Build Coastguard Worker     deinit();
2082*35238bceSAndroid Build Coastguard Worker }
2083*35238bceSAndroid Build Coastguard Worker 
init(void)2084*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::init(void)
2085*35238bceSAndroid Build Coastguard Worker {
2086*35238bceSAndroid Build Coastguard Worker     // requirements
2087*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
2088*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
2089*35238bceSAndroid Build Coastguard Worker 
2090*35238bceSAndroid Build Coastguard Worker     // gen resources
2091*35238bceSAndroid Build Coastguard Worker     {
2092*35238bceSAndroid Build Coastguard Worker         sglr::ReferenceContextLimits limits;
2093*35238bceSAndroid Build Coastguard Worker 
2094*35238bceSAndroid Build Coastguard Worker         m_glResult  = new tcu::Surface(m_viewportSize.x(), m_viewportSize.y());
2095*35238bceSAndroid Build Coastguard Worker         m_refResult = new tcu::Surface(m_viewportSize.x(), m_viewportSize.y());
2096*35238bceSAndroid Build Coastguard Worker 
2097*35238bceSAndroid Build Coastguard Worker         m_refBuffers = new sglr::ReferenceContextBuffers(m_context.getRenderTarget().getPixelFormat(),
2098*35238bceSAndroid Build Coastguard Worker                                                          m_context.getRenderTarget().getDepthBits(), 0,
2099*35238bceSAndroid Build Coastguard Worker                                                          m_viewportSize.x(), m_viewportSize.y());
2100*35238bceSAndroid Build Coastguard Worker         m_refContext = new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(),
2101*35238bceSAndroid Build Coastguard Worker                                                   m_refBuffers->getDepthbuffer(), m_refBuffers->getStencilbuffer());
2102*35238bceSAndroid Build Coastguard Worker         m_glContext  = new sglr::GLContext(m_context.getRenderContext(), m_testCtx.getLog(),
2103*35238bceSAndroid Build Coastguard Worker                                            sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS,
2104*35238bceSAndroid Build Coastguard Worker                                            tcu::IVec4(0, 0, m_viewportSize.x(), m_viewportSize.y()));
2105*35238bceSAndroid Build Coastguard Worker     }
2106*35238bceSAndroid Build Coastguard Worker }
2107*35238bceSAndroid Build Coastguard Worker 
deinit(void)2108*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::deinit(void)
2109*35238bceSAndroid Build Coastguard Worker {
2110*35238bceSAndroid Build Coastguard Worker     delete m_glResult;
2111*35238bceSAndroid Build Coastguard Worker     delete m_refResult;
2112*35238bceSAndroid Build Coastguard Worker 
2113*35238bceSAndroid Build Coastguard Worker     m_glResult  = DE_NULL;
2114*35238bceSAndroid Build Coastguard Worker     m_refResult = DE_NULL;
2115*35238bceSAndroid Build Coastguard Worker 
2116*35238bceSAndroid Build Coastguard Worker     delete m_refContext;
2117*35238bceSAndroid Build Coastguard Worker     delete m_glContext;
2118*35238bceSAndroid Build Coastguard Worker     delete m_refBuffers;
2119*35238bceSAndroid Build Coastguard Worker 
2120*35238bceSAndroid Build Coastguard Worker     m_refBuffers = DE_NULL;
2121*35238bceSAndroid Build Coastguard Worker     m_refContext = DE_NULL;
2122*35238bceSAndroid Build Coastguard Worker     m_glContext  = DE_NULL;
2123*35238bceSAndroid Build Coastguard Worker }
2124*35238bceSAndroid Build Coastguard Worker 
iterate(void)2125*35238bceSAndroid Build Coastguard Worker tcu::TestCase::IterateResult GeometryShaderRenderTest::iterate(void)
2126*35238bceSAndroid Build Coastguard Worker {
2127*35238bceSAndroid Build Coastguard Worker     // init() must be called
2128*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_glContext);
2129*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_refContext);
2130*35238bceSAndroid Build Coastguard Worker 
2131*35238bceSAndroid Build Coastguard Worker     const int iteration = m_interationCount++;
2132*35238bceSAndroid Build Coastguard Worker 
2133*35238bceSAndroid Build Coastguard Worker     if (iteration == 0)
2134*35238bceSAndroid Build Coastguard Worker     {
2135*35238bceSAndroid Build Coastguard Worker         // Check requirements
2136*35238bceSAndroid Build Coastguard Worker         const int width  = m_context.getRenderTarget().getWidth();
2137*35238bceSAndroid Build Coastguard Worker         const int height = m_context.getRenderTarget().getHeight();
2138*35238bceSAndroid Build Coastguard Worker 
2139*35238bceSAndroid Build Coastguard Worker         if (width < m_viewportSize.x() || height < m_viewportSize.y())
2140*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(std::string("Render target size must be at least ") +
2141*35238bceSAndroid Build Coastguard Worker                                          de::toString(m_viewportSize.x()) + "x" + de::toString(m_viewportSize.y()));
2142*35238bceSAndroid Build Coastguard Worker 
2143*35238bceSAndroid Build Coastguard Worker         // Gen data
2144*35238bceSAndroid Build Coastguard Worker         genVertexAttribData();
2145*35238bceSAndroid Build Coastguard Worker 
2146*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
2147*35238bceSAndroid Build Coastguard Worker     }
2148*35238bceSAndroid Build Coastguard Worker     else if (iteration == 1)
2149*35238bceSAndroid Build Coastguard Worker     {
2150*35238bceSAndroid Build Coastguard Worker         // Render
2151*35238bceSAndroid Build Coastguard Worker         sglr::ShaderProgram &program = getProgram();
2152*35238bceSAndroid Build Coastguard Worker 
2153*35238bceSAndroid Build Coastguard Worker         renderWithContext(*m_glContext, program, *m_glResult);
2154*35238bceSAndroid Build Coastguard Worker         renderWithContext(*m_refContext, program, *m_refResult);
2155*35238bceSAndroid Build Coastguard Worker 
2156*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
2157*35238bceSAndroid Build Coastguard Worker     }
2158*35238bceSAndroid Build Coastguard Worker     else
2159*35238bceSAndroid Build Coastguard Worker     {
2160*35238bceSAndroid Build Coastguard Worker         if (compare())
2161*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2162*35238bceSAndroid Build Coastguard Worker         else
2163*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
2164*35238bceSAndroid Build Coastguard Worker 
2165*35238bceSAndroid Build Coastguard Worker         return STOP;
2166*35238bceSAndroid Build Coastguard Worker     }
2167*35238bceSAndroid Build Coastguard Worker }
2168*35238bceSAndroid Build Coastguard Worker 
compare(void)2169*35238bceSAndroid Build Coastguard Worker bool GeometryShaderRenderTest::compare(void)
2170*35238bceSAndroid Build Coastguard Worker {
2171*35238bceSAndroid Build Coastguard Worker     using tcu::TestLog;
2172*35238bceSAndroid Build Coastguard Worker 
2173*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getNumSamples() > 1)
2174*35238bceSAndroid Build Coastguard Worker     {
2175*35238bceSAndroid Build Coastguard Worker         return tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", m_refResult->getAccess(),
2176*35238bceSAndroid Build Coastguard Worker                                  m_glResult->getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT);
2177*35238bceSAndroid Build Coastguard Worker     }
2178*35238bceSAndroid Build Coastguard Worker     else
2179*35238bceSAndroid Build Coastguard Worker     {
2180*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(m_viewportSize.x(), m_viewportSize.y());
2181*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA green(0, 255, 0, 255);
2182*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA red(255, 0, 0, 255);
2183*35238bceSAndroid Build Coastguard Worker         const int colorComponentThreshold = 20;
2184*35238bceSAndroid Build Coastguard Worker         bool testResult                   = true;
2185*35238bceSAndroid Build Coastguard Worker 
2186*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < m_viewportSize.x(); ++x)
2187*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < m_viewportSize.y(); ++y)
2188*35238bceSAndroid Build Coastguard Worker             {
2189*35238bceSAndroid Build Coastguard Worker                 if (x == 0 || y == 0 || x + 1 == m_viewportSize.x() || y + 1 == m_viewportSize.y())
2190*35238bceSAndroid Build Coastguard Worker                 {
2191*35238bceSAndroid Build Coastguard Worker                     // Mark edge pixels as correct since their neighbourhood is undefined
2192*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, green);
2193*35238bceSAndroid Build Coastguard Worker                 }
2194*35238bceSAndroid Build Coastguard Worker                 else
2195*35238bceSAndroid Build Coastguard Worker                 {
2196*35238bceSAndroid Build Coastguard Worker                     const tcu::RGBA refcolor = m_refResult->getPixel(x, y);
2197*35238bceSAndroid Build Coastguard Worker                     bool found               = false;
2198*35238bceSAndroid Build Coastguard Worker 
2199*35238bceSAndroid Build Coastguard Worker                     // Got to find similar pixel near this pixel (3x3 kernel)
2200*35238bceSAndroid Build Coastguard Worker                     for (int dx = -1; dx <= 1; ++dx)
2201*35238bceSAndroid Build Coastguard Worker                         for (int dy = -1; dy <= 1; ++dy)
2202*35238bceSAndroid Build Coastguard Worker                         {
2203*35238bceSAndroid Build Coastguard Worker                             const tcu::RGBA testColor = m_glResult->getPixel(x + dx, y + dy);
2204*35238bceSAndroid Build Coastguard Worker                             const tcu::IVec4 colDiff  = tcu::abs(testColor.toIVec() - refcolor.toIVec());
2205*35238bceSAndroid Build Coastguard Worker 
2206*35238bceSAndroid Build Coastguard Worker                             const int maxColDiff =
2207*35238bceSAndroid Build Coastguard Worker                                 de::max(de::max(colDiff.x(), colDiff.y()), colDiff.z()); // check RGB channels
2208*35238bceSAndroid Build Coastguard Worker 
2209*35238bceSAndroid Build Coastguard Worker                             if (maxColDiff <= colorComponentThreshold)
2210*35238bceSAndroid Build Coastguard Worker                                 found = true;
2211*35238bceSAndroid Build Coastguard Worker                         }
2212*35238bceSAndroid Build Coastguard Worker 
2213*35238bceSAndroid Build Coastguard Worker                     if (!found)
2214*35238bceSAndroid Build Coastguard Worker                         testResult = false;
2215*35238bceSAndroid Build Coastguard Worker 
2216*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, (found) ? (green) : (red));
2217*35238bceSAndroid Build Coastguard Worker                 }
2218*35238bceSAndroid Build Coastguard Worker             }
2219*35238bceSAndroid Build Coastguard Worker 
2220*35238bceSAndroid Build Coastguard Worker         if (testResult)
2221*35238bceSAndroid Build Coastguard Worker         {
2222*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::ImageSet("Compare result", "Result of rendering")
2223*35238bceSAndroid Build Coastguard Worker                                << TestLog::Image("Result", "Result", *m_glResult) << TestLog::EndImageSet;
2224*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Image compare ok." << TestLog::EndMessage;
2225*35238bceSAndroid Build Coastguard Worker         }
2226*35238bceSAndroid Build Coastguard Worker         else
2227*35238bceSAndroid Build Coastguard Worker         {
2228*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::ImageSet("Compare result", "Result of rendering")
2229*35238bceSAndroid Build Coastguard Worker                                << TestLog::Image("Result", "Result", *m_glResult)
2230*35238bceSAndroid Build Coastguard Worker                                << TestLog::Image("Reference", "Reference", *m_refResult)
2231*35238bceSAndroid Build Coastguard Worker                                << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
2232*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Image compare failed." << TestLog::EndMessage;
2233*35238bceSAndroid Build Coastguard Worker         }
2234*35238bceSAndroid Build Coastguard Worker 
2235*35238bceSAndroid Build Coastguard Worker         return testResult;
2236*35238bceSAndroid Build Coastguard Worker     }
2237*35238bceSAndroid Build Coastguard Worker }
2238*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2239*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::genVertexAttribData(void)
2240*35238bceSAndroid Build Coastguard Worker {
2241*35238bceSAndroid Build Coastguard Worker     // Create 1 X 2 grid in triangle strip adjacent - order
2242*35238bceSAndroid Build Coastguard Worker     const float scale = 0.3f;
2243*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 offset(-0.5f, -0.2f, 0.0f, 1.0f);
2244*35238bceSAndroid Build Coastguard Worker 
2245*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(12);
2246*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0]  = tcu::Vec4(0, 0, 0.0f, 0.0f) * scale + offset;
2247*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[1]  = tcu::Vec4(-1, -1, 0.0f, 0.0f) * scale + offset;
2248*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[2]  = tcu::Vec4(0, -1, 0.0f, 0.0f) * scale + offset;
2249*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[3]  = tcu::Vec4(1, 1, 0.0f, 0.0f) * scale + offset;
2250*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[4]  = tcu::Vec4(1, 0, 0.0f, 0.0f) * scale + offset;
2251*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[5]  = tcu::Vec4(0, -2, 0.0f, 0.0f) * scale + offset;
2252*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[6]  = tcu::Vec4(1, -1, 0.0f, 0.0f) * scale + offset;
2253*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[7]  = tcu::Vec4(2, 1, 0.0f, 0.0f) * scale + offset;
2254*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[8]  = tcu::Vec4(2, 0, 0.0f, 0.0f) * scale + offset;
2255*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[9]  = tcu::Vec4(1, -2, 0.0f, 0.0f) * scale + offset;
2256*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[10] = tcu::Vec4(2, -1, 0.0f, 0.0f) * scale + offset;
2257*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[11] = tcu::Vec4(3, 0, 0.0f, 0.0f) * scale + offset;
2258*35238bceSAndroid Build Coastguard Worker 
2259*35238bceSAndroid Build Coastguard Worker     // Red and white
2260*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(12);
2261*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 12; ++i)
2262*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[i] = (i % 2 == 0) ? tcu::Vec4(1, 1, 1, 1) : tcu::Vec4(1, 0, 0, 1);
2263*35238bceSAndroid Build Coastguard Worker 
2264*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 12;
2265*35238bceSAndroid Build Coastguard Worker }
2266*35238bceSAndroid Build Coastguard Worker 
renderWithContext(sglr::Context & ctx,sglr::ShaderProgram & program,tcu::Surface & dstSurface)2267*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::renderWithContext(sglr::Context &ctx, sglr::ShaderProgram &program,
2268*35238bceSAndroid Build Coastguard Worker                                                  tcu::Surface &dstSurface)
2269*35238bceSAndroid Build Coastguard Worker {
2270*35238bceSAndroid Build Coastguard Worker #define CHECK_GL_CTX_ERRORS() glu::checkError(ctx.getError(), DE_NULL, __FILE__, __LINE__)
2271*35238bceSAndroid Build Coastguard Worker 
2272*35238bceSAndroid Build Coastguard Worker     const GLuint programId = ctx.createProgram(&program);
2273*35238bceSAndroid Build Coastguard Worker     const GLint attrPosLoc = ctx.getAttribLocation(programId, "a_position");
2274*35238bceSAndroid Build Coastguard Worker     const GLint attrColLoc = ctx.getAttribLocation(programId, m_dataAttributeName);
2275*35238bceSAndroid Build Coastguard Worker     GLuint vaoId           = 0;
2276*35238bceSAndroid Build Coastguard Worker     GLuint vertexPosBuf    = 0;
2277*35238bceSAndroid Build Coastguard Worker     GLuint vertexAttrBuf   = 0;
2278*35238bceSAndroid Build Coastguard Worker     GLuint elementArrayBuf = 0;
2279*35238bceSAndroid Build Coastguard Worker 
2280*35238bceSAndroid Build Coastguard Worker     ctx.genVertexArrays(1, &vaoId);
2281*35238bceSAndroid Build Coastguard Worker     ctx.bindVertexArray(vaoId);
2282*35238bceSAndroid Build Coastguard Worker 
2283*35238bceSAndroid Build Coastguard Worker     if (attrPosLoc != -1)
2284*35238bceSAndroid Build Coastguard Worker     {
2285*35238bceSAndroid Build Coastguard Worker         ctx.genBuffers(1, &vertexPosBuf);
2286*35238bceSAndroid Build Coastguard Worker         ctx.bindBuffer(GL_ARRAY_BUFFER, vertexPosBuf);
2287*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_ARRAY_BUFFER, m_vertexPosData.size() * sizeof(tcu::Vec4), &m_vertexPosData[0],
2288*35238bceSAndroid Build Coastguard Worker                        GL_STATIC_DRAW);
2289*35238bceSAndroid Build Coastguard Worker         ctx.vertexAttribPointer(attrPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2290*35238bceSAndroid Build Coastguard Worker         ctx.enableVertexAttribArray(attrPosLoc);
2291*35238bceSAndroid Build Coastguard Worker     }
2292*35238bceSAndroid Build Coastguard Worker 
2293*35238bceSAndroid Build Coastguard Worker     if (attrColLoc != -1)
2294*35238bceSAndroid Build Coastguard Worker     {
2295*35238bceSAndroid Build Coastguard Worker         ctx.genBuffers(1, &vertexAttrBuf);
2296*35238bceSAndroid Build Coastguard Worker         ctx.bindBuffer(GL_ARRAY_BUFFER, vertexAttrBuf);
2297*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_ARRAY_BUFFER, m_vertexAttrData.size() * sizeof(tcu::Vec4), &m_vertexAttrData[0],
2298*35238bceSAndroid Build Coastguard Worker                        GL_STATIC_DRAW);
2299*35238bceSAndroid Build Coastguard Worker         ctx.vertexAttribPointer(attrColLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2300*35238bceSAndroid Build Coastguard Worker         ctx.enableVertexAttribArray(attrColLoc);
2301*35238bceSAndroid Build Coastguard Worker 
2302*35238bceSAndroid Build Coastguard Worker         if (m_vertexAttrDivisor)
2303*35238bceSAndroid Build Coastguard Worker             ctx.vertexAttribDivisor(attrColLoc, m_vertexAttrDivisor);
2304*35238bceSAndroid Build Coastguard Worker     }
2305*35238bceSAndroid Build Coastguard Worker 
2306*35238bceSAndroid Build Coastguard Worker     if (m_flags & FLAG_USE_INDICES)
2307*35238bceSAndroid Build Coastguard Worker     {
2308*35238bceSAndroid Build Coastguard Worker         ctx.genBuffers(1, &elementArrayBuf);
2309*35238bceSAndroid Build Coastguard Worker         ctx.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuf);
2310*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(uint16_t), &m_indices[0], GL_STATIC_DRAW);
2311*35238bceSAndroid Build Coastguard Worker     }
2312*35238bceSAndroid Build Coastguard Worker 
2313*35238bceSAndroid Build Coastguard Worker     ctx.clearColor(0, 0, 0, 1);
2314*35238bceSAndroid Build Coastguard Worker     ctx.clear(GL_COLOR_BUFFER_BIT);
2315*35238bceSAndroid Build Coastguard Worker 
2316*35238bceSAndroid Build Coastguard Worker     ctx.viewport(0, 0, m_viewportSize.x(), m_viewportSize.y());
2317*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2318*35238bceSAndroid Build Coastguard Worker 
2319*35238bceSAndroid Build Coastguard Worker     ctx.useProgram(programId);
2320*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2321*35238bceSAndroid Build Coastguard Worker 
2322*35238bceSAndroid Build Coastguard Worker     preRender(ctx, programId);
2323*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2324*35238bceSAndroid Build Coastguard Worker 
2325*35238bceSAndroid Build Coastguard Worker     if (m_flags & FLAG_USE_RESTART_INDEX)
2326*35238bceSAndroid Build Coastguard Worker     {
2327*35238bceSAndroid Build Coastguard Worker         ctx.enable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
2328*35238bceSAndroid Build Coastguard Worker         CHECK_GL_CTX_ERRORS();
2329*35238bceSAndroid Build Coastguard Worker     }
2330*35238bceSAndroid Build Coastguard Worker 
2331*35238bceSAndroid Build Coastguard Worker     if (m_flags & FLAG_USE_INDICES)
2332*35238bceSAndroid Build Coastguard Worker         ctx.drawElements(m_inputPrimitives, m_numDrawVertices, GL_UNSIGNED_SHORT, DE_NULL);
2333*35238bceSAndroid Build Coastguard Worker     else if (m_flags & FLAG_DRAW_INSTANCED)
2334*35238bceSAndroid Build Coastguard Worker         ctx.drawArraysInstanced(m_inputPrimitives, 0, m_numDrawVertices, m_numDrawInstances);
2335*35238bceSAndroid Build Coastguard Worker     else
2336*35238bceSAndroid Build Coastguard Worker         ctx.drawArrays(m_inputPrimitives, 0, m_numDrawVertices);
2337*35238bceSAndroid Build Coastguard Worker 
2338*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2339*35238bceSAndroid Build Coastguard Worker 
2340*35238bceSAndroid Build Coastguard Worker     if (m_flags & FLAG_USE_RESTART_INDEX)
2341*35238bceSAndroid Build Coastguard Worker     {
2342*35238bceSAndroid Build Coastguard Worker         ctx.disable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
2343*35238bceSAndroid Build Coastguard Worker         CHECK_GL_CTX_ERRORS();
2344*35238bceSAndroid Build Coastguard Worker     }
2345*35238bceSAndroid Build Coastguard Worker 
2346*35238bceSAndroid Build Coastguard Worker     postRender(ctx, programId);
2347*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2348*35238bceSAndroid Build Coastguard Worker 
2349*35238bceSAndroid Build Coastguard Worker     ctx.useProgram(0);
2350*35238bceSAndroid Build Coastguard Worker 
2351*35238bceSAndroid Build Coastguard Worker     if (attrPosLoc != -1)
2352*35238bceSAndroid Build Coastguard Worker         ctx.disableVertexAttribArray(attrPosLoc);
2353*35238bceSAndroid Build Coastguard Worker     if (attrColLoc != -1)
2354*35238bceSAndroid Build Coastguard Worker         ctx.disableVertexAttribArray(attrColLoc);
2355*35238bceSAndroid Build Coastguard Worker 
2356*35238bceSAndroid Build Coastguard Worker     if (vertexPosBuf)
2357*35238bceSAndroid Build Coastguard Worker         ctx.deleteBuffers(1, &vertexPosBuf);
2358*35238bceSAndroid Build Coastguard Worker     if (vertexAttrBuf)
2359*35238bceSAndroid Build Coastguard Worker         ctx.deleteBuffers(1, &vertexAttrBuf);
2360*35238bceSAndroid Build Coastguard Worker     if (elementArrayBuf)
2361*35238bceSAndroid Build Coastguard Worker         ctx.deleteBuffers(1, &elementArrayBuf);
2362*35238bceSAndroid Build Coastguard Worker 
2363*35238bceSAndroid Build Coastguard Worker     ctx.deleteVertexArrays(1, &vaoId);
2364*35238bceSAndroid Build Coastguard Worker 
2365*35238bceSAndroid Build Coastguard Worker     CHECK_GL_CTX_ERRORS();
2366*35238bceSAndroid Build Coastguard Worker 
2367*35238bceSAndroid Build Coastguard Worker     ctx.finish();
2368*35238bceSAndroid Build Coastguard Worker     ctx.readPixels(dstSurface, 0, 0, m_viewportSize.x(), m_viewportSize.y());
2369*35238bceSAndroid Build Coastguard Worker 
2370*35238bceSAndroid Build Coastguard Worker #undef CHECK_GL_CTX_ERRORS
2371*35238bceSAndroid Build Coastguard Worker }
2372*35238bceSAndroid Build Coastguard Worker 
preRender(sglr::Context & ctx,GLuint programID)2373*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::preRender(sglr::Context &ctx, GLuint programID)
2374*35238bceSAndroid Build Coastguard Worker {
2375*35238bceSAndroid Build Coastguard Worker     DE_UNREF(ctx);
2376*35238bceSAndroid Build Coastguard Worker     DE_UNREF(programID);
2377*35238bceSAndroid Build Coastguard Worker }
2378*35238bceSAndroid Build Coastguard Worker 
postRender(sglr::Context & ctx,GLuint programID)2379*35238bceSAndroid Build Coastguard Worker void GeometryShaderRenderTest::postRender(sglr::Context &ctx, GLuint programID)
2380*35238bceSAndroid Build Coastguard Worker {
2381*35238bceSAndroid Build Coastguard Worker     DE_UNREF(ctx);
2382*35238bceSAndroid Build Coastguard Worker     DE_UNREF(programID);
2383*35238bceSAndroid Build Coastguard Worker }
2384*35238bceSAndroid Build Coastguard Worker 
2385*35238bceSAndroid Build Coastguard Worker class GeometryExpanderRenderTest : public GeometryShaderRenderTest
2386*35238bceSAndroid Build Coastguard Worker {
2387*35238bceSAndroid Build Coastguard Worker public:
2388*35238bceSAndroid Build Coastguard Worker     GeometryExpanderRenderTest(Context &context, const char *name, const char *desc, GLenum inputPrimitives,
2389*35238bceSAndroid Build Coastguard Worker                                GLenum outputPrimitives);
2390*35238bceSAndroid Build Coastguard Worker     virtual ~GeometryExpanderRenderTest(void);
2391*35238bceSAndroid Build Coastguard Worker 
2392*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
2393*35238bceSAndroid Build Coastguard Worker 
2394*35238bceSAndroid Build Coastguard Worker private:
2395*35238bceSAndroid Build Coastguard Worker     void init(void);
2396*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2397*35238bceSAndroid Build Coastguard Worker     VertexExpanderShader *m_program;
2398*35238bceSAndroid Build Coastguard Worker };
2399*35238bceSAndroid Build Coastguard Worker 
GeometryExpanderRenderTest(Context & context,const char * name,const char * desc,GLenum inputPrimitives,GLenum outputPrimitives)2400*35238bceSAndroid Build Coastguard Worker GeometryExpanderRenderTest::GeometryExpanderRenderTest(Context &context, const char *name, const char *desc,
2401*35238bceSAndroid Build Coastguard Worker                                                        GLenum inputPrimitives, GLenum outputPrimitives)
2402*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, inputPrimitives, outputPrimitives, "a_color")
2403*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2404*35238bceSAndroid Build Coastguard Worker {
2405*35238bceSAndroid Build Coastguard Worker }
2406*35238bceSAndroid Build Coastguard Worker 
~GeometryExpanderRenderTest(void)2407*35238bceSAndroid Build Coastguard Worker GeometryExpanderRenderTest::~GeometryExpanderRenderTest(void)
2408*35238bceSAndroid Build Coastguard Worker {
2409*35238bceSAndroid Build Coastguard Worker }
2410*35238bceSAndroid Build Coastguard Worker 
init(void)2411*35238bceSAndroid Build Coastguard Worker void GeometryExpanderRenderTest::init(void)
2412*35238bceSAndroid Build Coastguard Worker {
2413*35238bceSAndroid Build Coastguard Worker     m_program = new VertexExpanderShader(m_context.getRenderContext().getType(),
2414*35238bceSAndroid Build Coastguard Worker                                          sglr::rr_util::mapGLGeometryShaderInputType(m_inputPrimitives),
2415*35238bceSAndroid Build Coastguard Worker                                          sglr::rr_util::mapGLGeometryShaderOutputType(m_outputPrimitives));
2416*35238bceSAndroid Build Coastguard Worker 
2417*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
2418*35238bceSAndroid Build Coastguard Worker }
2419*35238bceSAndroid Build Coastguard Worker 
deinit(void)2420*35238bceSAndroid Build Coastguard Worker void GeometryExpanderRenderTest::deinit(void)
2421*35238bceSAndroid Build Coastguard Worker {
2422*35238bceSAndroid Build Coastguard Worker     if (m_program)
2423*35238bceSAndroid Build Coastguard Worker     {
2424*35238bceSAndroid Build Coastguard Worker         delete m_program;
2425*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
2426*35238bceSAndroid Build Coastguard Worker     }
2427*35238bceSAndroid Build Coastguard Worker 
2428*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
2429*35238bceSAndroid Build Coastguard Worker }
2430*35238bceSAndroid Build Coastguard Worker 
getProgram(void)2431*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &GeometryExpanderRenderTest::getProgram(void)
2432*35238bceSAndroid Build Coastguard Worker {
2433*35238bceSAndroid Build Coastguard Worker     return *m_program;
2434*35238bceSAndroid Build Coastguard Worker }
2435*35238bceSAndroid Build Coastguard Worker 
2436*35238bceSAndroid Build Coastguard Worker class EmitTest : public GeometryShaderRenderTest
2437*35238bceSAndroid Build Coastguard Worker {
2438*35238bceSAndroid Build Coastguard Worker public:
2439*35238bceSAndroid Build Coastguard Worker     EmitTest(Context &context, const char *name, const char *desc, int emitCountA, int endCountA, int emitCountB,
2440*35238bceSAndroid Build Coastguard Worker              int endCountB, GLenum outputType);
2441*35238bceSAndroid Build Coastguard Worker 
2442*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
2443*35238bceSAndroid Build Coastguard Worker 
2444*35238bceSAndroid Build Coastguard Worker private:
2445*35238bceSAndroid Build Coastguard Worker     void init(void);
2446*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2447*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
2448*35238bceSAndroid Build Coastguard Worker 
2449*35238bceSAndroid Build Coastguard Worker     VertexEmitterShader *m_program;
2450*35238bceSAndroid Build Coastguard Worker     int m_emitCountA;
2451*35238bceSAndroid Build Coastguard Worker     int m_endCountA;
2452*35238bceSAndroid Build Coastguard Worker     int m_emitCountB;
2453*35238bceSAndroid Build Coastguard Worker     int m_endCountB;
2454*35238bceSAndroid Build Coastguard Worker     GLenum m_outputType;
2455*35238bceSAndroid Build Coastguard Worker };
2456*35238bceSAndroid Build Coastguard Worker 
EmitTest(Context & context,const char * name,const char * desc,int emitCountA,int endCountA,int emitCountB,int endCountB,GLenum outputType)2457*35238bceSAndroid Build Coastguard Worker EmitTest::EmitTest(Context &context, const char *name, const char *desc, int emitCountA, int endCountA, int emitCountB,
2458*35238bceSAndroid Build Coastguard Worker                    int endCountB, GLenum outputType)
2459*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, GL_POINTS, outputType, "a_color")
2460*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2461*35238bceSAndroid Build Coastguard Worker     , m_emitCountA(emitCountA)
2462*35238bceSAndroid Build Coastguard Worker     , m_endCountA(endCountA)
2463*35238bceSAndroid Build Coastguard Worker     , m_emitCountB(emitCountB)
2464*35238bceSAndroid Build Coastguard Worker     , m_endCountB(endCountB)
2465*35238bceSAndroid Build Coastguard Worker     , m_outputType(outputType)
2466*35238bceSAndroid Build Coastguard Worker {
2467*35238bceSAndroid Build Coastguard Worker }
2468*35238bceSAndroid Build Coastguard Worker 
init(void)2469*35238bceSAndroid Build Coastguard Worker void EmitTest::init(void)
2470*35238bceSAndroid Build Coastguard Worker {
2471*35238bceSAndroid Build Coastguard Worker     m_program = new VertexEmitterShader(m_context.getRenderContext().getType(), m_emitCountA, m_endCountA, m_emitCountB,
2472*35238bceSAndroid Build Coastguard Worker                                         m_endCountB, sglr::rr_util::mapGLGeometryShaderOutputType(m_outputType));
2473*35238bceSAndroid Build Coastguard Worker 
2474*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
2475*35238bceSAndroid Build Coastguard Worker }
2476*35238bceSAndroid Build Coastguard Worker 
deinit(void)2477*35238bceSAndroid Build Coastguard Worker void EmitTest::deinit(void)
2478*35238bceSAndroid Build Coastguard Worker {
2479*35238bceSAndroid Build Coastguard Worker     if (m_program)
2480*35238bceSAndroid Build Coastguard Worker     {
2481*35238bceSAndroid Build Coastguard Worker         delete m_program;
2482*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
2483*35238bceSAndroid Build Coastguard Worker     }
2484*35238bceSAndroid Build Coastguard Worker 
2485*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
2486*35238bceSAndroid Build Coastguard Worker }
2487*35238bceSAndroid Build Coastguard Worker 
getProgram(void)2488*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &EmitTest::getProgram(void)
2489*35238bceSAndroid Build Coastguard Worker {
2490*35238bceSAndroid Build Coastguard Worker     return *m_program;
2491*35238bceSAndroid Build Coastguard Worker }
2492*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2493*35238bceSAndroid Build Coastguard Worker void EmitTest::genVertexAttribData(void)
2494*35238bceSAndroid Build Coastguard Worker {
2495*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(1);
2496*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0, 0, 0, 1);
2497*35238bceSAndroid Build Coastguard Worker 
2498*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(1);
2499*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[0] = tcu::Vec4(1, 1, 1, 1);
2500*35238bceSAndroid Build Coastguard Worker 
2501*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 1;
2502*35238bceSAndroid Build Coastguard Worker }
2503*35238bceSAndroid Build Coastguard Worker 
2504*35238bceSAndroid Build Coastguard Worker class VaryingTest : public GeometryShaderRenderTest
2505*35238bceSAndroid Build Coastguard Worker {
2506*35238bceSAndroid Build Coastguard Worker public:
2507*35238bceSAndroid Build Coastguard Worker     VaryingTest(Context &context, const char *name, const char *desc, int vertexOut, int geometryOut);
2508*35238bceSAndroid Build Coastguard Worker 
2509*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
2510*35238bceSAndroid Build Coastguard Worker 
2511*35238bceSAndroid Build Coastguard Worker private:
2512*35238bceSAndroid Build Coastguard Worker     void init(void);
2513*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2514*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
2515*35238bceSAndroid Build Coastguard Worker 
2516*35238bceSAndroid Build Coastguard Worker     VertexVaryingShader *m_program;
2517*35238bceSAndroid Build Coastguard Worker     int m_vertexOut;
2518*35238bceSAndroid Build Coastguard Worker     int m_geometryOut;
2519*35238bceSAndroid Build Coastguard Worker };
2520*35238bceSAndroid Build Coastguard Worker 
VaryingTest(Context & context,const char * name,const char * desc,int vertexOut,int geometryOut)2521*35238bceSAndroid Build Coastguard Worker VaryingTest::VaryingTest(Context &context, const char *name, const char *desc, int vertexOut, int geometryOut)
2522*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, GL_TRIANGLES, GL_TRIANGLE_STRIP, "a_color")
2523*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2524*35238bceSAndroid Build Coastguard Worker     , m_vertexOut(vertexOut)
2525*35238bceSAndroid Build Coastguard Worker     , m_geometryOut(geometryOut)
2526*35238bceSAndroid Build Coastguard Worker {
2527*35238bceSAndroid Build Coastguard Worker }
2528*35238bceSAndroid Build Coastguard Worker 
init(void)2529*35238bceSAndroid Build Coastguard Worker void VaryingTest::init(void)
2530*35238bceSAndroid Build Coastguard Worker {
2531*35238bceSAndroid Build Coastguard Worker     m_program = new VertexVaryingShader(m_context.getRenderContext().getType(), m_vertexOut, m_geometryOut);
2532*35238bceSAndroid Build Coastguard Worker 
2533*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
2534*35238bceSAndroid Build Coastguard Worker }
2535*35238bceSAndroid Build Coastguard Worker 
deinit(void)2536*35238bceSAndroid Build Coastguard Worker void VaryingTest::deinit(void)
2537*35238bceSAndroid Build Coastguard Worker {
2538*35238bceSAndroid Build Coastguard Worker     if (m_program)
2539*35238bceSAndroid Build Coastguard Worker     {
2540*35238bceSAndroid Build Coastguard Worker         delete m_program;
2541*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
2542*35238bceSAndroid Build Coastguard Worker     }
2543*35238bceSAndroid Build Coastguard Worker 
2544*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
2545*35238bceSAndroid Build Coastguard Worker }
2546*35238bceSAndroid Build Coastguard Worker 
getProgram(void)2547*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &VaryingTest::getProgram(void)
2548*35238bceSAndroid Build Coastguard Worker {
2549*35238bceSAndroid Build Coastguard Worker     return *m_program;
2550*35238bceSAndroid Build Coastguard Worker }
2551*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2552*35238bceSAndroid Build Coastguard Worker void VaryingTest::genVertexAttribData(void)
2553*35238bceSAndroid Build Coastguard Worker {
2554*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(3);
2555*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
2556*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
2557*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[2] = tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f);
2558*35238bceSAndroid Build Coastguard Worker 
2559*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(3);
2560*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[0] = tcu::Vec4(0.7f, 0.4f, 0.6f, 1.0f);
2561*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[1] = tcu::Vec4(0.9f, 0.2f, 0.5f, 1.0f);
2562*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[2] = tcu::Vec4(0.1f, 0.8f, 0.3f, 1.0f);
2563*35238bceSAndroid Build Coastguard Worker 
2564*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 3;
2565*35238bceSAndroid Build Coastguard Worker }
2566*35238bceSAndroid Build Coastguard Worker 
2567*35238bceSAndroid Build Coastguard Worker class TriangleStripAdjacencyVertexCountTest : public GeometryExpanderRenderTest
2568*35238bceSAndroid Build Coastguard Worker {
2569*35238bceSAndroid Build Coastguard Worker public:
2570*35238bceSAndroid Build Coastguard Worker     TriangleStripAdjacencyVertexCountTest(Context &context, const char *name, const char *desc, int numInputVertices);
2571*35238bceSAndroid Build Coastguard Worker 
2572*35238bceSAndroid Build Coastguard Worker private:
2573*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
2574*35238bceSAndroid Build Coastguard Worker 
2575*35238bceSAndroid Build Coastguard Worker     int m_numInputVertices;
2576*35238bceSAndroid Build Coastguard Worker };
2577*35238bceSAndroid Build Coastguard Worker 
TriangleStripAdjacencyVertexCountTest(Context & context,const char * name,const char * desc,int numInputVertices)2578*35238bceSAndroid Build Coastguard Worker TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest(Context &context, const char *name,
2579*35238bceSAndroid Build Coastguard Worker                                                                              const char *desc, int numInputVertices)
2580*35238bceSAndroid Build Coastguard Worker     : GeometryExpanderRenderTest(context, name, desc, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLE_STRIP)
2581*35238bceSAndroid Build Coastguard Worker     , m_numInputVertices(numInputVertices)
2582*35238bceSAndroid Build Coastguard Worker {
2583*35238bceSAndroid Build Coastguard Worker }
2584*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2585*35238bceSAndroid Build Coastguard Worker void TriangleStripAdjacencyVertexCountTest::genVertexAttribData(void)
2586*35238bceSAndroid Build Coastguard Worker {
2587*35238bceSAndroid Build Coastguard Worker     this->GeometryShaderRenderTest::genVertexAttribData();
2588*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = m_numInputVertices;
2589*35238bceSAndroid Build Coastguard Worker }
2590*35238bceSAndroid Build Coastguard Worker 
2591*35238bceSAndroid Build Coastguard Worker class NegativeDrawCase : public TestCase
2592*35238bceSAndroid Build Coastguard Worker {
2593*35238bceSAndroid Build Coastguard Worker public:
2594*35238bceSAndroid Build Coastguard Worker     NegativeDrawCase(Context &context, const char *name, const char *desc, GLenum inputType, GLenum inputPrimitives);
2595*35238bceSAndroid Build Coastguard Worker     ~NegativeDrawCase(void);
2596*35238bceSAndroid Build Coastguard Worker 
2597*35238bceSAndroid Build Coastguard Worker     void init(void);
2598*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2599*35238bceSAndroid Build Coastguard Worker 
2600*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2601*35238bceSAndroid Build Coastguard Worker 
2602*35238bceSAndroid Build Coastguard Worker private:
2603*35238bceSAndroid Build Coastguard Worker     sglr::Context *m_ctx;
2604*35238bceSAndroid Build Coastguard Worker     VertexExpanderShader *m_program;
2605*35238bceSAndroid Build Coastguard Worker     GLenum m_inputType;
2606*35238bceSAndroid Build Coastguard Worker     GLenum m_inputPrimitives;
2607*35238bceSAndroid Build Coastguard Worker };
2608*35238bceSAndroid Build Coastguard Worker 
NegativeDrawCase(Context & context,const char * name,const char * desc,GLenum inputType,GLenum inputPrimitives)2609*35238bceSAndroid Build Coastguard Worker NegativeDrawCase::NegativeDrawCase(Context &context, const char *name, const char *desc, GLenum inputType,
2610*35238bceSAndroid Build Coastguard Worker                                    GLenum inputPrimitives)
2611*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2612*35238bceSAndroid Build Coastguard Worker     , m_ctx(DE_NULL)
2613*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2614*35238bceSAndroid Build Coastguard Worker     , m_inputType(inputType)
2615*35238bceSAndroid Build Coastguard Worker     , m_inputPrimitives(inputPrimitives)
2616*35238bceSAndroid Build Coastguard Worker {
2617*35238bceSAndroid Build Coastguard Worker }
2618*35238bceSAndroid Build Coastguard Worker 
~NegativeDrawCase(void)2619*35238bceSAndroid Build Coastguard Worker NegativeDrawCase::~NegativeDrawCase(void)
2620*35238bceSAndroid Build Coastguard Worker {
2621*35238bceSAndroid Build Coastguard Worker     deinit();
2622*35238bceSAndroid Build Coastguard Worker }
2623*35238bceSAndroid Build Coastguard Worker 
init(void)2624*35238bceSAndroid Build Coastguard Worker void NegativeDrawCase::init(void)
2625*35238bceSAndroid Build Coastguard Worker {
2626*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
2627*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
2628*35238bceSAndroid Build Coastguard Worker 
2629*35238bceSAndroid Build Coastguard Worker     m_ctx     = new sglr::GLContext(m_context.getRenderContext(), m_testCtx.getLog(),
2630*35238bceSAndroid Build Coastguard Worker                                     sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, 1, 1));
2631*35238bceSAndroid Build Coastguard Worker     m_program = new VertexExpanderShader(m_context.getRenderContext().getType(),
2632*35238bceSAndroid Build Coastguard Worker                                          sglr::rr_util::mapGLGeometryShaderInputType(m_inputType),
2633*35238bceSAndroid Build Coastguard Worker                                          rr::GEOMETRYSHADEROUTPUTTYPE_POINTS);
2634*35238bceSAndroid Build Coastguard Worker }
2635*35238bceSAndroid Build Coastguard Worker 
deinit(void)2636*35238bceSAndroid Build Coastguard Worker void NegativeDrawCase::deinit(void)
2637*35238bceSAndroid Build Coastguard Worker {
2638*35238bceSAndroid Build Coastguard Worker     delete m_ctx;
2639*35238bceSAndroid Build Coastguard Worker     delete m_program;
2640*35238bceSAndroid Build Coastguard Worker 
2641*35238bceSAndroid Build Coastguard Worker     m_ctx     = NULL;
2642*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
2643*35238bceSAndroid Build Coastguard Worker }
2644*35238bceSAndroid Build Coastguard Worker 
iterate(void)2645*35238bceSAndroid Build Coastguard Worker NegativeDrawCase::IterateResult NegativeDrawCase::iterate(void)
2646*35238bceSAndroid Build Coastguard Worker {
2647*35238bceSAndroid Build Coastguard Worker     const GLuint programId = m_ctx->createProgram(m_program);
2648*35238bceSAndroid Build Coastguard Worker     const GLint attrPosLoc = m_ctx->getAttribLocation(programId, "a_position");
2649*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexPosData(0, 0, 0, 1);
2650*35238bceSAndroid Build Coastguard Worker 
2651*35238bceSAndroid Build Coastguard Worker     GLuint vaoId        = 0;
2652*35238bceSAndroid Build Coastguard Worker     GLuint vertexPosBuf = 0;
2653*35238bceSAndroid Build Coastguard Worker     GLenum errorCode    = 0;
2654*35238bceSAndroid Build Coastguard Worker 
2655*35238bceSAndroid Build Coastguard Worker     m_ctx->genVertexArrays(1, &vaoId);
2656*35238bceSAndroid Build Coastguard Worker     m_ctx->bindVertexArray(vaoId);
2657*35238bceSAndroid Build Coastguard Worker 
2658*35238bceSAndroid Build Coastguard Worker     m_ctx->genBuffers(1, &vertexPosBuf);
2659*35238bceSAndroid Build Coastguard Worker     m_ctx->bindBuffer(GL_ARRAY_BUFFER, vertexPosBuf);
2660*35238bceSAndroid Build Coastguard Worker     m_ctx->bufferData(GL_ARRAY_BUFFER, sizeof(tcu::Vec4), vertexPosData.m_data, GL_STATIC_DRAW);
2661*35238bceSAndroid Build Coastguard Worker     m_ctx->vertexAttribPointer(attrPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2662*35238bceSAndroid Build Coastguard Worker     m_ctx->enableVertexAttribArray(attrPosLoc);
2663*35238bceSAndroid Build Coastguard Worker 
2664*35238bceSAndroid Build Coastguard Worker     m_ctx->clearColor(0, 0, 0, 1);
2665*35238bceSAndroid Build Coastguard Worker     m_ctx->clear(GL_COLOR_BUFFER_BIT);
2666*35238bceSAndroid Build Coastguard Worker 
2667*35238bceSAndroid Build Coastguard Worker     m_ctx->viewport(0, 0, 1, 1);
2668*35238bceSAndroid Build Coastguard Worker 
2669*35238bceSAndroid Build Coastguard Worker     m_ctx->useProgram(programId);
2670*35238bceSAndroid Build Coastguard Worker 
2671*35238bceSAndroid Build Coastguard Worker     // no errors before
2672*35238bceSAndroid Build Coastguard Worker     glu::checkError(m_ctx->getError(), "", __FILE__, __LINE__);
2673*35238bceSAndroid Build Coastguard Worker 
2674*35238bceSAndroid Build Coastguard Worker     m_ctx->drawArrays(m_inputPrimitives, 0, 1);
2675*35238bceSAndroid Build Coastguard Worker 
2676*35238bceSAndroid Build Coastguard Worker     errorCode = m_ctx->getError();
2677*35238bceSAndroid Build Coastguard Worker     if (errorCode != GL_INVALID_OPERATION)
2678*35238bceSAndroid Build Coastguard Worker     {
2679*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Expected GL_INVALID_OPERATION, got "
2680*35238bceSAndroid Build Coastguard Worker                            << glu::getErrorStr(errorCode) << tcu::TestLog::EndMessage;
2681*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong error code");
2682*35238bceSAndroid Build Coastguard Worker     }
2683*35238bceSAndroid Build Coastguard Worker     else
2684*35238bceSAndroid Build Coastguard Worker     {
2685*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2686*35238bceSAndroid Build Coastguard Worker     }
2687*35238bceSAndroid Build Coastguard Worker 
2688*35238bceSAndroid Build Coastguard Worker     m_ctx->useProgram(0);
2689*35238bceSAndroid Build Coastguard Worker 
2690*35238bceSAndroid Build Coastguard Worker     m_ctx->disableVertexAttribArray(attrPosLoc);
2691*35238bceSAndroid Build Coastguard Worker     m_ctx->deleteBuffers(1, &vertexPosBuf);
2692*35238bceSAndroid Build Coastguard Worker 
2693*35238bceSAndroid Build Coastguard Worker     m_ctx->deleteVertexArrays(1, &vaoId);
2694*35238bceSAndroid Build Coastguard Worker 
2695*35238bceSAndroid Build Coastguard Worker     return STOP;
2696*35238bceSAndroid Build Coastguard Worker }
2697*35238bceSAndroid Build Coastguard Worker 
2698*35238bceSAndroid Build Coastguard Worker class OutputCountCase : public GeometryShaderRenderTest
2699*35238bceSAndroid Build Coastguard Worker {
2700*35238bceSAndroid Build Coastguard Worker public:
2701*35238bceSAndroid Build Coastguard Worker     OutputCountCase(Context &context, const char *name, const char *desc, const OutputCountPatternSpec &);
2702*35238bceSAndroid Build Coastguard Worker 
2703*35238bceSAndroid Build Coastguard Worker private:
2704*35238bceSAndroid Build Coastguard Worker     void init(void);
2705*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2706*35238bceSAndroid Build Coastguard Worker 
2707*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
2708*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
2709*35238bceSAndroid Build Coastguard Worker 
2710*35238bceSAndroid Build Coastguard Worker     const int m_primitiveCount;
2711*35238bceSAndroid Build Coastguard Worker     OutputCountShader *m_program;
2712*35238bceSAndroid Build Coastguard Worker     OutputCountPatternSpec m_spec;
2713*35238bceSAndroid Build Coastguard Worker };
2714*35238bceSAndroid Build Coastguard Worker 
OutputCountCase(Context & context,const char * name,const char * desc,const OutputCountPatternSpec & spec)2715*35238bceSAndroid Build Coastguard Worker OutputCountCase::OutputCountCase(Context &context, const char *name, const char *desc,
2716*35238bceSAndroid Build Coastguard Worker                                  const OutputCountPatternSpec &spec)
2717*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, GL_POINTS, GL_TRIANGLE_STRIP, "a_color")
2718*35238bceSAndroid Build Coastguard Worker     , m_primitiveCount((int)spec.pattern.size())
2719*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2720*35238bceSAndroid Build Coastguard Worker     , m_spec(spec)
2721*35238bceSAndroid Build Coastguard Worker {
2722*35238bceSAndroid Build Coastguard Worker }
2723*35238bceSAndroid Build Coastguard Worker 
init(void)2724*35238bceSAndroid Build Coastguard Worker void OutputCountCase::init(void)
2725*35238bceSAndroid Build Coastguard Worker {
2726*35238bceSAndroid Build Coastguard Worker     // Check requirements and adapt to them
2727*35238bceSAndroid Build Coastguard Worker     {
2728*35238bceSAndroid Build Coastguard Worker         const int componentsPerVertex = 4 + 4; // vec4 pos, vec4 color
2729*35238bceSAndroid Build Coastguard Worker         const int testVertices        = *std::max_element(m_spec.pattern.begin(), m_spec.pattern.end());
2730*35238bceSAndroid Build Coastguard Worker         glw::GLint maxVertices        = 0;
2731*35238bceSAndroid Build Coastguard Worker         glw::GLint maxComponents      = 0;
2732*35238bceSAndroid Build Coastguard Worker 
2733*35238bceSAndroid Build Coastguard Worker         // check the extension before querying anything
2734*35238bceSAndroid Build Coastguard Worker         if (!checkSupport(m_context))
2735*35238bceSAndroid Build Coastguard Worker             TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
2736*35238bceSAndroid Build Coastguard Worker 
2737*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &maxVertices);
2738*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
2739*35238bceSAndroid Build Coastguard Worker                                                                 &maxComponents);
2740*35238bceSAndroid Build Coastguard Worker 
2741*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_OUTPUT_VERTICES = " << maxVertices
2742*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2743*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << maxComponents
2744*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2745*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Components per vertex = " << componentsPerVertex
2746*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2747*35238bceSAndroid Build Coastguard Worker 
2748*35238bceSAndroid Build Coastguard Worker         if (testVertices == -1)
2749*35238bceSAndroid Build Coastguard Worker         {
2750*35238bceSAndroid Build Coastguard Worker             // "max vertices"-case
2751*35238bceSAndroid Build Coastguard Worker             DE_ASSERT((int)m_spec.pattern.size() == 1);
2752*35238bceSAndroid Build Coastguard Worker             m_spec.pattern[0] = de::min(maxVertices, maxComponents / componentsPerVertex);
2753*35238bceSAndroid Build Coastguard Worker 
2754*35238bceSAndroid Build Coastguard Worker             // make sure size is dividable by 2, as OutputShader requires
2755*35238bceSAndroid Build Coastguard Worker             m_spec.pattern[0] = m_spec.pattern[0] & ~0x00000001;
2756*35238bceSAndroid Build Coastguard Worker 
2757*35238bceSAndroid Build Coastguard Worker             if (m_spec.pattern[0] == 0)
2758*35238bceSAndroid Build Coastguard Worker                 throw tcu::InternalError("Pattern size is invalid.");
2759*35238bceSAndroid Build Coastguard Worker         }
2760*35238bceSAndroid Build Coastguard Worker         else
2761*35238bceSAndroid Build Coastguard Worker         {
2762*35238bceSAndroid Build Coastguard Worker             // normal case
2763*35238bceSAndroid Build Coastguard Worker             if (testVertices > maxVertices)
2764*35238bceSAndroid Build Coastguard Worker                 throw tcu::NotSupportedError(de::toString(testVertices) + " output vertices required.");
2765*35238bceSAndroid Build Coastguard Worker             if (testVertices * componentsPerVertex > maxComponents)
2766*35238bceSAndroid Build Coastguard Worker                 throw tcu::NotSupportedError(de::toString(testVertices * componentsPerVertex) +
2767*35238bceSAndroid Build Coastguard Worker                                              " output components required.");
2768*35238bceSAndroid Build Coastguard Worker         }
2769*35238bceSAndroid Build Coastguard Worker     }
2770*35238bceSAndroid Build Coastguard Worker 
2771*35238bceSAndroid Build Coastguard Worker     // Log what the test tries to do
2772*35238bceSAndroid Build Coastguard Worker 
2773*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << (int)m_spec.pattern.size()
2774*35238bceSAndroid Build Coastguard Worker                        << " row(s).\nOne geometry shader invocation generates one row.\nRow sizes:"
2775*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
2776*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_spec.pattern.size(); ++ndx)
2777*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Row " << ndx << ": " << m_spec.pattern[ndx] << " vertices."
2778*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2779*35238bceSAndroid Build Coastguard Worker 
2780*35238bceSAndroid Build Coastguard Worker     // Gen shader
2781*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_program);
2782*35238bceSAndroid Build Coastguard Worker     m_program = new OutputCountShader(m_context.getRenderContext().getType(), m_spec);
2783*35238bceSAndroid Build Coastguard Worker 
2784*35238bceSAndroid Build Coastguard Worker     // Case init
2785*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
2786*35238bceSAndroid Build Coastguard Worker }
2787*35238bceSAndroid Build Coastguard Worker 
deinit(void)2788*35238bceSAndroid Build Coastguard Worker void OutputCountCase::deinit(void)
2789*35238bceSAndroid Build Coastguard Worker {
2790*35238bceSAndroid Build Coastguard Worker     if (m_program)
2791*35238bceSAndroid Build Coastguard Worker     {
2792*35238bceSAndroid Build Coastguard Worker         delete m_program;
2793*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
2794*35238bceSAndroid Build Coastguard Worker     }
2795*35238bceSAndroid Build Coastguard Worker 
2796*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
2797*35238bceSAndroid Build Coastguard Worker }
2798*35238bceSAndroid Build Coastguard Worker 
getProgram(void)2799*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &OutputCountCase::getProgram(void)
2800*35238bceSAndroid Build Coastguard Worker {
2801*35238bceSAndroid Build Coastguard Worker     return *m_program;
2802*35238bceSAndroid Build Coastguard Worker }
2803*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2804*35238bceSAndroid Build Coastguard Worker void OutputCountCase::genVertexAttribData(void)
2805*35238bceSAndroid Build Coastguard Worker {
2806*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(m_primitiveCount);
2807*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(m_primitiveCount);
2808*35238bceSAndroid Build Coastguard Worker 
2809*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < m_primitiveCount; ++ndx)
2810*35238bceSAndroid Build Coastguard Worker     {
2811*35238bceSAndroid Build Coastguard Worker         m_vertexPosData[ndx]  = tcu::Vec4(-1.0f, ((float)ndx) / (float)m_primitiveCount * 2.0f - 1.0f, 0.0f, 1.0f);
2812*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[ndx] = (ndx % 2 == 0) ? tcu::Vec4(1, 1, 1, 1) : tcu::Vec4(1, 0, 0, 1);
2813*35238bceSAndroid Build Coastguard Worker     }
2814*35238bceSAndroid Build Coastguard Worker 
2815*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = m_primitiveCount;
2816*35238bceSAndroid Build Coastguard Worker }
2817*35238bceSAndroid Build Coastguard Worker 
2818*35238bceSAndroid Build Coastguard Worker class BuiltinVariableRenderTest : public GeometryShaderRenderTest
2819*35238bceSAndroid Build Coastguard Worker {
2820*35238bceSAndroid Build Coastguard Worker public:
2821*35238bceSAndroid Build Coastguard Worker     BuiltinVariableRenderTest(Context &context, const char *name, const char *desc,
2822*35238bceSAndroid Build Coastguard Worker                               BuiltinVariableShader::VariableTest test, int flags = 0);
2823*35238bceSAndroid Build Coastguard Worker 
2824*35238bceSAndroid Build Coastguard Worker private:
2825*35238bceSAndroid Build Coastguard Worker     void init(void);
2826*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2827*35238bceSAndroid Build Coastguard Worker 
2828*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
2829*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
2830*35238bceSAndroid Build Coastguard Worker 
2831*35238bceSAndroid Build Coastguard Worker     BuiltinVariableShader *m_program;
2832*35238bceSAndroid Build Coastguard Worker     const BuiltinVariableShader::VariableTest m_test;
2833*35238bceSAndroid Build Coastguard Worker };
2834*35238bceSAndroid Build Coastguard Worker 
BuiltinVariableRenderTest(Context & context,const char * name,const char * desc,BuiltinVariableShader::VariableTest test,int flags)2835*35238bceSAndroid Build Coastguard Worker BuiltinVariableRenderTest::BuiltinVariableRenderTest(Context &context, const char *name, const char *desc,
2836*35238bceSAndroid Build Coastguard Worker                                                      BuiltinVariableShader::VariableTest test, int flags)
2837*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, GL_POINTS, GL_POINTS,
2838*35238bceSAndroid Build Coastguard Worker                                BuiltinVariableShader::getTestAttributeName(test), flags)
2839*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2840*35238bceSAndroid Build Coastguard Worker     , m_test(test)
2841*35238bceSAndroid Build Coastguard Worker {
2842*35238bceSAndroid Build Coastguard Worker }
2843*35238bceSAndroid Build Coastguard Worker 
init(void)2844*35238bceSAndroid Build Coastguard Worker void BuiltinVariableRenderTest::init(void)
2845*35238bceSAndroid Build Coastguard Worker {
2846*35238bceSAndroid Build Coastguard Worker     // Requirements
2847*35238bceSAndroid Build Coastguard Worker     if (m_test == BuiltinVariableShader::TEST_POINT_SIZE)
2848*35238bceSAndroid Build Coastguard Worker     {
2849*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2850*35238bceSAndroid Build Coastguard Worker 
2851*35238bceSAndroid Build Coastguard Worker         const float requiredPointSize = 5.0f;
2852*35238bceSAndroid Build Coastguard Worker 
2853*35238bceSAndroid Build Coastguard Worker         tcu::Vec2 range = tcu::Vec2(1.0f, 1.0f);
2854*35238bceSAndroid Build Coastguard Worker 
2855*35238bceSAndroid Build Coastguard Worker         if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 4)) &&
2856*35238bceSAndroid Build Coastguard Worker             !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
2857*35238bceSAndroid Build Coastguard Worker             TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_point_size extension.");
2858*35238bceSAndroid Build Coastguard Worker 
2859*35238bceSAndroid Build Coastguard Worker         gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range.getPtr());
2860*35238bceSAndroid Build Coastguard Worker         if (range.y() < requiredPointSize)
2861*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Test case requires point size " + de::toString(requiredPointSize));
2862*35238bceSAndroid Build Coastguard Worker 
2863*35238bceSAndroid Build Coastguard Worker         if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
2864*35238bceSAndroid Build Coastguard Worker             gl.enable(GL_PROGRAM_POINT_SIZE);
2865*35238bceSAndroid Build Coastguard Worker     }
2866*35238bceSAndroid Build Coastguard Worker 
2867*35238bceSAndroid Build Coastguard Worker     m_program = new BuiltinVariableShader(m_context.getRenderContext().getType(), m_test);
2868*35238bceSAndroid Build Coastguard Worker 
2869*35238bceSAndroid Build Coastguard Worker     // Shader init
2870*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
2871*35238bceSAndroid Build Coastguard Worker }
2872*35238bceSAndroid Build Coastguard Worker 
deinit(void)2873*35238bceSAndroid Build Coastguard Worker void BuiltinVariableRenderTest::deinit(void)
2874*35238bceSAndroid Build Coastguard Worker {
2875*35238bceSAndroid Build Coastguard Worker     if (BuiltinVariableShader::TEST_POINT_SIZE == m_test &&
2876*35238bceSAndroid Build Coastguard Worker         glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
2877*35238bceSAndroid Build Coastguard Worker     {
2878*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().disable(GL_PROGRAM_POINT_SIZE);
2879*35238bceSAndroid Build Coastguard Worker     }
2880*35238bceSAndroid Build Coastguard Worker 
2881*35238bceSAndroid Build Coastguard Worker     if (m_program)
2882*35238bceSAndroid Build Coastguard Worker     {
2883*35238bceSAndroid Build Coastguard Worker         delete m_program;
2884*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
2885*35238bceSAndroid Build Coastguard Worker     }
2886*35238bceSAndroid Build Coastguard Worker 
2887*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
2888*35238bceSAndroid Build Coastguard Worker }
2889*35238bceSAndroid Build Coastguard Worker 
getProgram(void)2890*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &BuiltinVariableRenderTest::getProgram(void)
2891*35238bceSAndroid Build Coastguard Worker {
2892*35238bceSAndroid Build Coastguard Worker     return *m_program;
2893*35238bceSAndroid Build Coastguard Worker }
2894*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)2895*35238bceSAndroid Build Coastguard Worker void BuiltinVariableRenderTest::genVertexAttribData(void)
2896*35238bceSAndroid Build Coastguard Worker {
2897*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(4);
2898*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
2899*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
2900*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
2901*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
2902*35238bceSAndroid Build Coastguard Worker 
2903*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(4);
2904*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2905*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
2906*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
2907*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
2908*35238bceSAndroid Build Coastguard Worker 
2909*35238bceSAndroid Build Coastguard Worker     // Only used by primitive ID restart test
2910*35238bceSAndroid Build Coastguard Worker     m_indices.resize(4);
2911*35238bceSAndroid Build Coastguard Worker     m_indices[0] = 3;
2912*35238bceSAndroid Build Coastguard Worker     m_indices[1] = 2;
2913*35238bceSAndroid Build Coastguard Worker     m_indices[2] = 0xFFFF; // restart
2914*35238bceSAndroid Build Coastguard Worker     m_indices[3] = 1;
2915*35238bceSAndroid Build Coastguard Worker 
2916*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 4;
2917*35238bceSAndroid Build Coastguard Worker }
2918*35238bceSAndroid Build Coastguard Worker 
2919*35238bceSAndroid Build Coastguard Worker class LayeredRenderCase : public TestCase
2920*35238bceSAndroid Build Coastguard Worker {
2921*35238bceSAndroid Build Coastguard Worker public:
2922*35238bceSAndroid Build Coastguard Worker     enum LayeredRenderTargetType
2923*35238bceSAndroid Build Coastguard Worker     {
2924*35238bceSAndroid Build Coastguard Worker         TARGET_CUBE = 0,
2925*35238bceSAndroid Build Coastguard Worker         TARGET_3D,
2926*35238bceSAndroid Build Coastguard Worker         TARGET_1D_ARRAY,
2927*35238bceSAndroid Build Coastguard Worker         TARGET_2D_ARRAY,
2928*35238bceSAndroid Build Coastguard Worker         TARGET_2D_MS_ARRAY,
2929*35238bceSAndroid Build Coastguard Worker 
2930*35238bceSAndroid Build Coastguard Worker         TARGET_LAST
2931*35238bceSAndroid Build Coastguard Worker     };
2932*35238bceSAndroid Build Coastguard Worker     enum TestType
2933*35238bceSAndroid Build Coastguard Worker     {
2934*35238bceSAndroid Build Coastguard Worker         TEST_DEFAULT_LAYER,                  // !< draw to default layer
2935*35238bceSAndroid Build Coastguard Worker         TEST_SINGLE_LAYER,                   // !< draw to single layer
2936*35238bceSAndroid Build Coastguard Worker         TEST_ALL_LAYERS,                     // !< draw all layers
2937*35238bceSAndroid Build Coastguard Worker         TEST_DIFFERENT_LAYERS,               // !< draw different content to different layers
2938*35238bceSAndroid Build Coastguard Worker         TEST_INVOCATION_PER_LAYER,           // !< draw to all layers, one invocation per layer
2939*35238bceSAndroid Build Coastguard Worker         TEST_MULTIPLE_LAYERS_PER_INVOCATION, // !< draw to all layers, multiple invocations write to multiple layers
2940*35238bceSAndroid Build Coastguard Worker         TEST_LAYER_ID,                       // !< draw to all layers, verify gl_Layer fragment input
2941*35238bceSAndroid Build Coastguard Worker         TEST_LAYER_PROVOKING_VERTEX, // !< draw primitive with vertices in different layers, check which layer it was drawn to
2942*35238bceSAndroid Build Coastguard Worker 
2943*35238bceSAndroid Build Coastguard Worker         TEST_LAST
2944*35238bceSAndroid Build Coastguard Worker     };
2945*35238bceSAndroid Build Coastguard Worker     LayeredRenderCase(Context &context, const char *name, const char *desc, LayeredRenderTargetType target,
2946*35238bceSAndroid Build Coastguard Worker                       TestType test);
2947*35238bceSAndroid Build Coastguard Worker     ~LayeredRenderCase(void);
2948*35238bceSAndroid Build Coastguard Worker 
2949*35238bceSAndroid Build Coastguard Worker     void init(void);
2950*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2951*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2952*35238bceSAndroid Build Coastguard Worker 
2953*35238bceSAndroid Build Coastguard Worker private:
2954*35238bceSAndroid Build Coastguard Worker     void initTexture(void);
2955*35238bceSAndroid Build Coastguard Worker     void initFbo(void);
2956*35238bceSAndroid Build Coastguard Worker     void initRenderShader(void);
2957*35238bceSAndroid Build Coastguard Worker     void initSamplerShader(void);
2958*35238bceSAndroid Build Coastguard Worker 
2959*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(const glu::ContextType &contextType) const;
2960*35238bceSAndroid Build Coastguard Worker     std::string genGeometrySource(const glu::ContextType &contextType) const;
2961*35238bceSAndroid Build Coastguard Worker     std::string genSamplerFragmentSource(const glu::ContextType &contextType) const;
2962*35238bceSAndroid Build Coastguard Worker 
2963*35238bceSAndroid Build Coastguard Worker     void renderToTexture(void);
2964*35238bceSAndroid Build Coastguard Worker     void sampleTextureLayer(tcu::Surface &dst, int layer);
2965*35238bceSAndroid Build Coastguard Worker     bool verifyLayerContent(const tcu::Surface &layer, int layerNdx);
2966*35238bceSAndroid Build Coastguard Worker     bool verifyImageSingleColoredRow(const tcu::Surface &layer, float rowWidthRatio, const tcu::Vec4 &color,
2967*35238bceSAndroid Build Coastguard Worker                                      bool logging = true);
2968*35238bceSAndroid Build Coastguard Worker     bool verifyEmptyImage(const tcu::Surface &layer, bool logging = true);
2969*35238bceSAndroid Build Coastguard Worker     bool verifyProvokingVertexLayers(const tcu::Surface &layer0, const tcu::Surface &layer1);
2970*35238bceSAndroid Build Coastguard Worker 
2971*35238bceSAndroid Build Coastguard Worker     static int getTargetLayers(LayeredRenderTargetType target);
2972*35238bceSAndroid Build Coastguard Worker     static glw::GLenum getTargetTextureTarget(LayeredRenderTargetType target);
2973*35238bceSAndroid Build Coastguard Worker     static tcu::IVec3 getTargetDimensions(LayeredRenderTargetType target);
2974*35238bceSAndroid Build Coastguard Worker     static tcu::IVec2 getResolveDimensions(LayeredRenderTargetType target);
2975*35238bceSAndroid Build Coastguard Worker 
2976*35238bceSAndroid Build Coastguard Worker     const LayeredRenderTargetType m_target;
2977*35238bceSAndroid Build Coastguard Worker     const TestType m_test;
2978*35238bceSAndroid Build Coastguard Worker     const int m_numLayers;
2979*35238bceSAndroid Build Coastguard Worker     const int m_targetLayer;
2980*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_resolveDimensions;
2981*35238bceSAndroid Build Coastguard Worker 
2982*35238bceSAndroid Build Coastguard Worker     int m_iteration;
2983*35238bceSAndroid Build Coastguard Worker     bool m_allLayersOk;
2984*35238bceSAndroid Build Coastguard Worker 
2985*35238bceSAndroid Build Coastguard Worker     glw::GLuint m_texture;
2986*35238bceSAndroid Build Coastguard Worker     glw::GLuint m_fbo;
2987*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_renderShader;
2988*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_samplerShader;
2989*35238bceSAndroid Build Coastguard Worker 
2990*35238bceSAndroid Build Coastguard Worker     glw::GLint m_samplerSamplerLoc;
2991*35238bceSAndroid Build Coastguard Worker     glw::GLint m_samplerLayerLoc;
2992*35238bceSAndroid Build Coastguard Worker 
2993*35238bceSAndroid Build Coastguard Worker     glw::GLenum m_provokingVertex;
2994*35238bceSAndroid Build Coastguard Worker };
2995*35238bceSAndroid Build Coastguard Worker 
LayeredRenderCase(Context & context,const char * name,const char * desc,LayeredRenderTargetType target,TestType test)2996*35238bceSAndroid Build Coastguard Worker LayeredRenderCase::LayeredRenderCase(Context &context, const char *name, const char *desc,
2997*35238bceSAndroid Build Coastguard Worker                                      LayeredRenderTargetType target, TestType test)
2998*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2999*35238bceSAndroid Build Coastguard Worker     , m_target(target)
3000*35238bceSAndroid Build Coastguard Worker     , m_test(test)
3001*35238bceSAndroid Build Coastguard Worker     , m_numLayers(getTargetLayers(target))
3002*35238bceSAndroid Build Coastguard Worker     , m_targetLayer(m_numLayers / 2)
3003*35238bceSAndroid Build Coastguard Worker     , m_resolveDimensions(getResolveDimensions(target))
3004*35238bceSAndroid Build Coastguard Worker     , m_iteration(0)
3005*35238bceSAndroid Build Coastguard Worker     , m_allLayersOk(true)
3006*35238bceSAndroid Build Coastguard Worker     , m_texture(0)
3007*35238bceSAndroid Build Coastguard Worker     , m_fbo(0)
3008*35238bceSAndroid Build Coastguard Worker     , m_renderShader(DE_NULL)
3009*35238bceSAndroid Build Coastguard Worker     , m_samplerShader(DE_NULL)
3010*35238bceSAndroid Build Coastguard Worker     , m_samplerSamplerLoc(-1)
3011*35238bceSAndroid Build Coastguard Worker     , m_samplerLayerLoc(-1)
3012*35238bceSAndroid Build Coastguard Worker     , m_provokingVertex(0)
3013*35238bceSAndroid Build Coastguard Worker {
3014*35238bceSAndroid Build Coastguard Worker }
3015*35238bceSAndroid Build Coastguard Worker 
~LayeredRenderCase(void)3016*35238bceSAndroid Build Coastguard Worker LayeredRenderCase::~LayeredRenderCase(void)
3017*35238bceSAndroid Build Coastguard Worker {
3018*35238bceSAndroid Build Coastguard Worker     deinit();
3019*35238bceSAndroid Build Coastguard Worker }
3020*35238bceSAndroid Build Coastguard Worker 
init(void)3021*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::init(void)
3022*35238bceSAndroid Build Coastguard Worker {
3023*35238bceSAndroid Build Coastguard Worker     // Requirements
3024*35238bceSAndroid Build Coastguard Worker 
3025*35238bceSAndroid Build Coastguard Worker     const bool supportES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
3026*35238bceSAndroid Build Coastguard Worker     const bool supportGL45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
3027*35238bceSAndroid Build Coastguard Worker 
3028*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
3029*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
3030*35238bceSAndroid Build Coastguard Worker 
3031*35238bceSAndroid Build Coastguard Worker     if (m_target == TARGET_2D_MS_ARRAY &&
3032*35238bceSAndroid Build Coastguard Worker         !(supportGL45 || (supportES32 && m_context.getContextInfo().isExtensionSupported(
3033*35238bceSAndroid Build Coastguard Worker                                              "GL_OES_texture_storage_multisample_2d_array"))))
3034*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError,
3035*35238bceSAndroid Build Coastguard Worker                   "Test requires OES_texture_storage_multisample_2d_array extension or higher context version.");
3036*35238bceSAndroid Build Coastguard Worker 
3037*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getWidth() < m_resolveDimensions.x() ||
3038*35238bceSAndroid Build Coastguard Worker         m_context.getRenderTarget().getHeight() < m_resolveDimensions.y())
3039*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Render target size must be at least " + de::toString(m_resolveDimensions.x()) +
3040*35238bceSAndroid Build Coastguard Worker                                      "x" + de::toString(m_resolveDimensions.y()));
3041*35238bceSAndroid Build Coastguard Worker 
3042*35238bceSAndroid Build Coastguard Worker     // log what the test tries to do
3043*35238bceSAndroid Build Coastguard Worker 
3044*35238bceSAndroid Build Coastguard Worker     if (m_test == TEST_DEFAULT_LAYER)
3045*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to the default layer." << tcu::TestLog::EndMessage;
3046*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_SINGLE_LAYER)
3047*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to a single layer." << tcu::TestLog::EndMessage;
3048*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_ALL_LAYERS)
3049*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to all layers." << tcu::TestLog::EndMessage;
3050*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_DIFFERENT_LAYERS)
3051*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Outputting different number of vertices to each layer."
3052*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
3053*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_INVOCATION_PER_LAYER)
3054*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Using a different invocation to output to each layer."
3055*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
3056*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_MULTIPLE_LAYERS_PER_INVOCATION)
3057*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Outputting to each layer from multiple invocations."
3058*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
3059*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_LAYER_ID)
3060*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Using gl_Layer in fragment shader." << tcu::TestLog::EndMessage;
3061*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_LAYER_PROVOKING_VERTEX)
3062*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying LAYER_PROVOKING_VERTEX." << tcu::TestLog::EndMessage;
3063*35238bceSAndroid Build Coastguard Worker     else
3064*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3065*35238bceSAndroid Build Coastguard Worker 
3066*35238bceSAndroid Build Coastguard Worker     // init resources
3067*35238bceSAndroid Build Coastguard Worker 
3068*35238bceSAndroid Build Coastguard Worker     initTexture();
3069*35238bceSAndroid Build Coastguard Worker     initFbo();
3070*35238bceSAndroid Build Coastguard Worker     initRenderShader();
3071*35238bceSAndroid Build Coastguard Worker     initSamplerShader();
3072*35238bceSAndroid Build Coastguard Worker }
3073*35238bceSAndroid Build Coastguard Worker 
deinit(void)3074*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::deinit(void)
3075*35238bceSAndroid Build Coastguard Worker {
3076*35238bceSAndroid Build Coastguard Worker     if (m_texture)
3077*35238bceSAndroid Build Coastguard Worker     {
3078*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture);
3079*35238bceSAndroid Build Coastguard Worker         m_texture = 0;
3080*35238bceSAndroid Build Coastguard Worker     }
3081*35238bceSAndroid Build Coastguard Worker 
3082*35238bceSAndroid Build Coastguard Worker     if (m_fbo)
3083*35238bceSAndroid Build Coastguard Worker     {
3084*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fbo);
3085*35238bceSAndroid Build Coastguard Worker         m_fbo = 0;
3086*35238bceSAndroid Build Coastguard Worker     }
3087*35238bceSAndroid Build Coastguard Worker 
3088*35238bceSAndroid Build Coastguard Worker     delete m_renderShader;
3089*35238bceSAndroid Build Coastguard Worker     delete m_samplerShader;
3090*35238bceSAndroid Build Coastguard Worker 
3091*35238bceSAndroid Build Coastguard Worker     m_renderShader  = DE_NULL;
3092*35238bceSAndroid Build Coastguard Worker     m_samplerShader = DE_NULL;
3093*35238bceSAndroid Build Coastguard Worker }
3094*35238bceSAndroid Build Coastguard Worker 
iterate(void)3095*35238bceSAndroid Build Coastguard Worker LayeredRenderCase::IterateResult LayeredRenderCase::iterate(void)
3096*35238bceSAndroid Build Coastguard Worker {
3097*35238bceSAndroid Build Coastguard Worker     ++m_iteration;
3098*35238bceSAndroid Build Coastguard Worker 
3099*35238bceSAndroid Build Coastguard Worker     if (m_iteration == 1)
3100*35238bceSAndroid Build Coastguard Worker     {
3101*35238bceSAndroid Build Coastguard Worker         if (m_test == TEST_LAYER_PROVOKING_VERTEX)
3102*35238bceSAndroid Build Coastguard Worker         {
3103*35238bceSAndroid Build Coastguard Worker             // which layer the implementation claims to render to
3104*35238bceSAndroid Build Coastguard Worker 
3105*35238bceSAndroid Build Coastguard Worker             gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> state;
3106*35238bceSAndroid Build Coastguard Worker 
3107*35238bceSAndroid Build Coastguard Worker             const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3108*35238bceSAndroid Build Coastguard Worker 
3109*35238bceSAndroid Build Coastguard Worker             gl.getIntegerv(GL_LAYER_PROVOKING_VERTEX, &state);
3110*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "getInteger(GL_LAYER_PROVOKING_VERTEX)");
3111*35238bceSAndroid Build Coastguard Worker 
3112*35238bceSAndroid Build Coastguard Worker             if (!state.verifyValidity(m_testCtx))
3113*35238bceSAndroid Build Coastguard Worker                 return STOP;
3114*35238bceSAndroid Build Coastguard Worker 
3115*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
3116*35238bceSAndroid Build Coastguard Worker                                << "GL_LAYER_PROVOKING_VERTEX = " << glu::getProvokingVertexStr(state)
3117*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
3118*35238bceSAndroid Build Coastguard Worker 
3119*35238bceSAndroid Build Coastguard Worker             bool ok = false;
3120*35238bceSAndroid Build Coastguard Worker             if (contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)))
3121*35238bceSAndroid Build Coastguard Worker             {
3122*35238bceSAndroid Build Coastguard Worker                 ok = state == GL_FIRST_VERTEX_CONVENTION || state == GL_LAST_VERTEX_CONVENTION ||
3123*35238bceSAndroid Build Coastguard Worker                      state == GL_PROVOKING_VERTEX || state == GL_UNDEFINED_VERTEX;
3124*35238bceSAndroid Build Coastguard Worker                 m_provokingVertex = (glw::GLenum)state;
3125*35238bceSAndroid Build Coastguard Worker 
3126*35238bceSAndroid Build Coastguard Worker                 if (state == GL_PROVOKING_VERTEX)
3127*35238bceSAndroid Build Coastguard Worker                 {
3128*35238bceSAndroid Build Coastguard Worker                     gl.getIntegerv(GL_PROVOKING_VERTEX, reinterpret_cast<glw::GLint *>(&m_provokingVertex));
3129*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "getInteger(GL_PROVOKING_VERTEX)");
3130*35238bceSAndroid Build Coastguard Worker                 }
3131*35238bceSAndroid Build Coastguard Worker             }
3132*35238bceSAndroid Build Coastguard Worker             else
3133*35238bceSAndroid Build Coastguard Worker             {
3134*35238bceSAndroid Build Coastguard Worker                 ok = state == GL_FIRST_VERTEX_CONVENTION || state == GL_LAST_VERTEX_CONVENTION ||
3135*35238bceSAndroid Build Coastguard Worker                      state == GL_UNDEFINED_VERTEX;
3136*35238bceSAndroid Build Coastguard Worker                 m_provokingVertex = (glw::GLenum)state;
3137*35238bceSAndroid Build Coastguard Worker             }
3138*35238bceSAndroid Build Coastguard Worker             if (!ok)
3139*35238bceSAndroid Build Coastguard Worker             {
3140*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
3141*35238bceSAndroid Build Coastguard Worker                                    << "getInteger(GL_LAYER_PROVOKING_VERTEX) returned illegal value. Got " << state
3142*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
3143*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected provoking vertex value");
3144*35238bceSAndroid Build Coastguard Worker                 return STOP;
3145*35238bceSAndroid Build Coastguard Worker             }
3146*35238bceSAndroid Build Coastguard Worker         }
3147*35238bceSAndroid Build Coastguard Worker 
3148*35238bceSAndroid Build Coastguard Worker         // render to texture
3149*35238bceSAndroid Build Coastguard Worker         {
3150*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "RenderToTexture", "Render to layered texture");
3151*35238bceSAndroid Build Coastguard Worker 
3152*35238bceSAndroid Build Coastguard Worker             // render to layered texture with the geometry shader
3153*35238bceSAndroid Build Coastguard Worker             renderToTexture();
3154*35238bceSAndroid Build Coastguard Worker         }
3155*35238bceSAndroid Build Coastguard Worker 
3156*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
3157*35238bceSAndroid Build Coastguard Worker     }
3158*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_LAYER_PROVOKING_VERTEX && m_provokingVertex == GL_UNDEFINED_VERTEX)
3159*35238bceSAndroid Build Coastguard Worker     {
3160*35238bceSAndroid Build Coastguard Worker         // Verification requires information from another layers, layers not independent
3161*35238bceSAndroid Build Coastguard Worker         {
3162*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "VerifyLayers", "Verify layers 0 and 1");
3163*35238bceSAndroid Build Coastguard Worker             tcu::Surface layer0(m_resolveDimensions.x(), m_resolveDimensions.y());
3164*35238bceSAndroid Build Coastguard Worker             tcu::Surface layer1(m_resolveDimensions.x(), m_resolveDimensions.y());
3165*35238bceSAndroid Build Coastguard Worker 
3166*35238bceSAndroid Build Coastguard Worker             // sample layer to frame buffer
3167*35238bceSAndroid Build Coastguard Worker             sampleTextureLayer(layer0, 0);
3168*35238bceSAndroid Build Coastguard Worker             sampleTextureLayer(layer1, 1);
3169*35238bceSAndroid Build Coastguard Worker 
3170*35238bceSAndroid Build Coastguard Worker             m_allLayersOk &= verifyProvokingVertexLayers(layer0, layer1);
3171*35238bceSAndroid Build Coastguard Worker         }
3172*35238bceSAndroid Build Coastguard Worker 
3173*35238bceSAndroid Build Coastguard Worker         // Other layers empty
3174*35238bceSAndroid Build Coastguard Worker         for (int layerNdx = 2; layerNdx < m_numLayers; ++layerNdx)
3175*35238bceSAndroid Build Coastguard Worker         {
3176*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "VerifyLayer",
3177*35238bceSAndroid Build Coastguard Worker                                                 "Verify layer " + de::toString(layerNdx));
3178*35238bceSAndroid Build Coastguard Worker             tcu::Surface layer(m_resolveDimensions.x(), m_resolveDimensions.y());
3179*35238bceSAndroid Build Coastguard Worker 
3180*35238bceSAndroid Build Coastguard Worker             // sample layer to frame buffer
3181*35238bceSAndroid Build Coastguard Worker             sampleTextureLayer(layer, layerNdx);
3182*35238bceSAndroid Build Coastguard Worker 
3183*35238bceSAndroid Build Coastguard Worker             // verify
3184*35238bceSAndroid Build Coastguard Worker             m_allLayersOk &= verifyEmptyImage(layer);
3185*35238bceSAndroid Build Coastguard Worker         }
3186*35238bceSAndroid Build Coastguard Worker     }
3187*35238bceSAndroid Build Coastguard Worker     else
3188*35238bceSAndroid Build Coastguard Worker     {
3189*35238bceSAndroid Build Coastguard Worker         // Layers independent
3190*35238bceSAndroid Build Coastguard Worker 
3191*35238bceSAndroid Build Coastguard Worker         const int layerNdx = m_iteration - 2;
3192*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "VerifyLayer",
3193*35238bceSAndroid Build Coastguard Worker                                             "Verify layer " + de::toString(layerNdx));
3194*35238bceSAndroid Build Coastguard Worker         tcu::Surface layer(m_resolveDimensions.x(), m_resolveDimensions.y());
3195*35238bceSAndroid Build Coastguard Worker 
3196*35238bceSAndroid Build Coastguard Worker         // sample layer to frame buffer
3197*35238bceSAndroid Build Coastguard Worker         sampleTextureLayer(layer, layerNdx);
3198*35238bceSAndroid Build Coastguard Worker 
3199*35238bceSAndroid Build Coastguard Worker         // verify
3200*35238bceSAndroid Build Coastguard Worker         m_allLayersOk &= verifyLayerContent(layer, layerNdx);
3201*35238bceSAndroid Build Coastguard Worker 
3202*35238bceSAndroid Build Coastguard Worker         if (layerNdx < m_numLayers - 1)
3203*35238bceSAndroid Build Coastguard Worker             return CONTINUE;
3204*35238bceSAndroid Build Coastguard Worker     }
3205*35238bceSAndroid Build Coastguard Worker 
3206*35238bceSAndroid Build Coastguard Worker     // last iteration
3207*35238bceSAndroid Build Coastguard Worker     if (m_allLayersOk)
3208*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3209*35238bceSAndroid Build Coastguard Worker     else
3210*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Detected invalid layer content");
3211*35238bceSAndroid Build Coastguard Worker 
3212*35238bceSAndroid Build Coastguard Worker     return STOP;
3213*35238bceSAndroid Build Coastguard Worker }
3214*35238bceSAndroid Build Coastguard Worker 
initTexture(void)3215*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::initTexture(void)
3216*35238bceSAndroid Build Coastguard Worker {
3217*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_texture);
3218*35238bceSAndroid Build Coastguard Worker 
3219*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl                 = m_context.getRenderContext().getFunctions();
3220*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 texSize                 = getTargetDimensions(m_target);
3221*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormat texFormat       = glu::mapGLInternalFormat(GL_RGBA8);
3222*35238bceSAndroid Build Coastguard Worker     const glu::TransferFormat transferFormat = glu::getTransferFormat(texFormat);
3223*35238bceSAndroid Build Coastguard Worker 
3224*35238bceSAndroid Build Coastguard Worker     gl.genTextures(1, &m_texture);
3225*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "gen texture");
3226*35238bceSAndroid Build Coastguard Worker 
3227*35238bceSAndroid Build Coastguard Worker     switch (m_target)
3228*35238bceSAndroid Build Coastguard Worker     {
3229*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
3230*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating cubemap texture, size = " << texSize.x() << "x"
3231*35238bceSAndroid Build Coastguard Worker                            << texSize.y() << tcu::TestLog::EndMessage;
3232*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
3233*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3234*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3235*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3236*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3237*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3238*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3239*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3240*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3241*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3242*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3243*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3244*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3245*35238bceSAndroid Build Coastguard Worker         break;
3246*35238bceSAndroid Build Coastguard Worker 
3247*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
3248*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating 3d texture, size = " << texSize.x() << "x"
3249*35238bceSAndroid Build Coastguard Worker                            << texSize.y() << "x" << texSize.z() << tcu::TestLog::EndMessage;
3250*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_3D, m_texture);
3251*35238bceSAndroid Build Coastguard Worker         gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, texSize.x(), texSize.y(), texSize.z(), 0, transferFormat.format,
3252*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3253*35238bceSAndroid Build Coastguard Worker         break;
3254*35238bceSAndroid Build Coastguard Worker 
3255*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
3256*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating 1d texture array, size = " << texSize.x()
3257*35238bceSAndroid Build Coastguard Worker                            << ", layers = " << texSize.y() << tcu::TestLog::EndMessage;
3258*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_1D_ARRAY, m_texture);
3259*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, texSize.x(), texSize.y(), 0, transferFormat.format,
3260*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3261*35238bceSAndroid Build Coastguard Worker         break;
3262*35238bceSAndroid Build Coastguard Worker 
3263*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
3264*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating 2d texture array, size = " << texSize.x() << "x"
3265*35238bceSAndroid Build Coastguard Worker                            << texSize.y() << ", layers = " << texSize.z() << tcu::TestLog::EndMessage;
3266*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
3267*35238bceSAndroid Build Coastguard Worker         gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, texSize.x(), texSize.y(), texSize.z(), 0, transferFormat.format,
3268*35238bceSAndroid Build Coastguard Worker                       transferFormat.dataType, DE_NULL);
3269*35238bceSAndroid Build Coastguard Worker         break;
3270*35238bceSAndroid Build Coastguard Worker 
3271*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
3272*35238bceSAndroid Build Coastguard Worker     {
3273*35238bceSAndroid Build Coastguard Worker         const int numSamples = 2;
3274*35238bceSAndroid Build Coastguard Worker 
3275*35238bceSAndroid Build Coastguard Worker         int maxSamples = 0;
3276*35238bceSAndroid Build Coastguard Worker         gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxSamples);
3277*35238bceSAndroid Build Coastguard Worker 
3278*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating 2d multisample texture array, size = " << texSize.x()
3279*35238bceSAndroid Build Coastguard Worker                            << "x" << texSize.y() << ", layers = " << texSize.z() << ", samples = " << numSamples
3280*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
3281*35238bceSAndroid Build Coastguard Worker 
3282*35238bceSAndroid Build Coastguard Worker         if (numSamples > maxSamples)
3283*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Test requires " + de::toString(numSamples) + " color texture samples.");
3284*35238bceSAndroid Build Coastguard Worker 
3285*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, m_texture);
3286*35238bceSAndroid Build Coastguard Worker         gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, numSamples, GL_RGBA8, texSize.x(), texSize.y(),
3287*35238bceSAndroid Build Coastguard Worker                                    texSize.z(), GL_TRUE);
3288*35238bceSAndroid Build Coastguard Worker         break;
3289*35238bceSAndroid Build Coastguard Worker     }
3290*35238bceSAndroid Build Coastguard Worker 
3291*35238bceSAndroid Build Coastguard Worker     default:
3292*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3293*35238bceSAndroid Build Coastguard Worker     }
3294*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "tex image");
3295*35238bceSAndroid Build Coastguard Worker 
3296*35238bceSAndroid Build Coastguard Worker     // Multisample textures don't use filters
3297*35238bceSAndroid Build Coastguard Worker     if (getTargetTextureTarget(m_target) != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
3298*35238bceSAndroid Build Coastguard Worker     {
3299*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(getTargetTextureTarget(m_target), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3300*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(getTargetTextureTarget(m_target), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3301*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(getTargetTextureTarget(m_target), GL_TEXTURE_WRAP_S, GL_REPEAT);
3302*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(getTargetTextureTarget(m_target), GL_TEXTURE_WRAP_T, GL_REPEAT);
3303*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(getTargetTextureTarget(m_target), GL_TEXTURE_WRAP_R, GL_REPEAT);
3304*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "tex filter");
3305*35238bceSAndroid Build Coastguard Worker     }
3306*35238bceSAndroid Build Coastguard Worker }
3307*35238bceSAndroid Build Coastguard Worker 
initFbo(void)3308*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::initFbo(void)
3309*35238bceSAndroid Build Coastguard Worker {
3310*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_fbo);
3311*35238bceSAndroid Build Coastguard Worker 
3312*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3313*35238bceSAndroid Build Coastguard Worker 
3314*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Creating FBO" << tcu::TestLog::EndMessage;
3315*35238bceSAndroid Build Coastguard Worker 
3316*35238bceSAndroid Build Coastguard Worker     gl.genFramebuffers(1, &m_fbo);
3317*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
3318*35238bceSAndroid Build Coastguard Worker     gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0);
3319*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3320*35238bceSAndroid Build Coastguard Worker 
3321*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "setup fbo");
3322*35238bceSAndroid Build Coastguard Worker }
3323*35238bceSAndroid Build Coastguard Worker 
initRenderShader(void)3324*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::initRenderShader(void)
3325*35238bceSAndroid Build Coastguard Worker {
3326*35238bceSAndroid Build Coastguard Worker     const tcu::ScopedLogSection section(m_testCtx.getLog(), "RenderToTextureShader",
3327*35238bceSAndroid Build Coastguard Worker                                         "Create layered rendering shader program");
3328*35238bceSAndroid Build Coastguard Worker 
3329*35238bceSAndroid Build Coastguard Worker     static const char *const positionVertex = "${GLSL_VERSION_DECL}\n"
3330*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
3331*35238bceSAndroid Build Coastguard Worker                                               "{\n"
3332*35238bceSAndroid Build Coastguard Worker                                               "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
3333*35238bceSAndroid Build Coastguard Worker                                               "}\n";
3334*35238bceSAndroid Build Coastguard Worker 
3335*35238bceSAndroid Build Coastguard Worker     m_renderShader = new glu::ShaderProgram(
3336*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext(),
3337*35238bceSAndroid Build Coastguard Worker         glu::ProgramSources() << glu::VertexSource(
3338*35238bceSAndroid Build Coastguard Worker                                      specializeShader(positionVertex, m_context.getRenderContext().getType()))
3339*35238bceSAndroid Build Coastguard Worker                               << glu::FragmentSource(genFragmentSource(m_context.getRenderContext().getType()))
3340*35238bceSAndroid Build Coastguard Worker                               << glu::GeometrySource(genGeometrySource(m_context.getRenderContext().getType())));
3341*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_renderShader;
3342*35238bceSAndroid Build Coastguard Worker 
3343*35238bceSAndroid Build Coastguard Worker     if (!m_renderShader->isOk())
3344*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("failed to build render shader");
3345*35238bceSAndroid Build Coastguard Worker }
3346*35238bceSAndroid Build Coastguard Worker 
initSamplerShader(void)3347*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::initSamplerShader(void)
3348*35238bceSAndroid Build Coastguard Worker {
3349*35238bceSAndroid Build Coastguard Worker     const tcu::ScopedLogSection section(m_testCtx.getLog(), "TextureSamplerShader", "Create shader sampler program");
3350*35238bceSAndroid Build Coastguard Worker 
3351*35238bceSAndroid Build Coastguard Worker     static const char *const positionVertex = "${GLSL_VERSION_DECL}\n"
3352*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_position;\n"
3353*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
3354*35238bceSAndroid Build Coastguard Worker                                               "{\n"
3355*35238bceSAndroid Build Coastguard Worker                                               "    gl_Position = a_position;\n"
3356*35238bceSAndroid Build Coastguard Worker                                               "}\n";
3357*35238bceSAndroid Build Coastguard Worker 
3358*35238bceSAndroid Build Coastguard Worker     m_samplerShader = new glu::ShaderProgram(
3359*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext(),
3360*35238bceSAndroid Build Coastguard Worker         glu::ProgramSources() << glu::VertexSource(
3361*35238bceSAndroid Build Coastguard Worker                                      specializeShader(positionVertex, m_context.getRenderContext().getType()))
3362*35238bceSAndroid Build Coastguard Worker                               << glu::FragmentSource(genSamplerFragmentSource(m_context.getRenderContext().getType())));
3363*35238bceSAndroid Build Coastguard Worker 
3364*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_samplerShader;
3365*35238bceSAndroid Build Coastguard Worker 
3366*35238bceSAndroid Build Coastguard Worker     if (!m_samplerShader->isOk())
3367*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("failed to build sampler shader");
3368*35238bceSAndroid Build Coastguard Worker 
3369*35238bceSAndroid Build Coastguard Worker     m_samplerSamplerLoc =
3370*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getUniformLocation(m_samplerShader->getProgram(), "u_sampler");
3371*35238bceSAndroid Build Coastguard Worker     if (m_samplerSamplerLoc == -1)
3372*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("u_sampler uniform location = -1");
3373*35238bceSAndroid Build Coastguard Worker 
3374*35238bceSAndroid Build Coastguard Worker     m_samplerLayerLoc =
3375*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getUniformLocation(m_samplerShader->getProgram(), "u_layer");
3376*35238bceSAndroid Build Coastguard Worker     if (m_samplerLayerLoc == -1)
3377*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("u_layer uniform location = -1");
3378*35238bceSAndroid Build Coastguard Worker }
3379*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(const glu::ContextType & contextType) const3380*35238bceSAndroid Build Coastguard Worker std::string LayeredRenderCase::genFragmentSource(const glu::ContextType &contextType) const
3381*35238bceSAndroid Build Coastguard Worker {
3382*35238bceSAndroid Build Coastguard Worker     static const char *const fragmentLayerIdShader = "${GLSL_VERSION_DECL}\n"
3383*35238bceSAndroid Build Coastguard Worker                                                      "${GLSL_EXT_GEOMETRY_SHADER}"
3384*35238bceSAndroid Build Coastguard Worker                                                      "layout(location = 0) out mediump vec4 fragColor;\n"
3385*35238bceSAndroid Build Coastguard Worker                                                      "void main (void)\n"
3386*35238bceSAndroid Build Coastguard Worker                                                      "{\n"
3387*35238bceSAndroid Build Coastguard Worker                                                      "    fragColor = vec4(((gl_Layer % 2) == 1) ? 1.0 : 0.5,\n"
3388*35238bceSAndroid Build Coastguard Worker                                                      "                     (((gl_Layer / 2) % 2) == 1) ? 1.0 : 0.5,\n"
3389*35238bceSAndroid Build Coastguard Worker                                                      "                     (gl_Layer == 0) ? 1.0 : 0.0,\n"
3390*35238bceSAndroid Build Coastguard Worker                                                      "                     1.0);\n"
3391*35238bceSAndroid Build Coastguard Worker                                                      "}\n";
3392*35238bceSAndroid Build Coastguard Worker 
3393*35238bceSAndroid Build Coastguard Worker     if (m_test != TEST_LAYER_ID)
3394*35238bceSAndroid Build Coastguard Worker         return specializeShader(s_commonShaderSourceFragment, contextType);
3395*35238bceSAndroid Build Coastguard Worker     else
3396*35238bceSAndroid Build Coastguard Worker         return specializeShader(fragmentLayerIdShader, contextType);
3397*35238bceSAndroid Build Coastguard Worker }
3398*35238bceSAndroid Build Coastguard Worker 
genGeometrySource(const glu::ContextType & contextType) const3399*35238bceSAndroid Build Coastguard Worker std::string LayeredRenderCase::genGeometrySource(const glu::ContextType &contextType) const
3400*35238bceSAndroid Build Coastguard Worker {
3401*35238bceSAndroid Build Coastguard Worker     // TEST_DIFFERENT_LAYERS: draw 0 quad to first layer, 1 to second, etc.
3402*35238bceSAndroid Build Coastguard Worker     // TEST_ALL_LAYERS: draw 1 quad to all layers
3403*35238bceSAndroid Build Coastguard Worker     // TEST_MULTIPLE_LAYERS_PER_INVOCATION: draw 1 triangle to "current layer" and 1 triangle to another layer
3404*35238bceSAndroid Build Coastguard Worker     // else: draw 1 quad to some single layer
3405*35238bceSAndroid Build Coastguard Worker     const int maxVertices = (m_test == TEST_DIFFERENT_LAYERS) ? ((2 + m_numLayers - 1) * m_numLayers) :
3406*35238bceSAndroid Build Coastguard Worker                             (m_test == TEST_ALL_LAYERS || m_test == TEST_LAYER_ID) ? (m_numLayers * 4) :
3407*35238bceSAndroid Build Coastguard Worker                             (m_test == TEST_MULTIPLE_LAYERS_PER_INVOCATION)        ? (6) :
3408*35238bceSAndroid Build Coastguard Worker                             (m_test == TEST_LAYER_PROVOKING_VERTEX)                ? (6) :
3409*35238bceSAndroid Build Coastguard Worker                                                                                      (4);
3410*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
3411*35238bceSAndroid Build Coastguard Worker 
3412*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n"
3413*35238bceSAndroid Build Coastguard Worker            "${GLSL_EXT_GEOMETRY_SHADER}";
3414*35238bceSAndroid Build Coastguard Worker 
3415*35238bceSAndroid Build Coastguard Worker     if (m_test == TEST_INVOCATION_PER_LAYER || m_test == TEST_MULTIPLE_LAYERS_PER_INVOCATION)
3416*35238bceSAndroid Build Coastguard Worker         buf << "layout(points, invocations=" << m_numLayers << ") in;\n";
3417*35238bceSAndroid Build Coastguard Worker     else
3418*35238bceSAndroid Build Coastguard Worker         buf << "layout(points) in;\n";
3419*35238bceSAndroid Build Coastguard Worker 
3420*35238bceSAndroid Build Coastguard Worker     buf << "layout(triangle_strip, max_vertices = " << maxVertices
3421*35238bceSAndroid Build Coastguard Worker         << ") out;\n"
3422*35238bceSAndroid Build Coastguard Worker            "out highp vec4 v_frag_FragColor;\n"
3423*35238bceSAndroid Build Coastguard Worker            "\n"
3424*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
3425*35238bceSAndroid Build Coastguard Worker            "{\n";
3426*35238bceSAndroid Build Coastguard Worker 
3427*35238bceSAndroid Build Coastguard Worker     if (m_test == TEST_DEFAULT_LAYER)
3428*35238bceSAndroid Build Coastguard Worker     {
3429*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white = vec4(1.0, 1.0, 1.0, 1.0);\n\n"
3430*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3431*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3432*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3433*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3434*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3435*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3436*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3437*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3438*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3439*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
3440*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3441*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
3442*35238bceSAndroid Build Coastguard Worker     }
3443*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_SINGLE_LAYER)
3444*35238bceSAndroid Build Coastguard Worker     {
3445*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white = vec4(1.0, 1.0, 1.0, 1.0);\n\n"
3446*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3447*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = "
3448*35238bceSAndroid Build Coastguard Worker             << m_targetLayer
3449*35238bceSAndroid Build Coastguard Worker             << ";\n"
3450*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3451*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3452*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3453*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = "
3454*35238bceSAndroid Build Coastguard Worker             << m_targetLayer
3455*35238bceSAndroid Build Coastguard Worker             << ";\n"
3456*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3457*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3458*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3459*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = "
3460*35238bceSAndroid Build Coastguard Worker             << m_targetLayer
3461*35238bceSAndroid Build Coastguard Worker             << ";\n"
3462*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3463*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3464*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
3465*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = "
3466*35238bceSAndroid Build Coastguard Worker             << m_targetLayer
3467*35238bceSAndroid Build Coastguard Worker             << ";\n"
3468*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3469*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
3470*35238bceSAndroid Build Coastguard Worker     }
3471*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_ALL_LAYERS || m_test == TEST_LAYER_ID)
3472*35238bceSAndroid Build Coastguard Worker     {
3473*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numLayers <= 6);
3474*35238bceSAndroid Build Coastguard Worker 
3475*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white   = vec4(1.0, 1.0, 1.0, 1.0);\n"
3476*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 red     = vec4(1.0, 0.0, 0.0, 1.0);\n"
3477*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 green   = vec4(0.0, 1.0, 0.0, 1.0);\n"
3478*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 blue    = vec4(0.0, 0.0, 1.0, 1.0);\n"
3479*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 yellow  = vec4(1.0, 1.0, 0.0, 1.0);\n"
3480*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 magenta = vec4(1.0, 0.0, 1.0, 1.0);\n"
3481*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 colors[6] = vec4[6](white, red, green, blue, yellow, magenta);\n\n"
3482*35238bceSAndroid Build Coastguard Worker                "    for (mediump int layerNdx = 0; layerNdx < "
3483*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3484*35238bceSAndroid Build Coastguard Worker             << "; ++layerNdx)\n"
3485*35238bceSAndroid Build Coastguard Worker                "    {\n"
3486*35238bceSAndroid Build Coastguard Worker                "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3487*35238bceSAndroid Build Coastguard Worker                "        gl_Layer = layerNdx;\n"
3488*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = colors[layerNdx];\n"
3489*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n\n"
3490*35238bceSAndroid Build Coastguard Worker                "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3491*35238bceSAndroid Build Coastguard Worker                "        gl_Layer = layerNdx;\n"
3492*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = colors[layerNdx];\n"
3493*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n\n"
3494*35238bceSAndroid Build Coastguard Worker                "        gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3495*35238bceSAndroid Build Coastguard Worker                "        gl_Layer = layerNdx;\n"
3496*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = colors[layerNdx];\n"
3497*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n\n"
3498*35238bceSAndroid Build Coastguard Worker                "        gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
3499*35238bceSAndroid Build Coastguard Worker                "        gl_Layer = layerNdx;\n"
3500*35238bceSAndroid Build Coastguard Worker                "        v_frag_FragColor = colors[layerNdx];\n"
3501*35238bceSAndroid Build Coastguard Worker                "        EmitVertex();\n"
3502*35238bceSAndroid Build Coastguard Worker                "        EndPrimitive();\n"
3503*35238bceSAndroid Build Coastguard Worker                "    }\n";
3504*35238bceSAndroid Build Coastguard Worker     }
3505*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_DIFFERENT_LAYERS)
3506*35238bceSAndroid Build Coastguard Worker     {
3507*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numLayers <= 6);
3508*35238bceSAndroid Build Coastguard Worker 
3509*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white = vec4(1.0, 1.0, 1.0, 1.0);\n\n"
3510*35238bceSAndroid Build Coastguard Worker                "    for (mediump int layerNdx = 0; layerNdx < "
3511*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3512*35238bceSAndroid Build Coastguard Worker             << "; ++layerNdx)\n"
3513*35238bceSAndroid Build Coastguard Worker                "    {\n"
3514*35238bceSAndroid Build Coastguard Worker                "        for (mediump int colNdx = 0; colNdx <= layerNdx; ++colNdx)\n"
3515*35238bceSAndroid Build Coastguard Worker                "        {\n"
3516*35238bceSAndroid Build Coastguard Worker                "            highp float posX = float(colNdx) / float("
3517*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3518*35238bceSAndroid Build Coastguard Worker             << ") * 2.0 - 1.0;\n\n"
3519*35238bceSAndroid Build Coastguard Worker                "            gl_Position = vec4(posX,  1.0, 0.0, 1.0);\n"
3520*35238bceSAndroid Build Coastguard Worker                "            gl_Layer = layerNdx;\n"
3521*35238bceSAndroid Build Coastguard Worker                "            v_frag_FragColor = white;\n"
3522*35238bceSAndroid Build Coastguard Worker                "            EmitVertex();\n\n"
3523*35238bceSAndroid Build Coastguard Worker                "            gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n"
3524*35238bceSAndroid Build Coastguard Worker                "            gl_Layer = layerNdx;\n"
3525*35238bceSAndroid Build Coastguard Worker                "            v_frag_FragColor = white;\n"
3526*35238bceSAndroid Build Coastguard Worker                "            EmitVertex();\n"
3527*35238bceSAndroid Build Coastguard Worker                "        }\n"
3528*35238bceSAndroid Build Coastguard Worker                "        EndPrimitive();\n"
3529*35238bceSAndroid Build Coastguard Worker                "    }\n";
3530*35238bceSAndroid Build Coastguard Worker     }
3531*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_INVOCATION_PER_LAYER)
3532*35238bceSAndroid Build Coastguard Worker     {
3533*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white   = vec4(1.0, 1.0, 1.0, 1.0);\n"
3534*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 red     = vec4(1.0, 0.0, 0.0, 1.0);\n"
3535*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 green   = vec4(0.0, 1.0, 0.0, 1.0);\n"
3536*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 blue    = vec4(0.0, 0.0, 1.0, 1.0);\n"
3537*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 yellow  = vec4(1.0, 1.0, 0.0, 1.0);\n"
3538*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 magenta = vec4(1.0, 0.0, 1.0, 1.0);\n"
3539*35238bceSAndroid Build Coastguard Worker                "    const highp vec4 colors[6] = vec4[6](white, red, green, blue, yellow, magenta);\n"
3540*35238bceSAndroid Build Coastguard Worker                "\n"
3541*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3542*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = gl_InvocationID;\n"
3543*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_InvocationID];\n"
3544*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3545*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3546*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = gl_InvocationID;\n"
3547*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_InvocationID];\n"
3548*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3549*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3550*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = gl_InvocationID;\n"
3551*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_InvocationID];\n"
3552*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3553*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
3554*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = gl_InvocationID;\n"
3555*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = colors[gl_InvocationID];\n"
3556*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n"
3557*35238bceSAndroid Build Coastguard Worker                "    EndPrimitive();\n";
3558*35238bceSAndroid Build Coastguard Worker     }
3559*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_MULTIPLE_LAYERS_PER_INVOCATION)
3560*35238bceSAndroid Build Coastguard Worker     {
3561*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white = vec4(1.0, 1.0, 1.0, 1.0);\n"
3562*35238bceSAndroid Build Coastguard Worker                "\n"
3563*35238bceSAndroid Build Coastguard Worker                "    mediump int layerA = gl_InvocationID;\n"
3564*35238bceSAndroid Build Coastguard Worker                "    mediump int layerB = (gl_InvocationID + 1) % "
3565*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3566*35238bceSAndroid Build Coastguard Worker             << ";\n"
3567*35238bceSAndroid Build Coastguard Worker                "    highp float aEnd = float(layerA) / float("
3568*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3569*35238bceSAndroid Build Coastguard Worker             << ") * 2.0 - 1.0;\n"
3570*35238bceSAndroid Build Coastguard Worker                "    highp float bEnd = float(layerB) / float("
3571*35238bceSAndroid Build Coastguard Worker             << m_numLayers
3572*35238bceSAndroid Build Coastguard Worker             << ") * 2.0 - 1.0;\n"
3573*35238bceSAndroid Build Coastguard Worker                "\n"
3574*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3575*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerA;\n"
3576*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3577*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3578*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3579*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerA;\n"
3580*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3581*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3582*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n"
3583*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerA;\n"
3584*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3585*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3586*35238bceSAndroid Build Coastguard Worker                "    EndPrimitive();\n"
3587*35238bceSAndroid Build Coastguard Worker                "\n"
3588*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3589*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerB;\n"
3590*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3591*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3592*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(bEnd,  1.0, 0.0, 1.0);\n"
3593*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerB;\n"
3594*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3595*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3596*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n"
3597*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = layerB;\n"
3598*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3599*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3600*35238bceSAndroid Build Coastguard Worker                "    EndPrimitive();\n";
3601*35238bceSAndroid Build Coastguard Worker     }
3602*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_LAYER_PROVOKING_VERTEX)
3603*35238bceSAndroid Build Coastguard Worker     {
3604*35238bceSAndroid Build Coastguard Worker         buf << "    const highp vec4 white = vec4(1.0, 1.0, 1.0, 1.0);\n\n"
3605*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
3606*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 0;\n"
3607*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3608*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3609*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3610*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 1;\n"
3611*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3612*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3613*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3614*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 1;\n"
3615*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3616*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3617*35238bceSAndroid Build Coastguard Worker                "    EndPrimitive();\n\n"
3618*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
3619*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 0;\n"
3620*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3621*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3622*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
3623*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 1;\n"
3624*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3625*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n\n"
3626*35238bceSAndroid Build Coastguard Worker                "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
3627*35238bceSAndroid Build Coastguard Worker                "    gl_Layer = 1;\n"
3628*35238bceSAndroid Build Coastguard Worker                "    v_frag_FragColor = white;\n"
3629*35238bceSAndroid Build Coastguard Worker                "    EmitVertex();\n";
3630*35238bceSAndroid Build Coastguard Worker     }
3631*35238bceSAndroid Build Coastguard Worker     else
3632*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3633*35238bceSAndroid Build Coastguard Worker 
3634*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
3635*35238bceSAndroid Build Coastguard Worker 
3636*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
3637*35238bceSAndroid Build Coastguard Worker }
3638*35238bceSAndroid Build Coastguard Worker 
genSamplerFragmentSource(const glu::ContextType & contextType) const3639*35238bceSAndroid Build Coastguard Worker std::string LayeredRenderCase::genSamplerFragmentSource(const glu::ContextType &contextType) const
3640*35238bceSAndroid Build Coastguard Worker {
3641*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
3642*35238bceSAndroid Build Coastguard Worker 
3643*35238bceSAndroid Build Coastguard Worker     buf << "${GLSL_VERSION_DECL}\n";
3644*35238bceSAndroid Build Coastguard Worker     if (m_target == TARGET_2D_MS_ARRAY)
3645*35238bceSAndroid Build Coastguard Worker         buf << "${GLSL_OES_TEXTURE_STORAGE_MULTISAMPLE}";
3646*35238bceSAndroid Build Coastguard Worker     buf << "layout(location = 0) out mediump vec4 fragColor;\n";
3647*35238bceSAndroid Build Coastguard Worker 
3648*35238bceSAndroid Build Coastguard Worker     switch (m_target)
3649*35238bceSAndroid Build Coastguard Worker     {
3650*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
3651*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp samplerCube u_sampler;\n";
3652*35238bceSAndroid Build Coastguard Worker         break;
3653*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
3654*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp sampler3D u_sampler;\n";
3655*35238bceSAndroid Build Coastguard Worker         break;
3656*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
3657*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp sampler2DArray u_sampler;\n";
3658*35238bceSAndroid Build Coastguard Worker         break;
3659*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
3660*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp sampler1DArray u_sampler;\n";
3661*35238bceSAndroid Build Coastguard Worker         break;
3662*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
3663*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp sampler2DMSArray u_sampler;\n";
3664*35238bceSAndroid Build Coastguard Worker         break;
3665*35238bceSAndroid Build Coastguard Worker     default:
3666*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3667*35238bceSAndroid Build Coastguard Worker     }
3668*35238bceSAndroid Build Coastguard Worker 
3669*35238bceSAndroid Build Coastguard Worker     buf << "uniform highp int u_layer;\n"
3670*35238bceSAndroid Build Coastguard Worker            "void main (void)\n"
3671*35238bceSAndroid Build Coastguard Worker            "{\n";
3672*35238bceSAndroid Build Coastguard Worker 
3673*35238bceSAndroid Build Coastguard Worker     switch (m_target)
3674*35238bceSAndroid Build Coastguard Worker     {
3675*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
3676*35238bceSAndroid Build Coastguard Worker         buf << "    highp vec2 facepos = 2.0 * gl_FragCoord.xy / vec2(ivec2(" << m_resolveDimensions.x() << ", "
3677*35238bceSAndroid Build Coastguard Worker             << m_resolveDimensions.y()
3678*35238bceSAndroid Build Coastguard Worker             << ")) - vec2(1.0, 1.0);\n"
3679*35238bceSAndroid Build Coastguard Worker                "    if (u_layer == 0)\n"
3680*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(1.0, -facepos.y, -facepos.x), 0.0);\n"
3681*35238bceSAndroid Build Coastguard Worker                "    else if (u_layer == 1)\n"
3682*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(-1.0, -facepos.y, facepos.x), 0.0);\n"
3683*35238bceSAndroid Build Coastguard Worker                "    else if (u_layer == 2)\n"
3684*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(facepos.x, 1.0, facepos.y), 0.0);\n"
3685*35238bceSAndroid Build Coastguard Worker                "    else if (u_layer == 3)\n"
3686*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(facepos.x, -1.0, -facepos.y), 0.0);\n"
3687*35238bceSAndroid Build Coastguard Worker                "    else if (u_layer == 4)\n"
3688*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(facepos.x, -facepos.y, 1.0), 0.0);\n"
3689*35238bceSAndroid Build Coastguard Worker                "    else if (u_layer == 5)\n"
3690*35238bceSAndroid Build Coastguard Worker                "        fragColor = textureLod(u_sampler, vec3(-facepos.x, -facepos.y, -1.0), 0.0);\n"
3691*35238bceSAndroid Build Coastguard Worker                "    else\n"
3692*35238bceSAndroid Build Coastguard Worker                "        fragColor = vec4(1.0, 0.0, 1.0, 1.0);\n";
3693*35238bceSAndroid Build Coastguard Worker         break;
3694*35238bceSAndroid Build Coastguard Worker 
3695*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
3696*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
3697*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
3698*35238bceSAndroid Build Coastguard Worker         buf << "    highp ivec2 screenpos = ivec2(floor(gl_FragCoord.xy));\n"
3699*35238bceSAndroid Build Coastguard Worker                "    fragColor = texelFetch(u_sampler, ivec3(screenpos, u_layer), 0);\n";
3700*35238bceSAndroid Build Coastguard Worker         break;
3701*35238bceSAndroid Build Coastguard Worker 
3702*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
3703*35238bceSAndroid Build Coastguard Worker         buf << "    highp ivec2 screenpos = ivec2(floor(gl_FragCoord.xy));\n"
3704*35238bceSAndroid Build Coastguard Worker                "    fragColor = texelFetch(u_sampler, ivec2(screenpos.x, u_layer), 0);\n";
3705*35238bceSAndroid Build Coastguard Worker         break;
3706*35238bceSAndroid Build Coastguard Worker 
3707*35238bceSAndroid Build Coastguard Worker     default:
3708*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3709*35238bceSAndroid Build Coastguard Worker     }
3710*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
3711*35238bceSAndroid Build Coastguard Worker     return specializeShader(buf.str(), contextType);
3712*35238bceSAndroid Build Coastguard Worker }
3713*35238bceSAndroid Build Coastguard Worker 
renderToTexture(void)3714*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::renderToTexture(void)
3715*35238bceSAndroid Build Coastguard Worker {
3716*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 texSize = getTargetDimensions(m_target);
3717*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3718*35238bceSAndroid Build Coastguard Worker     glu::VertexArray vao(m_context.getRenderContext());
3719*35238bceSAndroid Build Coastguard Worker 
3720*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to texture" << tcu::TestLog::EndMessage;
3721*35238bceSAndroid Build Coastguard Worker 
3722*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
3723*35238bceSAndroid Build Coastguard Worker     gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3724*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
3725*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, texSize.x(), texSize.y());
3726*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
3727*35238bceSAndroid Build Coastguard Worker 
3728*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(*vao);
3729*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_renderShader->getProgram());
3730*35238bceSAndroid Build Coastguard Worker     gl.drawArrays(GL_POINTS, 0, 1);
3731*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
3732*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(0);
3733*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3734*35238bceSAndroid Build Coastguard Worker 
3735*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "render");
3736*35238bceSAndroid Build Coastguard Worker }
3737*35238bceSAndroid Build Coastguard Worker 
sampleTextureLayer(tcu::Surface & dst,int layer)3738*35238bceSAndroid Build Coastguard Worker void LayeredRenderCase::sampleTextureLayer(tcu::Surface &dst, int layer)
3739*35238bceSAndroid Build Coastguard Worker {
3740*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getWidth() == m_resolveDimensions.x());
3741*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getHeight() == m_resolveDimensions.y());
3742*35238bceSAndroid Build Coastguard Worker 
3743*35238bceSAndroid Build Coastguard Worker     static const tcu::Vec4 fullscreenQuad[4] = {
3744*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
3745*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
3746*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
3747*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
3748*35238bceSAndroid Build Coastguard Worker     };
3749*35238bceSAndroid Build Coastguard Worker 
3750*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3751*35238bceSAndroid Build Coastguard Worker     const int positionLoc    = gl.getAttribLocation(m_samplerShader->getProgram(), "a_position");
3752*35238bceSAndroid Build Coastguard Worker     glu::VertexArray vao(m_context.getRenderContext());
3753*35238bceSAndroid Build Coastguard Worker     glu::Buffer buf(m_context.getRenderContext());
3754*35238bceSAndroid Build Coastguard Worker 
3755*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Sampling from texture layer " << layer << tcu::TestLog::EndMessage;
3756*35238bceSAndroid Build Coastguard Worker 
3757*35238bceSAndroid Build Coastguard Worker     gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3758*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
3759*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, m_resolveDimensions.x(), m_resolveDimensions.y());
3760*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
3761*35238bceSAndroid Build Coastguard Worker 
3762*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, *buf);
3763*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
3764*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "buf");
3765*35238bceSAndroid Build Coastguard Worker 
3766*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(*vao);
3767*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3768*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(positionLoc);
3769*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs");
3770*35238bceSAndroid Build Coastguard Worker 
3771*35238bceSAndroid Build Coastguard Worker     gl.activeTexture(GL_TEXTURE0);
3772*35238bceSAndroid Build Coastguard Worker     gl.bindTexture(getTargetTextureTarget(m_target), m_texture);
3773*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "bind texture");
3774*35238bceSAndroid Build Coastguard Worker 
3775*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_samplerShader->getProgram());
3776*35238bceSAndroid Build Coastguard Worker     gl.uniform1i(m_samplerLayerLoc, layer);
3777*35238bceSAndroid Build Coastguard Worker     gl.uniform1i(m_samplerSamplerLoc, 0);
3778*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "setup program");
3779*35238bceSAndroid Build Coastguard Worker 
3780*35238bceSAndroid Build Coastguard Worker     gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
3781*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
3782*35238bceSAndroid Build Coastguard Worker 
3783*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
3784*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(0);
3785*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "clean");
3786*35238bceSAndroid Build Coastguard Worker 
3787*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
3788*35238bceSAndroid Build Coastguard Worker }
3789*35238bceSAndroid Build Coastguard Worker 
verifyLayerContent(const tcu::Surface & layer,int layerNdx)3790*35238bceSAndroid Build Coastguard Worker bool LayeredRenderCase::verifyLayerContent(const tcu::Surface &layer, int layerNdx)
3791*35238bceSAndroid Build Coastguard Worker {
3792*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 white     = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
3793*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 red       = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
3794*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green     = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
3795*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 blue      = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
3796*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow    = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
3797*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 magenta   = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
3798*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 colors[6] = {white, red, green, blue, yellow, magenta};
3799*35238bceSAndroid Build Coastguard Worker 
3800*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying layer contents" << tcu::TestLog::EndMessage;
3801*35238bceSAndroid Build Coastguard Worker 
3802*35238bceSAndroid Build Coastguard Worker     switch (m_test)
3803*35238bceSAndroid Build Coastguard Worker     {
3804*35238bceSAndroid Build Coastguard Worker     case TEST_DEFAULT_LAYER:
3805*35238bceSAndroid Build Coastguard Worker         if (layerNdx == 0)
3806*35238bceSAndroid Build Coastguard Worker             return verifyImageSingleColoredRow(layer, 0.5f, white);
3807*35238bceSAndroid Build Coastguard Worker         else
3808*35238bceSAndroid Build Coastguard Worker             return verifyEmptyImage(layer);
3809*35238bceSAndroid Build Coastguard Worker 
3810*35238bceSAndroid Build Coastguard Worker     case TEST_SINGLE_LAYER:
3811*35238bceSAndroid Build Coastguard Worker         if (layerNdx == m_targetLayer)
3812*35238bceSAndroid Build Coastguard Worker             return verifyImageSingleColoredRow(layer, 0.5f, white);
3813*35238bceSAndroid Build Coastguard Worker         else
3814*35238bceSAndroid Build Coastguard Worker             return verifyEmptyImage(layer);
3815*35238bceSAndroid Build Coastguard Worker 
3816*35238bceSAndroid Build Coastguard Worker     case TEST_ALL_LAYERS:
3817*35238bceSAndroid Build Coastguard Worker     case TEST_INVOCATION_PER_LAYER:
3818*35238bceSAndroid Build Coastguard Worker         return verifyImageSingleColoredRow(layer, 0.5f, colors[layerNdx]);
3819*35238bceSAndroid Build Coastguard Worker 
3820*35238bceSAndroid Build Coastguard Worker     case TEST_DIFFERENT_LAYERS:
3821*35238bceSAndroid Build Coastguard Worker     case TEST_MULTIPLE_LAYERS_PER_INVOCATION:
3822*35238bceSAndroid Build Coastguard Worker         if (layerNdx == 0)
3823*35238bceSAndroid Build Coastguard Worker             return verifyEmptyImage(layer);
3824*35238bceSAndroid Build Coastguard Worker         else
3825*35238bceSAndroid Build Coastguard Worker             return verifyImageSingleColoredRow(layer, (float)layerNdx / (float)m_numLayers, white);
3826*35238bceSAndroid Build Coastguard Worker 
3827*35238bceSAndroid Build Coastguard Worker     case TEST_LAYER_ID:
3828*35238bceSAndroid Build Coastguard Worker     {
3829*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 layerColor((layerNdx % 2 == 1) ? (1.0f) : (0.5f), ((layerNdx / 2) % 2 == 1) ? (1.0f) : (0.5f),
3830*35238bceSAndroid Build Coastguard Worker                                    (layerNdx == 0) ? (1.0f) : (0.0f), 1.0f);
3831*35238bceSAndroid Build Coastguard Worker         return verifyImageSingleColoredRow(layer, 0.5f, layerColor);
3832*35238bceSAndroid Build Coastguard Worker     }
3833*35238bceSAndroid Build Coastguard Worker 
3834*35238bceSAndroid Build Coastguard Worker     case TEST_LAYER_PROVOKING_VERTEX:
3835*35238bceSAndroid Build Coastguard Worker         if (m_provokingVertex == GL_FIRST_VERTEX_CONVENTION)
3836*35238bceSAndroid Build Coastguard Worker         {
3837*35238bceSAndroid Build Coastguard Worker             if (layerNdx == 0)
3838*35238bceSAndroid Build Coastguard Worker                 return verifyImageSingleColoredRow(layer, 0.5f, white);
3839*35238bceSAndroid Build Coastguard Worker             else
3840*35238bceSAndroid Build Coastguard Worker                 return verifyEmptyImage(layer);
3841*35238bceSAndroid Build Coastguard Worker         }
3842*35238bceSAndroid Build Coastguard Worker         else if (m_provokingVertex == GL_LAST_VERTEX_CONVENTION)
3843*35238bceSAndroid Build Coastguard Worker         {
3844*35238bceSAndroid Build Coastguard Worker             if (layerNdx == 1)
3845*35238bceSAndroid Build Coastguard Worker                 return verifyImageSingleColoredRow(layer, 0.5f, white);
3846*35238bceSAndroid Build Coastguard Worker             else
3847*35238bceSAndroid Build Coastguard Worker                 return verifyEmptyImage(layer);
3848*35238bceSAndroid Build Coastguard Worker         }
3849*35238bceSAndroid Build Coastguard Worker         else
3850*35238bceSAndroid Build Coastguard Worker         {
3851*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
3852*35238bceSAndroid Build Coastguard Worker             return false;
3853*35238bceSAndroid Build Coastguard Worker         }
3854*35238bceSAndroid Build Coastguard Worker 
3855*35238bceSAndroid Build Coastguard Worker     default:
3856*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3857*35238bceSAndroid Build Coastguard Worker         return false;
3858*35238bceSAndroid Build Coastguard Worker     }
3859*35238bceSAndroid Build Coastguard Worker }
3860*35238bceSAndroid Build Coastguard Worker 
verifyImageSingleColoredRow(const tcu::Surface & layer,float rowWidthRatio,const tcu::Vec4 & barColor,bool logging)3861*35238bceSAndroid Build Coastguard Worker bool LayeredRenderCase::verifyImageSingleColoredRow(const tcu::Surface &layer, float rowWidthRatio,
3862*35238bceSAndroid Build Coastguard Worker                                                     const tcu::Vec4 &barColor, bool logging)
3863*35238bceSAndroid Build Coastguard Worker {
3864*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(rowWidthRatio > 0.0f);
3865*35238bceSAndroid Build Coastguard Worker 
3866*35238bceSAndroid Build Coastguard Worker     const int barLength          = (int)(rowWidthRatio * (float)layer.getWidth());
3867*35238bceSAndroid Build Coastguard Worker     const int barLengthThreshold = 1;
3868*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(layer.getWidth(), layer.getHeight());
3869*35238bceSAndroid Build Coastguard Worker     bool allPixelsOk = true;
3870*35238bceSAndroid Build Coastguard Worker 
3871*35238bceSAndroid Build Coastguard Worker     if (logging)
3872*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Expecting all pixels with distance less or equal to (about) "
3873*35238bceSAndroid Build Coastguard Worker                            << barLength << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2)
3874*35238bceSAndroid Build Coastguard Worker                            << "." << tcu::TestLog::EndMessage;
3875*35238bceSAndroid Build Coastguard Worker 
3876*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
3877*35238bceSAndroid Build Coastguard Worker 
3878*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < layer.getHeight(); ++y)
3879*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < layer.getWidth(); ++x)
3880*35238bceSAndroid Build Coastguard Worker         {
3881*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA color    = layer.getPixel(x, y);
3882*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA refColor = tcu::RGBA(barColor);
3883*35238bceSAndroid Build Coastguard Worker             const int threshold      = 8;
3884*35238bceSAndroid Build Coastguard Worker             const bool isBlack =
3885*35238bceSAndroid Build Coastguard Worker                 color.getRed() <= threshold || color.getGreen() <= threshold || color.getBlue() <= threshold;
3886*35238bceSAndroid Build Coastguard Worker             const bool isColor = tcu::allEqual(
3887*35238bceSAndroid Build Coastguard Worker                 tcu::lessThan(tcu::abs(color.toIVec().swizzle(0, 1, 2) - refColor.toIVec().swizzle(0, 1, 2)),
3888*35238bceSAndroid Build Coastguard Worker                               tcu::IVec3(threshold, threshold, threshold)),
3889*35238bceSAndroid Build Coastguard Worker                 tcu::BVec3(true, true, true));
3890*35238bceSAndroid Build Coastguard Worker 
3891*35238bceSAndroid Build Coastguard Worker             bool isOk;
3892*35238bceSAndroid Build Coastguard Worker 
3893*35238bceSAndroid Build Coastguard Worker             if (x <= barLength - barLengthThreshold)
3894*35238bceSAndroid Build Coastguard Worker                 isOk = isColor;
3895*35238bceSAndroid Build Coastguard Worker             else if (x >= barLength + barLengthThreshold)
3896*35238bceSAndroid Build Coastguard Worker                 isOk = isBlack;
3897*35238bceSAndroid Build Coastguard Worker             else
3898*35238bceSAndroid Build Coastguard Worker                 isOk = isColor || isBlack;
3899*35238bceSAndroid Build Coastguard Worker 
3900*35238bceSAndroid Build Coastguard Worker             allPixelsOk &= isOk;
3901*35238bceSAndroid Build Coastguard Worker 
3902*35238bceSAndroid Build Coastguard Worker             if (!isOk)
3903*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::red());
3904*35238bceSAndroid Build Coastguard Worker         }
3905*35238bceSAndroid Build Coastguard Worker 
3906*35238bceSAndroid Build Coastguard Worker     if (allPixelsOk)
3907*35238bceSAndroid Build Coastguard Worker     {
3908*35238bceSAndroid Build Coastguard Worker         if (logging)
3909*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
3910*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3911*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Layer", "Layer", layer) << tcu::TestLog::EndImageSet;
3912*35238bceSAndroid Build Coastguard Worker         return true;
3913*35238bceSAndroid Build Coastguard Worker     }
3914*35238bceSAndroid Build Coastguard Worker     else
3915*35238bceSAndroid Build Coastguard Worker     {
3916*35238bceSAndroid Build Coastguard Worker         if (logging)
3917*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels."
3918*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3919*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Layer", "Layer", layer)
3920*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("ErrorMask", "Errors", errorMask) << tcu::TestLog::EndImageSet;
3921*35238bceSAndroid Build Coastguard Worker         return false;
3922*35238bceSAndroid Build Coastguard Worker     }
3923*35238bceSAndroid Build Coastguard Worker 
3924*35238bceSAndroid Build Coastguard Worker     // Note: never reached
3925*35238bceSAndroid Build Coastguard Worker     if (logging)
3926*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Image("LayerContent", "Layer content", layer);
3927*35238bceSAndroid Build Coastguard Worker 
3928*35238bceSAndroid Build Coastguard Worker     return allPixelsOk;
3929*35238bceSAndroid Build Coastguard Worker }
3930*35238bceSAndroid Build Coastguard Worker 
verifyEmptyImage(const tcu::Surface & layer,bool logging)3931*35238bceSAndroid Build Coastguard Worker bool LayeredRenderCase::verifyEmptyImage(const tcu::Surface &layer, bool logging)
3932*35238bceSAndroid Build Coastguard Worker {
3933*35238bceSAndroid Build Coastguard Worker     // Expect black
3934*35238bceSAndroid Build Coastguard Worker     if (logging)
3935*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage;
3936*35238bceSAndroid Build Coastguard Worker 
3937*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < layer.getHeight(); ++y)
3938*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < layer.getWidth(); ++x)
3939*35238bceSAndroid Build Coastguard Worker         {
3940*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA color = layer.getPixel(x, y);
3941*35238bceSAndroid Build Coastguard Worker             const int threshold   = 8;
3942*35238bceSAndroid Build Coastguard Worker             const bool isBlack =
3943*35238bceSAndroid Build Coastguard Worker                 color.getRed() <= threshold || color.getGreen() <= threshold || color.getBlue() <= threshold;
3944*35238bceSAndroid Build Coastguard Worker 
3945*35238bceSAndroid Build Coastguard Worker             if (!isBlack)
3946*35238bceSAndroid Build Coastguard Worker             {
3947*35238bceSAndroid Build Coastguard Worker                 if (logging)
3948*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Found (at least) one bad pixel at " << x << "," << y
3949*35238bceSAndroid Build Coastguard Worker                                        << ". Pixel color is not background color." << tcu::TestLog::EndMessage
3950*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3951*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::Image("Layer", "Layer", layer) << tcu::TestLog::EndImageSet;
3952*35238bceSAndroid Build Coastguard Worker                 return false;
3953*35238bceSAndroid Build Coastguard Worker             }
3954*35238bceSAndroid Build Coastguard Worker         }
3955*35238bceSAndroid Build Coastguard Worker 
3956*35238bceSAndroid Build Coastguard Worker     if (logging)
3957*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
3958*35238bceSAndroid Build Coastguard Worker 
3959*35238bceSAndroid Build Coastguard Worker     return true;
3960*35238bceSAndroid Build Coastguard Worker }
3961*35238bceSAndroid Build Coastguard Worker 
verifyProvokingVertexLayers(const tcu::Surface & layer0,const tcu::Surface & layer1)3962*35238bceSAndroid Build Coastguard Worker bool LayeredRenderCase::verifyProvokingVertexLayers(const tcu::Surface &layer0, const tcu::Surface &layer1)
3963*35238bceSAndroid Build Coastguard Worker {
3964*35238bceSAndroid Build Coastguard Worker     const bool layer0Empty = verifyEmptyImage(layer0, false);
3965*35238bceSAndroid Build Coastguard Worker     const bool layer1Empty = verifyEmptyImage(layer1, false);
3966*35238bceSAndroid Build Coastguard Worker     bool error             = false;
3967*35238bceSAndroid Build Coastguard Worker 
3968*35238bceSAndroid Build Coastguard Worker     // Both images could contain something if the quad triangles get assigned to different layers
3969*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Expecting non-empty layers, or non-empty layer."
3970*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
3971*35238bceSAndroid Build Coastguard Worker 
3972*35238bceSAndroid Build Coastguard Worker     if (layer0Empty == true && layer1Empty == true)
3973*35238bceSAndroid Build Coastguard Worker     {
3974*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Got empty images." << tcu::TestLog::EndMessage;
3975*35238bceSAndroid Build Coastguard Worker         error = true;
3976*35238bceSAndroid Build Coastguard Worker     }
3977*35238bceSAndroid Build Coastguard Worker 
3978*35238bceSAndroid Build Coastguard Worker     // log images always
3979*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3980*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::Image("Layer", "Layer0", layer0)
3981*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::Image("Layer", "Layer1", layer1) << tcu::TestLog::EndImageSet;
3982*35238bceSAndroid Build Coastguard Worker 
3983*35238bceSAndroid Build Coastguard Worker     if (error)
3984*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage;
3985*35238bceSAndroid Build Coastguard Worker     else
3986*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage;
3987*35238bceSAndroid Build Coastguard Worker 
3988*35238bceSAndroid Build Coastguard Worker     return !error;
3989*35238bceSAndroid Build Coastguard Worker }
3990*35238bceSAndroid Build Coastguard Worker 
getTargetLayers(LayeredRenderTargetType target)3991*35238bceSAndroid Build Coastguard Worker int LayeredRenderCase::getTargetLayers(LayeredRenderTargetType target)
3992*35238bceSAndroid Build Coastguard Worker {
3993*35238bceSAndroid Build Coastguard Worker     switch (target)
3994*35238bceSAndroid Build Coastguard Worker     {
3995*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
3996*35238bceSAndroid Build Coastguard Worker         return 6;
3997*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
3998*35238bceSAndroid Build Coastguard Worker         return 4;
3999*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
4000*35238bceSAndroid Build Coastguard Worker         return 4;
4001*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
4002*35238bceSAndroid Build Coastguard Worker         return 4;
4003*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
4004*35238bceSAndroid Build Coastguard Worker         return 2;
4005*35238bceSAndroid Build Coastguard Worker     default:
4006*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4007*35238bceSAndroid Build Coastguard Worker         return 0;
4008*35238bceSAndroid Build Coastguard Worker     }
4009*35238bceSAndroid Build Coastguard Worker }
4010*35238bceSAndroid Build Coastguard Worker 
getTargetTextureTarget(LayeredRenderTargetType target)4011*35238bceSAndroid Build Coastguard Worker glw::GLenum LayeredRenderCase::getTargetTextureTarget(LayeredRenderTargetType target)
4012*35238bceSAndroid Build Coastguard Worker {
4013*35238bceSAndroid Build Coastguard Worker     switch (target)
4014*35238bceSAndroid Build Coastguard Worker     {
4015*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
4016*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_CUBE_MAP;
4017*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
4018*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_3D;
4019*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
4020*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_1D_ARRAY;
4021*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
4022*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_2D_ARRAY;
4023*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
4024*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
4025*35238bceSAndroid Build Coastguard Worker     default:
4026*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4027*35238bceSAndroid Build Coastguard Worker         return 0;
4028*35238bceSAndroid Build Coastguard Worker     }
4029*35238bceSAndroid Build Coastguard Worker }
4030*35238bceSAndroid Build Coastguard Worker 
getTargetDimensions(LayeredRenderTargetType target)4031*35238bceSAndroid Build Coastguard Worker tcu::IVec3 LayeredRenderCase::getTargetDimensions(LayeredRenderTargetType target)
4032*35238bceSAndroid Build Coastguard Worker {
4033*35238bceSAndroid Build Coastguard Worker     switch (target)
4034*35238bceSAndroid Build Coastguard Worker     {
4035*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
4036*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(64, 64, 0);
4037*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
4038*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(64, 64, 4);
4039*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
4040*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(64, 4, 0);
4041*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
4042*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(64, 64, 4);
4043*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
4044*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(64, 64, 2);
4045*35238bceSAndroid Build Coastguard Worker     default:
4046*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4047*35238bceSAndroid Build Coastguard Worker         return tcu::IVec3(0, 0, 0);
4048*35238bceSAndroid Build Coastguard Worker     }
4049*35238bceSAndroid Build Coastguard Worker }
4050*35238bceSAndroid Build Coastguard Worker 
getResolveDimensions(LayeredRenderTargetType target)4051*35238bceSAndroid Build Coastguard Worker tcu::IVec2 LayeredRenderCase::getResolveDimensions(LayeredRenderTargetType target)
4052*35238bceSAndroid Build Coastguard Worker {
4053*35238bceSAndroid Build Coastguard Worker     switch (target)
4054*35238bceSAndroid Build Coastguard Worker     {
4055*35238bceSAndroid Build Coastguard Worker     case TARGET_CUBE:
4056*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(64, 64);
4057*35238bceSAndroid Build Coastguard Worker     case TARGET_3D:
4058*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(64, 64);
4059*35238bceSAndroid Build Coastguard Worker     case TARGET_1D_ARRAY:
4060*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(64, 1);
4061*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_ARRAY:
4062*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(64, 64);
4063*35238bceSAndroid Build Coastguard Worker     case TARGET_2D_MS_ARRAY:
4064*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(64, 64);
4065*35238bceSAndroid Build Coastguard Worker     default:
4066*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4067*35238bceSAndroid Build Coastguard Worker         return tcu::IVec2(0, 0);
4068*35238bceSAndroid Build Coastguard Worker     }
4069*35238bceSAndroid Build Coastguard Worker }
4070*35238bceSAndroid Build Coastguard Worker 
4071*35238bceSAndroid Build Coastguard Worker class VaryingOutputCountCase : public GeometryShaderRenderTest
4072*35238bceSAndroid Build Coastguard Worker {
4073*35238bceSAndroid Build Coastguard Worker public:
4074*35238bceSAndroid Build Coastguard Worker     enum ShaderInstancingMode
4075*35238bceSAndroid Build Coastguard Worker     {
4076*35238bceSAndroid Build Coastguard Worker         MODE_WITHOUT_INSTANCING = 0,
4077*35238bceSAndroid Build Coastguard Worker         MODE_WITH_INSTANCING,
4078*35238bceSAndroid Build Coastguard Worker 
4079*35238bceSAndroid Build Coastguard Worker         MODE_LAST
4080*35238bceSAndroid Build Coastguard Worker     };
4081*35238bceSAndroid Build Coastguard Worker     VaryingOutputCountCase(Context &context, const char *name, const char *desc,
4082*35238bceSAndroid Build Coastguard Worker                            VaryingOutputCountShader::VaryingSource test, ShaderInstancingMode mode);
4083*35238bceSAndroid Build Coastguard Worker 
4084*35238bceSAndroid Build Coastguard Worker private:
4085*35238bceSAndroid Build Coastguard Worker     void init(void);
4086*35238bceSAndroid Build Coastguard Worker     void deinit(void);
4087*35238bceSAndroid Build Coastguard Worker     void preRender(sglr::Context &ctx, GLuint programID);
4088*35238bceSAndroid Build Coastguard Worker 
4089*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
4090*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
4091*35238bceSAndroid Build Coastguard Worker     void genVertexDataWithoutInstancing(void);
4092*35238bceSAndroid Build Coastguard Worker     void genVertexDataWithInstancing(void);
4093*35238bceSAndroid Build Coastguard Worker 
4094*35238bceSAndroid Build Coastguard Worker     VaryingOutputCountShader *m_program;
4095*35238bceSAndroid Build Coastguard Worker     const VaryingOutputCountShader::VaryingSource m_test;
4096*35238bceSAndroid Build Coastguard Worker     const ShaderInstancingMode m_mode;
4097*35238bceSAndroid Build Coastguard Worker     int m_maxEmitCount;
4098*35238bceSAndroid Build Coastguard Worker };
4099*35238bceSAndroid Build Coastguard Worker 
VaryingOutputCountCase(Context & context,const char * name,const char * desc,VaryingOutputCountShader::VaryingSource test,ShaderInstancingMode mode)4100*35238bceSAndroid Build Coastguard Worker VaryingOutputCountCase::VaryingOutputCountCase(Context &context, const char *name, const char *desc,
4101*35238bceSAndroid Build Coastguard Worker                                                VaryingOutputCountShader::VaryingSource test, ShaderInstancingMode mode)
4102*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, desc, GL_POINTS, GL_TRIANGLE_STRIP,
4103*35238bceSAndroid Build Coastguard Worker                                VaryingOutputCountShader::getAttributeName(test))
4104*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
4105*35238bceSAndroid Build Coastguard Worker     , m_test(test)
4106*35238bceSAndroid Build Coastguard Worker     , m_mode(mode)
4107*35238bceSAndroid Build Coastguard Worker     , m_maxEmitCount(0)
4108*35238bceSAndroid Build Coastguard Worker {
4109*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(mode < MODE_LAST);
4110*35238bceSAndroid Build Coastguard Worker }
4111*35238bceSAndroid Build Coastguard Worker 
init(void)4112*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::init(void)
4113*35238bceSAndroid Build Coastguard Worker {
4114*35238bceSAndroid Build Coastguard Worker     // Check requirements
4115*35238bceSAndroid Build Coastguard Worker 
4116*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4117*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4118*35238bceSAndroid Build Coastguard Worker 
4119*35238bceSAndroid Build Coastguard Worker     if (m_test == VaryingOutputCountShader::READ_TEXTURE)
4120*35238bceSAndroid Build Coastguard Worker     {
4121*35238bceSAndroid Build Coastguard Worker         glw::GLint maxTextures = 0;
4122*35238bceSAndroid Build Coastguard Worker 
4123*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxTextures);
4124*35238bceSAndroid Build Coastguard Worker 
4125*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = " << maxTextures
4126*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4127*35238bceSAndroid Build Coastguard Worker 
4128*35238bceSAndroid Build Coastguard Worker         if (maxTextures < 1)
4129*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Geometry shader texture units required");
4130*35238bceSAndroid Build Coastguard Worker     }
4131*35238bceSAndroid Build Coastguard Worker 
4132*35238bceSAndroid Build Coastguard Worker     // Get max emit count
4133*35238bceSAndroid Build Coastguard Worker     {
4134*35238bceSAndroid Build Coastguard Worker         const int componentsPerVertex = 4 + 4; // vec4 pos, vec4 color
4135*35238bceSAndroid Build Coastguard Worker         glw::GLint maxVertices        = 0;
4136*35238bceSAndroid Build Coastguard Worker         glw::GLint maxComponents      = 0;
4137*35238bceSAndroid Build Coastguard Worker 
4138*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &maxVertices);
4139*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
4140*35238bceSAndroid Build Coastguard Worker                                                                 &maxComponents);
4141*35238bceSAndroid Build Coastguard Worker 
4142*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_OUTPUT_VERTICES = " << maxVertices
4143*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4144*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << maxComponents
4145*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4146*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Components per vertex = " << componentsPerVertex
4147*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4148*35238bceSAndroid Build Coastguard Worker 
4149*35238bceSAndroid Build Coastguard Worker         if (maxVertices < 256)
4150*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("MAX_GEOMETRY_OUTPUT_VERTICES was less than minimum required (256)");
4151*35238bceSAndroid Build Coastguard Worker         if (maxComponents < 1024)
4152*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS was less than minimum required (1024)");
4153*35238bceSAndroid Build Coastguard Worker 
4154*35238bceSAndroid Build Coastguard Worker         m_maxEmitCount = de::min(maxVertices, maxComponents / componentsPerVertex);
4155*35238bceSAndroid Build Coastguard Worker     }
4156*35238bceSAndroid Build Coastguard Worker 
4157*35238bceSAndroid Build Coastguard Worker     // Log what the test tries to do
4158*35238bceSAndroid Build Coastguard Worker 
4159*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Rendering 4 n-gons with n = "
4160*35238bceSAndroid Build Coastguard Worker                        << ((VaryingOutputCountShader::EMIT_COUNT_VERTEX_0 == -1) ?
4161*35238bceSAndroid Build Coastguard Worker                                (m_maxEmitCount) :
4162*35238bceSAndroid Build Coastguard Worker                                (VaryingOutputCountShader::EMIT_COUNT_VERTEX_0))
4163*35238bceSAndroid Build Coastguard Worker                        << ", "
4164*35238bceSAndroid Build Coastguard Worker                        << ((VaryingOutputCountShader::EMIT_COUNT_VERTEX_1 == -1) ?
4165*35238bceSAndroid Build Coastguard Worker                                (m_maxEmitCount) :
4166*35238bceSAndroid Build Coastguard Worker                                (VaryingOutputCountShader::EMIT_COUNT_VERTEX_1))
4167*35238bceSAndroid Build Coastguard Worker                        << ", "
4168*35238bceSAndroid Build Coastguard Worker                        << ((VaryingOutputCountShader::EMIT_COUNT_VERTEX_2 == -1) ?
4169*35238bceSAndroid Build Coastguard Worker                                (m_maxEmitCount) :
4170*35238bceSAndroid Build Coastguard Worker                                (VaryingOutputCountShader::EMIT_COUNT_VERTEX_2))
4171*35238bceSAndroid Build Coastguard Worker                        << ", and "
4172*35238bceSAndroid Build Coastguard Worker                        << ((VaryingOutputCountShader::EMIT_COUNT_VERTEX_3 == -1) ?
4173*35238bceSAndroid Build Coastguard Worker                                (m_maxEmitCount) :
4174*35238bceSAndroid Build Coastguard Worker                                (VaryingOutputCountShader::EMIT_COUNT_VERTEX_3))
4175*35238bceSAndroid Build Coastguard Worker                        << ".\n"
4176*35238bceSAndroid Build Coastguard Worker                        << "N is supplied to the geomery shader with "
4177*35238bceSAndroid Build Coastguard Worker                        << ((m_test == VaryingOutputCountShader::READ_ATTRIBUTE) ? ("attribute") :
4178*35238bceSAndroid Build Coastguard Worker                            (m_test == VaryingOutputCountShader::READ_UNIFORM)   ? ("uniform") :
4179*35238bceSAndroid Build Coastguard Worker                                                                                   ("texture"))
4180*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
4181*35238bceSAndroid Build Coastguard Worker 
4182*35238bceSAndroid Build Coastguard Worker     // Gen shader
4183*35238bceSAndroid Build Coastguard Worker     {
4184*35238bceSAndroid Build Coastguard Worker         const bool instanced = (m_mode == MODE_WITH_INSTANCING);
4185*35238bceSAndroid Build Coastguard Worker 
4186*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!m_program);
4187*35238bceSAndroid Build Coastguard Worker         m_program =
4188*35238bceSAndroid Build Coastguard Worker             new VaryingOutputCountShader(m_context.getRenderContext().getType(), m_test, m_maxEmitCount, instanced);
4189*35238bceSAndroid Build Coastguard Worker     }
4190*35238bceSAndroid Build Coastguard Worker 
4191*35238bceSAndroid Build Coastguard Worker     // Case init
4192*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
4193*35238bceSAndroid Build Coastguard Worker }
4194*35238bceSAndroid Build Coastguard Worker 
deinit(void)4195*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::deinit(void)
4196*35238bceSAndroid Build Coastguard Worker {
4197*35238bceSAndroid Build Coastguard Worker     if (m_program)
4198*35238bceSAndroid Build Coastguard Worker     {
4199*35238bceSAndroid Build Coastguard Worker         delete m_program;
4200*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
4201*35238bceSAndroid Build Coastguard Worker     }
4202*35238bceSAndroid Build Coastguard Worker 
4203*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
4204*35238bceSAndroid Build Coastguard Worker }
4205*35238bceSAndroid Build Coastguard Worker 
preRender(sglr::Context & ctx,GLuint programID)4206*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::preRender(sglr::Context &ctx, GLuint programID)
4207*35238bceSAndroid Build Coastguard Worker {
4208*35238bceSAndroid Build Coastguard Worker     if (m_test == VaryingOutputCountShader::READ_UNIFORM)
4209*35238bceSAndroid Build Coastguard Worker     {
4210*35238bceSAndroid Build Coastguard Worker         const int location         = ctx.getUniformLocation(programID, "u_emitCount");
4211*35238bceSAndroid Build Coastguard Worker         const int32_t emitCount[4] = {6, 0, m_maxEmitCount, 10};
4212*35238bceSAndroid Build Coastguard Worker 
4213*35238bceSAndroid Build Coastguard Worker         if (location == -1)
4214*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("uniform location of u_emitCount was -1.");
4215*35238bceSAndroid Build Coastguard Worker 
4216*35238bceSAndroid Build Coastguard Worker         ctx.uniform4iv(location, 1, emitCount);
4217*35238bceSAndroid Build Coastguard Worker     }
4218*35238bceSAndroid Build Coastguard Worker     else if (m_test == VaryingOutputCountShader::READ_TEXTURE)
4219*35238bceSAndroid Build Coastguard Worker     {
4220*35238bceSAndroid Build Coastguard Worker         const uint8_t data[4 * 4] = {
4221*35238bceSAndroid Build Coastguard Worker             255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
4222*35238bceSAndroid Build Coastguard Worker         };
4223*35238bceSAndroid Build Coastguard Worker         const int location = ctx.getUniformLocation(programID, "u_sampler");
4224*35238bceSAndroid Build Coastguard Worker         GLuint texID       = 0;
4225*35238bceSAndroid Build Coastguard Worker 
4226*35238bceSAndroid Build Coastguard Worker         if (location == -1)
4227*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("uniform location of u_sampler was -1.");
4228*35238bceSAndroid Build Coastguard Worker         ctx.uniform1i(location, 0);
4229*35238bceSAndroid Build Coastguard Worker 
4230*35238bceSAndroid Build Coastguard Worker         // \note we don't need to explicitly delete the texture, the sglr context will delete it
4231*35238bceSAndroid Build Coastguard Worker         ctx.genTextures(1, &texID);
4232*35238bceSAndroid Build Coastguard Worker         ctx.bindTexture(GL_TEXTURE_2D, texID);
4233*35238bceSAndroid Build Coastguard Worker         ctx.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
4234*35238bceSAndroid Build Coastguard Worker         ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4235*35238bceSAndroid Build Coastguard Worker         ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4236*35238bceSAndroid Build Coastguard Worker     }
4237*35238bceSAndroid Build Coastguard Worker }
4238*35238bceSAndroid Build Coastguard Worker 
getProgram(void)4239*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &VaryingOutputCountCase::getProgram(void)
4240*35238bceSAndroid Build Coastguard Worker {
4241*35238bceSAndroid Build Coastguard Worker     return *m_program;
4242*35238bceSAndroid Build Coastguard Worker }
4243*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)4244*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::genVertexAttribData(void)
4245*35238bceSAndroid Build Coastguard Worker {
4246*35238bceSAndroid Build Coastguard Worker     if (m_mode == MODE_WITHOUT_INSTANCING)
4247*35238bceSAndroid Build Coastguard Worker         genVertexDataWithoutInstancing();
4248*35238bceSAndroid Build Coastguard Worker     else if (m_mode == MODE_WITH_INSTANCING)
4249*35238bceSAndroid Build Coastguard Worker         genVertexDataWithInstancing();
4250*35238bceSAndroid Build Coastguard Worker     else
4251*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4252*35238bceSAndroid Build Coastguard Worker }
4253*35238bceSAndroid Build Coastguard Worker 
genVertexDataWithoutInstancing(void)4254*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::genVertexDataWithoutInstancing(void)
4255*35238bceSAndroid Build Coastguard Worker {
4256*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 4;
4257*35238bceSAndroid Build Coastguard Worker 
4258*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(4);
4259*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(4);
4260*35238bceSAndroid Build Coastguard Worker 
4261*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
4262*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
4263*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
4264*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
4265*35238bceSAndroid Build Coastguard Worker 
4266*35238bceSAndroid Build Coastguard Worker     if (m_test == VaryingOutputCountShader::READ_ATTRIBUTE)
4267*35238bceSAndroid Build Coastguard Worker     {
4268*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[0] = tcu::Vec4(((VaryingOutputCountShader::EMIT_COUNT_VERTEX_0 == -1) ?
4269*35238bceSAndroid Build Coastguard Worker                                              ((float)m_maxEmitCount) :
4270*35238bceSAndroid Build Coastguard Worker                                              ((float)VaryingOutputCountShader::EMIT_COUNT_VERTEX_0)),
4271*35238bceSAndroid Build Coastguard Worker                                         0.0f, 0.0f, 0.0f);
4272*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[1] = tcu::Vec4(((VaryingOutputCountShader::EMIT_COUNT_VERTEX_1 == -1) ?
4273*35238bceSAndroid Build Coastguard Worker                                              ((float)m_maxEmitCount) :
4274*35238bceSAndroid Build Coastguard Worker                                              ((float)VaryingOutputCountShader::EMIT_COUNT_VERTEX_1)),
4275*35238bceSAndroid Build Coastguard Worker                                         0.0f, 0.0f, 0.0f);
4276*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[2] = tcu::Vec4(((VaryingOutputCountShader::EMIT_COUNT_VERTEX_2 == -1) ?
4277*35238bceSAndroid Build Coastguard Worker                                              ((float)m_maxEmitCount) :
4278*35238bceSAndroid Build Coastguard Worker                                              ((float)VaryingOutputCountShader::EMIT_COUNT_VERTEX_2)),
4279*35238bceSAndroid Build Coastguard Worker                                         0.0f, 0.0f, 0.0f);
4280*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[3] = tcu::Vec4(((VaryingOutputCountShader::EMIT_COUNT_VERTEX_3 == -1) ?
4281*35238bceSAndroid Build Coastguard Worker                                              ((float)m_maxEmitCount) :
4282*35238bceSAndroid Build Coastguard Worker                                              ((float)VaryingOutputCountShader::EMIT_COUNT_VERTEX_3)),
4283*35238bceSAndroid Build Coastguard Worker                                         0.0f, 0.0f, 0.0f);
4284*35238bceSAndroid Build Coastguard Worker     }
4285*35238bceSAndroid Build Coastguard Worker     else
4286*35238bceSAndroid Build Coastguard Worker     {
4287*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
4288*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
4289*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
4290*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
4291*35238bceSAndroid Build Coastguard Worker     }
4292*35238bceSAndroid Build Coastguard Worker }
4293*35238bceSAndroid Build Coastguard Worker 
genVertexDataWithInstancing(void)4294*35238bceSAndroid Build Coastguard Worker void VaryingOutputCountCase::genVertexDataWithInstancing(void)
4295*35238bceSAndroid Build Coastguard Worker {
4296*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices = 1;
4297*35238bceSAndroid Build Coastguard Worker 
4298*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(1);
4299*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(1);
4300*35238bceSAndroid Build Coastguard Worker 
4301*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4302*35238bceSAndroid Build Coastguard Worker 
4303*35238bceSAndroid Build Coastguard Worker     if (m_test == VaryingOutputCountShader::READ_ATTRIBUTE)
4304*35238bceSAndroid Build Coastguard Worker     {
4305*35238bceSAndroid Build Coastguard Worker         const int emitCounts[] = {
4306*35238bceSAndroid Build Coastguard Worker             (VaryingOutputCountShader::EMIT_COUNT_VERTEX_0 == -1) ? (m_maxEmitCount) :
4307*35238bceSAndroid Build Coastguard Worker                                                                     (VaryingOutputCountShader::EMIT_COUNT_VERTEX_0),
4308*35238bceSAndroid Build Coastguard Worker             (VaryingOutputCountShader::EMIT_COUNT_VERTEX_1 == -1) ? (m_maxEmitCount) :
4309*35238bceSAndroid Build Coastguard Worker                                                                     (VaryingOutputCountShader::EMIT_COUNT_VERTEX_1),
4310*35238bceSAndroid Build Coastguard Worker             (VaryingOutputCountShader::EMIT_COUNT_VERTEX_2 == -1) ? (m_maxEmitCount) :
4311*35238bceSAndroid Build Coastguard Worker                                                                     (VaryingOutputCountShader::EMIT_COUNT_VERTEX_2),
4312*35238bceSAndroid Build Coastguard Worker             (VaryingOutputCountShader::EMIT_COUNT_VERTEX_3 == -1) ? (m_maxEmitCount) :
4313*35238bceSAndroid Build Coastguard Worker                                                                     (VaryingOutputCountShader::EMIT_COUNT_VERTEX_3),
4314*35238bceSAndroid Build Coastguard Worker         };
4315*35238bceSAndroid Build Coastguard Worker 
4316*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[0] =
4317*35238bceSAndroid Build Coastguard Worker             tcu::Vec4((float)emitCounts[0], (float)emitCounts[1], (float)emitCounts[2], (float)emitCounts[3]);
4318*35238bceSAndroid Build Coastguard Worker     }
4319*35238bceSAndroid Build Coastguard Worker     else
4320*35238bceSAndroid Build Coastguard Worker     {
4321*35238bceSAndroid Build Coastguard Worker         // not used
4322*35238bceSAndroid Build Coastguard Worker         m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
4323*35238bceSAndroid Build Coastguard Worker     }
4324*35238bceSAndroid Build Coastguard Worker }
4325*35238bceSAndroid Build Coastguard Worker 
4326*35238bceSAndroid Build Coastguard Worker class GeometryProgramQueryCase : public TestCase
4327*35238bceSAndroid Build Coastguard Worker {
4328*35238bceSAndroid Build Coastguard Worker public:
4329*35238bceSAndroid Build Coastguard Worker     struct ProgramCase
4330*35238bceSAndroid Build Coastguard Worker     {
4331*35238bceSAndroid Build Coastguard Worker         const char *description;
4332*35238bceSAndroid Build Coastguard Worker         const char *header;
4333*35238bceSAndroid Build Coastguard Worker         int value;
4334*35238bceSAndroid Build Coastguard Worker     };
4335*35238bceSAndroid Build Coastguard Worker 
4336*35238bceSAndroid Build Coastguard Worker     GeometryProgramQueryCase(Context &context, const char *name, const char *description, glw::GLenum target);
4337*35238bceSAndroid Build Coastguard Worker 
4338*35238bceSAndroid Build Coastguard Worker     void init(void);
4339*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
4340*35238bceSAndroid Build Coastguard Worker 
4341*35238bceSAndroid Build Coastguard Worker private:
4342*35238bceSAndroid Build Coastguard Worker     void expectProgramValue(uint32_t program, int value);
4343*35238bceSAndroid Build Coastguard Worker     void expectQueryError(uint32_t program);
4344*35238bceSAndroid Build Coastguard Worker 
4345*35238bceSAndroid Build Coastguard Worker     const glw::GLenum m_target;
4346*35238bceSAndroid Build Coastguard Worker 
4347*35238bceSAndroid Build Coastguard Worker protected:
4348*35238bceSAndroid Build Coastguard Worker     std::vector<ProgramCase> m_cases;
4349*35238bceSAndroid Build Coastguard Worker };
4350*35238bceSAndroid Build Coastguard Worker 
GeometryProgramQueryCase(Context & context,const char * name,const char * description,glw::GLenum target)4351*35238bceSAndroid Build Coastguard Worker GeometryProgramQueryCase::GeometryProgramQueryCase(Context &context, const char *name, const char *description,
4352*35238bceSAndroid Build Coastguard Worker                                                    glw::GLenum target)
4353*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
4354*35238bceSAndroid Build Coastguard Worker     , m_target(target)
4355*35238bceSAndroid Build Coastguard Worker {
4356*35238bceSAndroid Build Coastguard Worker }
4357*35238bceSAndroid Build Coastguard Worker 
init(void)4358*35238bceSAndroid Build Coastguard Worker void GeometryProgramQueryCase::init(void)
4359*35238bceSAndroid Build Coastguard Worker {
4360*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4361*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4362*35238bceSAndroid Build Coastguard Worker }
4363*35238bceSAndroid Build Coastguard Worker 
iterate(void)4364*35238bceSAndroid Build Coastguard Worker GeometryProgramQueryCase::IterateResult GeometryProgramQueryCase::iterate(void)
4365*35238bceSAndroid Build Coastguard Worker {
4366*35238bceSAndroid Build Coastguard Worker     const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
4367*35238bceSAndroid Build Coastguard Worker 
4368*35238bceSAndroid Build Coastguard Worker     const std::string vertexSource = std::string(glu::getGLSLVersionDeclaration(
4369*35238bceSAndroid Build Coastguard Worker                                          glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()))) +
4370*35238bceSAndroid Build Coastguard Worker                                      "\n"
4371*35238bceSAndroid Build Coastguard Worker                                      "void main ()\n"
4372*35238bceSAndroid Build Coastguard Worker                                      "{\n"
4373*35238bceSAndroid Build Coastguard Worker                                      "    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
4374*35238bceSAndroid Build Coastguard Worker                                      "}\n";
4375*35238bceSAndroid Build Coastguard Worker     const std::string fragmentSource = std::string(glu::getGLSLVersionDeclaration(
4376*35238bceSAndroid Build Coastguard Worker                                            glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()))) +
4377*35238bceSAndroid Build Coastguard Worker                                        "\n"
4378*35238bceSAndroid Build Coastguard Worker                                        "layout(location = 0) out mediump vec4 fragColor;\n"
4379*35238bceSAndroid Build Coastguard Worker                                        "void main ()\n"
4380*35238bceSAndroid Build Coastguard Worker                                        "{\n"
4381*35238bceSAndroid Build Coastguard Worker                                        "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
4382*35238bceSAndroid Build Coastguard Worker                                        "}\n";
4383*35238bceSAndroid Build Coastguard Worker     static const char *s_geometryBody = "void main ()\n"
4384*35238bceSAndroid Build Coastguard Worker                                         "{\n"
4385*35238bceSAndroid Build Coastguard Worker                                         "    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
4386*35238bceSAndroid Build Coastguard Worker                                         "    EmitVertex();\n"
4387*35238bceSAndroid Build Coastguard Worker                                         "}\n";
4388*35238bceSAndroid Build Coastguard Worker 
4389*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4390*35238bceSAndroid Build Coastguard Worker 
4391*35238bceSAndroid Build Coastguard Worker     // default cases
4392*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_cases.size(); ++ndx)
4393*35238bceSAndroid Build Coastguard Worker     {
4394*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Case", m_cases[ndx].description);
4395*35238bceSAndroid Build Coastguard Worker         const std::string geometrySource = m_cases[ndx].header + std::string(s_geometryBody);
4396*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(m_context.getRenderContext(),
4397*35238bceSAndroid Build Coastguard Worker                                          glu::ProgramSources()
4398*35238bceSAndroid Build Coastguard Worker                                              << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource)
4399*35238bceSAndroid Build Coastguard Worker                                              << glu::GeometrySource(specializeShader(
4400*35238bceSAndroid Build Coastguard Worker                                                     geometrySource, m_context.getRenderContext().getType())));
4401*35238bceSAndroid Build Coastguard Worker 
4402*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
4403*35238bceSAndroid Build Coastguard Worker         expectProgramValue(program.getProgram(), m_cases[ndx].value);
4404*35238bceSAndroid Build Coastguard Worker     }
4405*35238bceSAndroid Build Coastguard Worker 
4406*35238bceSAndroid Build Coastguard Worker     // no geometry shader -case (INVALID OP)
4407*35238bceSAndroid Build Coastguard Worker     {
4408*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "NoGeometryShader", "No geometry shader");
4409*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources()
4410*35238bceSAndroid Build Coastguard Worker                                                                            << glu::VertexSource(vertexSource)
4411*35238bceSAndroid Build Coastguard Worker                                                                            << glu::FragmentSource(fragmentSource));
4412*35238bceSAndroid Build Coastguard Worker 
4413*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
4414*35238bceSAndroid Build Coastguard Worker         expectQueryError(program.getProgram());
4415*35238bceSAndroid Build Coastguard Worker     }
4416*35238bceSAndroid Build Coastguard Worker 
4417*35238bceSAndroid Build Coastguard Worker     // not linked -case (INVALID OP)
4418*35238bceSAndroid Build Coastguard Worker     {
4419*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "NotLinkedProgram", "Shader program not linked");
4420*35238bceSAndroid Build Coastguard Worker         const std::string geometrySource =
4421*35238bceSAndroid Build Coastguard Worker             std::string(glu::getGLSLVersionDeclaration(
4422*35238bceSAndroid Build Coastguard Worker                 glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()))) +
4423*35238bceSAndroid Build Coastguard Worker             "\n" + std::string(supportsES32 ? "" : "#extension GL_EXT_geometry_shader : require\n") +
4424*35238bceSAndroid Build Coastguard Worker             "layout (triangles) in;\n"
4425*35238bceSAndroid Build Coastguard Worker             "layout (points, max_vertices = 3) out;\n" +
4426*35238bceSAndroid Build Coastguard Worker             std::string(s_geometryBody);
4427*35238bceSAndroid Build Coastguard Worker 
4428*35238bceSAndroid Build Coastguard Worker         const char *const vtxSourcePtr  = vertexSource.c_str();
4429*35238bceSAndroid Build Coastguard Worker         const char *const fragSourcePtr = fragmentSource.c_str();
4430*35238bceSAndroid Build Coastguard Worker         const char *const geomSourcePtr = geometrySource.c_str();
4431*35238bceSAndroid Build Coastguard Worker 
4432*35238bceSAndroid Build Coastguard Worker         glu::Shader vertexShader(m_context.getRenderContext(), glu::SHADERTYPE_VERTEX);
4433*35238bceSAndroid Build Coastguard Worker         glu::Shader fragmentShader(m_context.getRenderContext(), glu::SHADERTYPE_FRAGMENT);
4434*35238bceSAndroid Build Coastguard Worker         glu::Shader geometryShader(m_context.getRenderContext(), glu::SHADERTYPE_GEOMETRY);
4435*35238bceSAndroid Build Coastguard Worker         glu::Program program(m_context.getRenderContext());
4436*35238bceSAndroid Build Coastguard Worker 
4437*35238bceSAndroid Build Coastguard Worker         vertexShader.setSources(1, &vtxSourcePtr, DE_NULL);
4438*35238bceSAndroid Build Coastguard Worker         fragmentShader.setSources(1, &fragSourcePtr, DE_NULL);
4439*35238bceSAndroid Build Coastguard Worker         geometryShader.setSources(1, &geomSourcePtr, DE_NULL);
4440*35238bceSAndroid Build Coastguard Worker 
4441*35238bceSAndroid Build Coastguard Worker         vertexShader.compile();
4442*35238bceSAndroid Build Coastguard Worker         fragmentShader.compile();
4443*35238bceSAndroid Build Coastguard Worker         geometryShader.compile();
4444*35238bceSAndroid Build Coastguard Worker 
4445*35238bceSAndroid Build Coastguard Worker         if (!vertexShader.getCompileStatus() || !fragmentShader.getCompileStatus() ||
4446*35238bceSAndroid Build Coastguard Worker             !geometryShader.getCompileStatus())
4447*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Failed to compile shader");
4448*35238bceSAndroid Build Coastguard Worker 
4449*35238bceSAndroid Build Coastguard Worker         program.attachShader(vertexShader.getShader());
4450*35238bceSAndroid Build Coastguard Worker         program.attachShader(fragmentShader.getShader());
4451*35238bceSAndroid Build Coastguard Worker         program.attachShader(geometryShader.getShader());
4452*35238bceSAndroid Build Coastguard Worker 
4453*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Creating a program with geometry shader, but not linking it"
4454*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4455*35238bceSAndroid Build Coastguard Worker 
4456*35238bceSAndroid Build Coastguard Worker         expectQueryError(program.getProgram());
4457*35238bceSAndroid Build Coastguard Worker     }
4458*35238bceSAndroid Build Coastguard Worker 
4459*35238bceSAndroid Build Coastguard Worker     return STOP;
4460*35238bceSAndroid Build Coastguard Worker }
4461*35238bceSAndroid Build Coastguard Worker 
expectProgramValue(uint32_t program,int value)4462*35238bceSAndroid Build Coastguard Worker void GeometryProgramQueryCase::expectProgramValue(uint32_t program, int value)
4463*35238bceSAndroid Build Coastguard Worker {
4464*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4465*35238bceSAndroid Build Coastguard Worker     gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> state;
4466*35238bceSAndroid Build Coastguard Worker 
4467*35238bceSAndroid Build Coastguard Worker     gl.getProgramiv(program, m_target, &state);
4468*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
4469*35238bceSAndroid Build Coastguard Worker 
4470*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramParamStr(m_target) << " = " << state
4471*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
4472*35238bceSAndroid Build Coastguard Worker 
4473*35238bceSAndroid Build Coastguard Worker     if (state != value)
4474*35238bceSAndroid Build Coastguard Worker     {
4475*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected " << value << ", got " << state
4476*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4477*35238bceSAndroid Build Coastguard Worker 
4478*35238bceSAndroid Build Coastguard Worker         // don't overwrite error
4479*35238bceSAndroid Build Coastguard Worker         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
4480*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
4481*35238bceSAndroid Build Coastguard Worker     }
4482*35238bceSAndroid Build Coastguard Worker }
4483*35238bceSAndroid Build Coastguard Worker 
expectQueryError(uint32_t program)4484*35238bceSAndroid Build Coastguard Worker void GeometryProgramQueryCase::expectQueryError(uint32_t program)
4485*35238bceSAndroid Build Coastguard Worker {
4486*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4487*35238bceSAndroid Build Coastguard Worker     glw::GLint unused;
4488*35238bceSAndroid Build Coastguard Worker     glw::GLenum errorCode;
4489*35238bceSAndroid Build Coastguard Worker 
4490*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramParamStr(m_target)
4491*35238bceSAndroid Build Coastguard Worker                        << ", expecting INVALID_OPERATION" << tcu::TestLog::EndMessage;
4492*35238bceSAndroid Build Coastguard Worker     gl.getProgramiv(program, m_target, &unused);
4493*35238bceSAndroid Build Coastguard Worker 
4494*35238bceSAndroid Build Coastguard Worker     errorCode = gl.getError();
4495*35238bceSAndroid Build Coastguard Worker 
4496*35238bceSAndroid Build Coastguard Worker     if (errorCode != GL_INVALID_OPERATION)
4497*35238bceSAndroid Build Coastguard Worker     {
4498*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: Expected INVALID_OPERATION, got "
4499*35238bceSAndroid Build Coastguard Worker                            << glu::getErrorStr(errorCode) << tcu::TestLog::EndMessage;
4500*35238bceSAndroid Build Coastguard Worker 
4501*35238bceSAndroid Build Coastguard Worker         // don't overwrite error
4502*35238bceSAndroid Build Coastguard Worker         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
4503*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected error code");
4504*35238bceSAndroid Build Coastguard Worker     }
4505*35238bceSAndroid Build Coastguard Worker }
4506*35238bceSAndroid Build Coastguard Worker 
4507*35238bceSAndroid Build Coastguard Worker class GeometryShaderInvocationsQueryCase : public GeometryProgramQueryCase
4508*35238bceSAndroid Build Coastguard Worker {
4509*35238bceSAndroid Build Coastguard Worker public:
4510*35238bceSAndroid Build Coastguard Worker     GeometryShaderInvocationsQueryCase(Context &context, const char *name, const char *description);
4511*35238bceSAndroid Build Coastguard Worker };
4512*35238bceSAndroid Build Coastguard Worker 
GeometryShaderInvocationsQueryCase(Context & context,const char * name,const char * description)4513*35238bceSAndroid Build Coastguard Worker GeometryShaderInvocationsQueryCase::GeometryShaderInvocationsQueryCase(Context &context, const char *name,
4514*35238bceSAndroid Build Coastguard Worker                                                                        const char *description)
4515*35238bceSAndroid Build Coastguard Worker     : GeometryProgramQueryCase(context, name, description, GL_GEOMETRY_SHADER_INVOCATIONS)
4516*35238bceSAndroid Build Coastguard Worker {
4517*35238bceSAndroid Build Coastguard Worker     // 2 normal cases
4518*35238bceSAndroid Build Coastguard Worker     m_cases.resize(2);
4519*35238bceSAndroid Build Coastguard Worker 
4520*35238bceSAndroid Build Coastguard Worker     m_cases[0].description = "Default value";
4521*35238bceSAndroid Build Coastguard Worker     m_cases[0].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout (points, "
4522*35238bceSAndroid Build Coastguard Worker                              "max_vertices = 3) out;\n";
4523*35238bceSAndroid Build Coastguard Worker     m_cases[0].value       = 1;
4524*35238bceSAndroid Build Coastguard Worker 
4525*35238bceSAndroid Build Coastguard Worker     m_cases[1].description = "Value declared";
4526*35238bceSAndroid Build Coastguard Worker     m_cases[1].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles, invocations=2) "
4527*35238bceSAndroid Build Coastguard Worker                              "in;\nlayout (points, max_vertices = 3) out;\n";
4528*35238bceSAndroid Build Coastguard Worker     m_cases[1].value       = 2;
4529*35238bceSAndroid Build Coastguard Worker }
4530*35238bceSAndroid Build Coastguard Worker 
4531*35238bceSAndroid Build Coastguard Worker class GeometryShaderVerticesQueryCase : public GeometryProgramQueryCase
4532*35238bceSAndroid Build Coastguard Worker {
4533*35238bceSAndroid Build Coastguard Worker public:
4534*35238bceSAndroid Build Coastguard Worker     GeometryShaderVerticesQueryCase(Context &context, const char *name, const char *description);
4535*35238bceSAndroid Build Coastguard Worker };
4536*35238bceSAndroid Build Coastguard Worker 
GeometryShaderVerticesQueryCase(Context & context,const char * name,const char * description)4537*35238bceSAndroid Build Coastguard Worker GeometryShaderVerticesQueryCase::GeometryShaderVerticesQueryCase(Context &context, const char *name,
4538*35238bceSAndroid Build Coastguard Worker                                                                  const char *description)
4539*35238bceSAndroid Build Coastguard Worker     : GeometryProgramQueryCase(context, name, description, GL_GEOMETRY_LINKED_VERTICES_OUT_EXT)
4540*35238bceSAndroid Build Coastguard Worker {
4541*35238bceSAndroid Build Coastguard Worker     m_cases.resize(1);
4542*35238bceSAndroid Build Coastguard Worker 
4543*35238bceSAndroid Build Coastguard Worker     m_cases[0].description = "max_vertices = 1";
4544*35238bceSAndroid Build Coastguard Worker     m_cases[0].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout (points, "
4545*35238bceSAndroid Build Coastguard Worker                              "max_vertices = 1) out;\n";
4546*35238bceSAndroid Build Coastguard Worker     m_cases[0].value       = 1;
4547*35238bceSAndroid Build Coastguard Worker }
4548*35238bceSAndroid Build Coastguard Worker 
4549*35238bceSAndroid Build Coastguard Worker class GeometryShaderInputQueryCase : public GeometryProgramQueryCase
4550*35238bceSAndroid Build Coastguard Worker {
4551*35238bceSAndroid Build Coastguard Worker public:
4552*35238bceSAndroid Build Coastguard Worker     GeometryShaderInputQueryCase(Context &context, const char *name, const char *description);
4553*35238bceSAndroid Build Coastguard Worker };
4554*35238bceSAndroid Build Coastguard Worker 
GeometryShaderInputQueryCase(Context & context,const char * name,const char * description)4555*35238bceSAndroid Build Coastguard Worker GeometryShaderInputQueryCase::GeometryShaderInputQueryCase(Context &context, const char *name, const char *description)
4556*35238bceSAndroid Build Coastguard Worker     : GeometryProgramQueryCase(context, name, description, GL_GEOMETRY_LINKED_INPUT_TYPE_EXT)
4557*35238bceSAndroid Build Coastguard Worker {
4558*35238bceSAndroid Build Coastguard Worker     m_cases.resize(3);
4559*35238bceSAndroid Build Coastguard Worker 
4560*35238bceSAndroid Build Coastguard Worker     m_cases[0].description = "Triangles";
4561*35238bceSAndroid Build Coastguard Worker     m_cases[0].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout (points, "
4562*35238bceSAndroid Build Coastguard Worker                              "max_vertices = 3) out;\n";
4563*35238bceSAndroid Build Coastguard Worker     m_cases[0].value       = GL_TRIANGLES;
4564*35238bceSAndroid Build Coastguard Worker 
4565*35238bceSAndroid Build Coastguard Worker     m_cases[1].description = "Lines";
4566*35238bceSAndroid Build Coastguard Worker     m_cases[1].header =
4567*35238bceSAndroid Build Coastguard Worker         "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (lines) in;\nlayout (points, max_vertices = 3) out;\n";
4568*35238bceSAndroid Build Coastguard Worker     m_cases[1].value = GL_LINES;
4569*35238bceSAndroid Build Coastguard Worker 
4570*35238bceSAndroid Build Coastguard Worker     m_cases[2].description = "Points";
4571*35238bceSAndroid Build Coastguard Worker     m_cases[2].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (points) in;\nlayout (points, "
4572*35238bceSAndroid Build Coastguard Worker                              "max_vertices = 3) out;\n";
4573*35238bceSAndroid Build Coastguard Worker     m_cases[2].value       = GL_POINTS;
4574*35238bceSAndroid Build Coastguard Worker }
4575*35238bceSAndroid Build Coastguard Worker 
4576*35238bceSAndroid Build Coastguard Worker class GeometryShaderOutputQueryCase : public GeometryProgramQueryCase
4577*35238bceSAndroid Build Coastguard Worker {
4578*35238bceSAndroid Build Coastguard Worker public:
4579*35238bceSAndroid Build Coastguard Worker     GeometryShaderOutputQueryCase(Context &context, const char *name, const char *description);
4580*35238bceSAndroid Build Coastguard Worker };
4581*35238bceSAndroid Build Coastguard Worker 
GeometryShaderOutputQueryCase(Context & context,const char * name,const char * description)4582*35238bceSAndroid Build Coastguard Worker GeometryShaderOutputQueryCase::GeometryShaderOutputQueryCase(Context &context, const char *name,
4583*35238bceSAndroid Build Coastguard Worker                                                              const char *description)
4584*35238bceSAndroid Build Coastguard Worker     : GeometryProgramQueryCase(context, name, description, GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT)
4585*35238bceSAndroid Build Coastguard Worker {
4586*35238bceSAndroid Build Coastguard Worker     m_cases.resize(3);
4587*35238bceSAndroid Build Coastguard Worker 
4588*35238bceSAndroid Build Coastguard Worker     m_cases[0].description = "Triangle strip";
4589*35238bceSAndroid Build Coastguard Worker     m_cases[0].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout "
4590*35238bceSAndroid Build Coastguard Worker                              "(triangle_strip, max_vertices = 3) out;\n";
4591*35238bceSAndroid Build Coastguard Worker     m_cases[0].value       = GL_TRIANGLE_STRIP;
4592*35238bceSAndroid Build Coastguard Worker 
4593*35238bceSAndroid Build Coastguard Worker     m_cases[1].description = "Lines";
4594*35238bceSAndroid Build Coastguard Worker     m_cases[1].header = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout (line_strip, "
4595*35238bceSAndroid Build Coastguard Worker                         "max_vertices = 3) out;\n";
4596*35238bceSAndroid Build Coastguard Worker     m_cases[1].value  = GL_LINE_STRIP;
4597*35238bceSAndroid Build Coastguard Worker 
4598*35238bceSAndroid Build Coastguard Worker     m_cases[2].description = "Points";
4599*35238bceSAndroid Build Coastguard Worker     m_cases[2].header      = "${GLSL_VERSION_DECL}\n${GLSL_EXT_GEOMETRY_SHADER}layout (triangles) in;\nlayout (points, "
4600*35238bceSAndroid Build Coastguard Worker                              "max_vertices = 3) out;\n";
4601*35238bceSAndroid Build Coastguard Worker     m_cases[2].value       = GL_POINTS;
4602*35238bceSAndroid Build Coastguard Worker }
4603*35238bceSAndroid Build Coastguard Worker 
4604*35238bceSAndroid Build Coastguard Worker class ImplementationLimitCase : public TestCase
4605*35238bceSAndroid Build Coastguard Worker {
4606*35238bceSAndroid Build Coastguard Worker public:
4607*35238bceSAndroid Build Coastguard Worker     ImplementationLimitCase(Context &context, const char *name, const char *description, glw::GLenum target,
4608*35238bceSAndroid Build Coastguard Worker                             int minValue);
4609*35238bceSAndroid Build Coastguard Worker 
4610*35238bceSAndroid Build Coastguard Worker     void init(void);
4611*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
4612*35238bceSAndroid Build Coastguard Worker 
4613*35238bceSAndroid Build Coastguard Worker     const glw::GLenum m_target;
4614*35238bceSAndroid Build Coastguard Worker     const int m_minValue;
4615*35238bceSAndroid Build Coastguard Worker };
4616*35238bceSAndroid Build Coastguard Worker 
ImplementationLimitCase(Context & context,const char * name,const char * description,glw::GLenum target,int minValue)4617*35238bceSAndroid Build Coastguard Worker ImplementationLimitCase::ImplementationLimitCase(Context &context, const char *name, const char *description,
4618*35238bceSAndroid Build Coastguard Worker                                                  glw::GLenum target, int minValue)
4619*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
4620*35238bceSAndroid Build Coastguard Worker     , m_target(target)
4621*35238bceSAndroid Build Coastguard Worker     , m_minValue(minValue)
4622*35238bceSAndroid Build Coastguard Worker {
4623*35238bceSAndroid Build Coastguard Worker }
4624*35238bceSAndroid Build Coastguard Worker 
init(void)4625*35238bceSAndroid Build Coastguard Worker void ImplementationLimitCase::init(void)
4626*35238bceSAndroid Build Coastguard Worker {
4627*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4628*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4629*35238bceSAndroid Build Coastguard Worker }
4630*35238bceSAndroid Build Coastguard Worker 
iterate(void)4631*35238bceSAndroid Build Coastguard Worker ImplementationLimitCase::IterateResult ImplementationLimitCase::iterate(void)
4632*35238bceSAndroid Build Coastguard Worker {
4633*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
4634*35238bceSAndroid Build Coastguard Worker     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
4635*35238bceSAndroid Build Coastguard Worker 
4636*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
4637*35238bceSAndroid Build Coastguard Worker     verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER);
4638*35238bceSAndroid Build Coastguard Worker 
4639*35238bceSAndroid Build Coastguard Worker     {
4640*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries");
4641*35238bceSAndroid Build Coastguard Worker         verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_BOOLEAN);
4642*35238bceSAndroid Build Coastguard Worker         verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER64);
4643*35238bceSAndroid Build Coastguard Worker         verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_FLOAT);
4644*35238bceSAndroid Build Coastguard Worker     }
4645*35238bceSAndroid Build Coastguard Worker 
4646*35238bceSAndroid Build Coastguard Worker     result.setTestContextResult(m_testCtx);
4647*35238bceSAndroid Build Coastguard Worker     return STOP;
4648*35238bceSAndroid Build Coastguard Worker }
4649*35238bceSAndroid Build Coastguard Worker 
4650*35238bceSAndroid Build Coastguard Worker class LayerProvokingVertexQueryCase : public TestCase
4651*35238bceSAndroid Build Coastguard Worker {
4652*35238bceSAndroid Build Coastguard Worker public:
4653*35238bceSAndroid Build Coastguard Worker     LayerProvokingVertexQueryCase(Context &context, const char *name, const char *description);
4654*35238bceSAndroid Build Coastguard Worker 
4655*35238bceSAndroid Build Coastguard Worker     void init(void);
4656*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
4657*35238bceSAndroid Build Coastguard Worker };
4658*35238bceSAndroid Build Coastguard Worker 
LayerProvokingVertexQueryCase(Context & context,const char * name,const char * description)4659*35238bceSAndroid Build Coastguard Worker LayerProvokingVertexQueryCase::LayerProvokingVertexQueryCase(Context &context, const char *name,
4660*35238bceSAndroid Build Coastguard Worker                                                              const char *description)
4661*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
4662*35238bceSAndroid Build Coastguard Worker {
4663*35238bceSAndroid Build Coastguard Worker }
4664*35238bceSAndroid Build Coastguard Worker 
init(void)4665*35238bceSAndroid Build Coastguard Worker void LayerProvokingVertexQueryCase::init(void)
4666*35238bceSAndroid Build Coastguard Worker {
4667*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4668*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4669*35238bceSAndroid Build Coastguard Worker }
4670*35238bceSAndroid Build Coastguard Worker 
iterate(void)4671*35238bceSAndroid Build Coastguard Worker LayerProvokingVertexQueryCase::IterateResult LayerProvokingVertexQueryCase::iterate(void)
4672*35238bceSAndroid Build Coastguard Worker {
4673*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
4674*35238bceSAndroid Build Coastguard Worker     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
4675*35238bceSAndroid Build Coastguard Worker     QueriedState state;
4676*35238bceSAndroid Build Coastguard Worker 
4677*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
4678*35238bceSAndroid Build Coastguard Worker     queryState(result, gl, QUERY_INTEGER, GL_LAYER_PROVOKING_VERTEX, state);
4679*35238bceSAndroid Build Coastguard Worker 
4680*35238bceSAndroid Build Coastguard Worker     if (!state.isUndefined())
4681*35238bceSAndroid Build Coastguard Worker     {
4682*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
4683*35238bceSAndroid Build Coastguard Worker                            << "LAYER_PROVOKING_VERTEX = " << glu::getProvokingVertexStr(state.getIntAccess())
4684*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4685*35238bceSAndroid Build Coastguard Worker 
4686*35238bceSAndroid Build Coastguard Worker         bool ok = true;
4687*35238bceSAndroid Build Coastguard Worker         std::string expectedValue;
4688*35238bceSAndroid Build Coastguard Worker 
4689*35238bceSAndroid Build Coastguard Worker         if (contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)))
4690*35238bceSAndroid Build Coastguard Worker         {
4691*35238bceSAndroid Build Coastguard Worker             if (state.getIntAccess() != GL_FIRST_VERTEX_CONVENTION &&
4692*35238bceSAndroid Build Coastguard Worker                 state.getIntAccess() != GL_LAST_VERTEX_CONVENTION && state.getIntAccess() != GL_PROVOKING_VERTEX &&
4693*35238bceSAndroid Build Coastguard Worker                 state.getIntAccess() != GL_UNDEFINED_VERTEX)
4694*35238bceSAndroid Build Coastguard Worker             {
4695*35238bceSAndroid Build Coastguard Worker                 ok = false;
4696*35238bceSAndroid Build Coastguard Worker                 expectedValue =
4697*35238bceSAndroid Build Coastguard Worker                     "any of {FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, GL_PROVOKING_VERTEX, UNDEFINED_VERTEX}";
4698*35238bceSAndroid Build Coastguard Worker             }
4699*35238bceSAndroid Build Coastguard Worker         }
4700*35238bceSAndroid Build Coastguard Worker         else if (state.getIntAccess() != GL_FIRST_VERTEX_CONVENTION &&
4701*35238bceSAndroid Build Coastguard Worker                  state.getIntAccess() != GL_LAST_VERTEX_CONVENTION && state.getIntAccess() != GL_UNDEFINED_VERTEX)
4702*35238bceSAndroid Build Coastguard Worker         {
4703*35238bceSAndroid Build Coastguard Worker             ok            = false;
4704*35238bceSAndroid Build Coastguard Worker             expectedValue = "any of {FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, UNDEFINED_VERTEX}";
4705*35238bceSAndroid Build Coastguard Worker         }
4706*35238bceSAndroid Build Coastguard Worker 
4707*35238bceSAndroid Build Coastguard Worker         if (!ok)
4708*35238bceSAndroid Build Coastguard Worker         {
4709*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
4710*35238bceSAndroid Build Coastguard Worker                                << "getInteger(GL_LAYER_PROVOKING_VERTEX) returned illegal value. Got "
4711*35238bceSAndroid Build Coastguard Worker                                << state.getIntAccess() << "\n"
4712*35238bceSAndroid Build Coastguard Worker                                << "Expected " << expectedValue << "." << tcu::TestLog::EndMessage;
4713*35238bceSAndroid Build Coastguard Worker 
4714*35238bceSAndroid Build Coastguard Worker             result.fail("got unexpected provoking vertex value");
4715*35238bceSAndroid Build Coastguard Worker         }
4716*35238bceSAndroid Build Coastguard Worker 
4717*35238bceSAndroid Build Coastguard Worker         {
4718*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries");
4719*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, GL_LAYER_PROVOKING_VERTEX, state.getIntAccess(), QUERY_BOOLEAN);
4720*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, GL_LAYER_PROVOKING_VERTEX, state.getIntAccess(), QUERY_INTEGER64);
4721*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, GL_LAYER_PROVOKING_VERTEX, state.getIntAccess(), QUERY_FLOAT);
4722*35238bceSAndroid Build Coastguard Worker         }
4723*35238bceSAndroid Build Coastguard Worker     }
4724*35238bceSAndroid Build Coastguard Worker 
4725*35238bceSAndroid Build Coastguard Worker     result.setTestContextResult(m_testCtx);
4726*35238bceSAndroid Build Coastguard Worker     return STOP;
4727*35238bceSAndroid Build Coastguard Worker }
4728*35238bceSAndroid Build Coastguard Worker 
4729*35238bceSAndroid Build Coastguard Worker class GeometryInvocationCase : public GeometryShaderRenderTest
4730*35238bceSAndroid Build Coastguard Worker {
4731*35238bceSAndroid Build Coastguard Worker public:
4732*35238bceSAndroid Build Coastguard Worker     enum OutputCase
4733*35238bceSAndroid Build Coastguard Worker     {
4734*35238bceSAndroid Build Coastguard Worker         CASE_FIXED_OUTPUT_COUNTS = 0,
4735*35238bceSAndroid Build Coastguard Worker         CASE_DIFFERENT_OUTPUT_COUNTS,
4736*35238bceSAndroid Build Coastguard Worker 
4737*35238bceSAndroid Build Coastguard Worker         CASE_LAST
4738*35238bceSAndroid Build Coastguard Worker     };
4739*35238bceSAndroid Build Coastguard Worker 
4740*35238bceSAndroid Build Coastguard Worker     GeometryInvocationCase(Context &context, const char *name, const char *description, int numInvocations,
4741*35238bceSAndroid Build Coastguard Worker                            OutputCase testCase);
4742*35238bceSAndroid Build Coastguard Worker     ~GeometryInvocationCase(void);
4743*35238bceSAndroid Build Coastguard Worker 
4744*35238bceSAndroid Build Coastguard Worker     void init(void);
4745*35238bceSAndroid Build Coastguard Worker     void deinit(void);
4746*35238bceSAndroid Build Coastguard Worker 
4747*35238bceSAndroid Build Coastguard Worker private:
4748*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
4749*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
4750*35238bceSAndroid Build Coastguard Worker 
4751*35238bceSAndroid Build Coastguard Worker     static InvocationCountShader::OutputCase mapToShaderCaseType(OutputCase testCase);
4752*35238bceSAndroid Build Coastguard Worker 
4753*35238bceSAndroid Build Coastguard Worker     const OutputCase m_testCase;
4754*35238bceSAndroid Build Coastguard Worker     int m_numInvocations;
4755*35238bceSAndroid Build Coastguard Worker     InvocationCountShader *m_program;
4756*35238bceSAndroid Build Coastguard Worker };
4757*35238bceSAndroid Build Coastguard Worker 
GeometryInvocationCase(Context & context,const char * name,const char * description,int numInvocations,OutputCase testCase)4758*35238bceSAndroid Build Coastguard Worker GeometryInvocationCase::GeometryInvocationCase(Context &context, const char *name, const char *description,
4759*35238bceSAndroid Build Coastguard Worker                                                int numInvocations, OutputCase testCase)
4760*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, description, GL_POINTS, GL_TRIANGLE_STRIP, "a_color")
4761*35238bceSAndroid Build Coastguard Worker     , m_testCase(testCase)
4762*35238bceSAndroid Build Coastguard Worker     , m_numInvocations(numInvocations)
4763*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
4764*35238bceSAndroid Build Coastguard Worker {
4765*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_testCase < CASE_LAST);
4766*35238bceSAndroid Build Coastguard Worker }
4767*35238bceSAndroid Build Coastguard Worker 
~GeometryInvocationCase(void)4768*35238bceSAndroid Build Coastguard Worker GeometryInvocationCase::~GeometryInvocationCase(void)
4769*35238bceSAndroid Build Coastguard Worker {
4770*35238bceSAndroid Build Coastguard Worker     deinit();
4771*35238bceSAndroid Build Coastguard Worker }
4772*35238bceSAndroid Build Coastguard Worker 
init(void)4773*35238bceSAndroid Build Coastguard Worker void GeometryInvocationCase::init(void)
4774*35238bceSAndroid Build Coastguard Worker {
4775*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl         = m_context.getRenderContext().getFunctions();
4776*35238bceSAndroid Build Coastguard Worker     int maxGeometryShaderInvocations = 0;
4777*35238bceSAndroid Build Coastguard Worker     int maxComponents                = 0;
4778*35238bceSAndroid Build Coastguard Worker 
4779*35238bceSAndroid Build Coastguard Worker     // requirements
4780*35238bceSAndroid Build Coastguard Worker 
4781*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4782*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4783*35238bceSAndroid Build Coastguard Worker 
4784*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &maxGeometryShaderInvocations);
4785*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS)");
4786*35238bceSAndroid Build Coastguard Worker 
4787*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &maxComponents);
4788*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS)");
4789*35238bceSAndroid Build Coastguard Worker 
4790*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
4791*35238bceSAndroid Build Coastguard Worker                        << "GL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << maxGeometryShaderInvocations
4792*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
4793*35238bceSAndroid Build Coastguard Worker 
4794*35238bceSAndroid Build Coastguard Worker     // set target num invocations
4795*35238bceSAndroid Build Coastguard Worker 
4796*35238bceSAndroid Build Coastguard Worker     if (m_numInvocations == -1)
4797*35238bceSAndroid Build Coastguard Worker         m_numInvocations = maxGeometryShaderInvocations;
4798*35238bceSAndroid Build Coastguard Worker     else if (maxGeometryShaderInvocations < m_numInvocations)
4799*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires larger GL_MAX_GEOMETRY_SHADER_INVOCATIONS");
4800*35238bceSAndroid Build Coastguard Worker 
4801*35238bceSAndroid Build Coastguard Worker     if (m_testCase == CASE_DIFFERENT_OUTPUT_COUNTS)
4802*35238bceSAndroid Build Coastguard Worker     {
4803*35238bceSAndroid Build Coastguard Worker         const int maxEmitCount  = m_numInvocations + 2;
4804*35238bceSAndroid Build Coastguard Worker         const int numComponents = 8; // pos + color
4805*35238bceSAndroid Build Coastguard Worker         if (maxEmitCount * numComponents > maxComponents)
4806*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Test requires larger GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS");
4807*35238bceSAndroid Build Coastguard Worker     }
4808*35238bceSAndroid Build Coastguard Worker 
4809*35238bceSAndroid Build Coastguard Worker     // Log what the test tries to do
4810*35238bceSAndroid Build Coastguard Worker 
4811*35238bceSAndroid Build Coastguard Worker     if (m_testCase == CASE_FIXED_OUTPUT_COUNTS)
4812*35238bceSAndroid Build Coastguard Worker     {
4813*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
4814*35238bceSAndroid Build Coastguard Worker                            << "Rendering triangles in a partial circle formation with a geometry shader. Each triangle "
4815*35238bceSAndroid Build Coastguard Worker                               "is generated by a separate invocation.\n"
4816*35238bceSAndroid Build Coastguard Worker                            << "Drawing 2 points, each generating " << m_numInvocations << " triangles."
4817*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4818*35238bceSAndroid Build Coastguard Worker     }
4819*35238bceSAndroid Build Coastguard Worker     else if (m_testCase == CASE_DIFFERENT_OUTPUT_COUNTS)
4820*35238bceSAndroid Build Coastguard Worker     {
4821*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
4822*35238bceSAndroid Build Coastguard Worker                            << "Rendering n-gons in a partial circle formation with a geometry shader. Each n-gon is "
4823*35238bceSAndroid Build Coastguard Worker                               "generated by a separate invocation.\n"
4824*35238bceSAndroid Build Coastguard Worker                            << "Drawing 2 points, each generating " << m_numInvocations << " n-gons."
4825*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4826*35238bceSAndroid Build Coastguard Worker     }
4827*35238bceSAndroid Build Coastguard Worker     else
4828*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4829*35238bceSAndroid Build Coastguard Worker 
4830*35238bceSAndroid Build Coastguard Worker     // resources
4831*35238bceSAndroid Build Coastguard Worker 
4832*35238bceSAndroid Build Coastguard Worker     m_program = new InvocationCountShader(m_context.getRenderContext().getType(), m_numInvocations,
4833*35238bceSAndroid Build Coastguard Worker                                           mapToShaderCaseType(m_testCase));
4834*35238bceSAndroid Build Coastguard Worker 
4835*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
4836*35238bceSAndroid Build Coastguard Worker }
4837*35238bceSAndroid Build Coastguard Worker 
deinit(void)4838*35238bceSAndroid Build Coastguard Worker void GeometryInvocationCase::deinit(void)
4839*35238bceSAndroid Build Coastguard Worker {
4840*35238bceSAndroid Build Coastguard Worker     if (m_program)
4841*35238bceSAndroid Build Coastguard Worker     {
4842*35238bceSAndroid Build Coastguard Worker         delete m_program;
4843*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
4844*35238bceSAndroid Build Coastguard Worker     }
4845*35238bceSAndroid Build Coastguard Worker 
4846*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
4847*35238bceSAndroid Build Coastguard Worker }
4848*35238bceSAndroid Build Coastguard Worker 
getProgram(void)4849*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &GeometryInvocationCase::getProgram(void)
4850*35238bceSAndroid Build Coastguard Worker {
4851*35238bceSAndroid Build Coastguard Worker     return *m_program;
4852*35238bceSAndroid Build Coastguard Worker }
4853*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)4854*35238bceSAndroid Build Coastguard Worker void GeometryInvocationCase::genVertexAttribData(void)
4855*35238bceSAndroid Build Coastguard Worker {
4856*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(2);
4857*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.0f, -0.3f, 0.0f, 1.0f);
4858*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[1] = tcu::Vec4(0.2f, 0.3f, 0.0f, 1.0f);
4859*35238bceSAndroid Build Coastguard Worker 
4860*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(2);
4861*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[0] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
4862*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[1] = tcu::Vec4(0.8f, 0.8f, 0.8f, 1.0f);
4863*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices   = 2;
4864*35238bceSAndroid Build Coastguard Worker }
4865*35238bceSAndroid Build Coastguard Worker 
mapToShaderCaseType(OutputCase testCase)4866*35238bceSAndroid Build Coastguard Worker InvocationCountShader::OutputCase GeometryInvocationCase::mapToShaderCaseType(OutputCase testCase)
4867*35238bceSAndroid Build Coastguard Worker {
4868*35238bceSAndroid Build Coastguard Worker     switch (testCase)
4869*35238bceSAndroid Build Coastguard Worker     {
4870*35238bceSAndroid Build Coastguard Worker     case CASE_FIXED_OUTPUT_COUNTS:
4871*35238bceSAndroid Build Coastguard Worker         return InvocationCountShader::CASE_FIXED_OUTPUT_COUNTS;
4872*35238bceSAndroid Build Coastguard Worker     case CASE_DIFFERENT_OUTPUT_COUNTS:
4873*35238bceSAndroid Build Coastguard Worker         return InvocationCountShader::CASE_DIFFERENT_OUTPUT_COUNTS;
4874*35238bceSAndroid Build Coastguard Worker     default:
4875*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
4876*35238bceSAndroid Build Coastguard Worker         return InvocationCountShader::CASE_LAST;
4877*35238bceSAndroid Build Coastguard Worker     }
4878*35238bceSAndroid Build Coastguard Worker }
4879*35238bceSAndroid Build Coastguard Worker 
4880*35238bceSAndroid Build Coastguard Worker class DrawInstancedGeometryInstancedCase : public GeometryShaderRenderTest
4881*35238bceSAndroid Build Coastguard Worker {
4882*35238bceSAndroid Build Coastguard Worker public:
4883*35238bceSAndroid Build Coastguard Worker     DrawInstancedGeometryInstancedCase(Context &context, const char *name, const char *description, int numInstances,
4884*35238bceSAndroid Build Coastguard Worker                                        int numInvocations);
4885*35238bceSAndroid Build Coastguard Worker     ~DrawInstancedGeometryInstancedCase(void);
4886*35238bceSAndroid Build Coastguard Worker 
4887*35238bceSAndroid Build Coastguard Worker private:
4888*35238bceSAndroid Build Coastguard Worker     void init(void);
4889*35238bceSAndroid Build Coastguard Worker     void deinit(void);
4890*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram &getProgram(void);
4891*35238bceSAndroid Build Coastguard Worker     void genVertexAttribData(void);
4892*35238bceSAndroid Build Coastguard Worker 
4893*35238bceSAndroid Build Coastguard Worker     const int m_numInstances;
4894*35238bceSAndroid Build Coastguard Worker     const int m_numInvocations;
4895*35238bceSAndroid Build Coastguard Worker     InstancedExpansionShader *m_program;
4896*35238bceSAndroid Build Coastguard Worker };
4897*35238bceSAndroid Build Coastguard Worker 
DrawInstancedGeometryInstancedCase(Context & context,const char * name,const char * description,int numInstances,int numInvocations)4898*35238bceSAndroid Build Coastguard Worker DrawInstancedGeometryInstancedCase::DrawInstancedGeometryInstancedCase(Context &context, const char *name,
4899*35238bceSAndroid Build Coastguard Worker                                                                        const char *description, int numInstances,
4900*35238bceSAndroid Build Coastguard Worker                                                                        int numInvocations)
4901*35238bceSAndroid Build Coastguard Worker     : GeometryShaderRenderTest(context, name, description, GL_POINTS, GL_TRIANGLE_STRIP, "a_offset",
4902*35238bceSAndroid Build Coastguard Worker                                FLAG_DRAW_INSTANCED)
4903*35238bceSAndroid Build Coastguard Worker     , m_numInstances(numInstances)
4904*35238bceSAndroid Build Coastguard Worker     , m_numInvocations(numInvocations)
4905*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
4906*35238bceSAndroid Build Coastguard Worker {
4907*35238bceSAndroid Build Coastguard Worker }
4908*35238bceSAndroid Build Coastguard Worker 
~DrawInstancedGeometryInstancedCase(void)4909*35238bceSAndroid Build Coastguard Worker DrawInstancedGeometryInstancedCase::~DrawInstancedGeometryInstancedCase(void)
4910*35238bceSAndroid Build Coastguard Worker {
4911*35238bceSAndroid Build Coastguard Worker }
4912*35238bceSAndroid Build Coastguard Worker 
init(void)4913*35238bceSAndroid Build Coastguard Worker void DrawInstancedGeometryInstancedCase::init(void)
4914*35238bceSAndroid Build Coastguard Worker {
4915*35238bceSAndroid Build Coastguard Worker     m_program = new InstancedExpansionShader(m_context.getRenderContext().getType(), m_numInvocations);
4916*35238bceSAndroid Build Coastguard Worker 
4917*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Rendering a single point with " << m_numInstances << " instances. "
4918*35238bceSAndroid Build Coastguard Worker                        << "Each geometry shader is invoked " << m_numInvocations << " times for each primitive. "
4919*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
4920*35238bceSAndroid Build Coastguard Worker 
4921*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::init();
4922*35238bceSAndroid Build Coastguard Worker }
4923*35238bceSAndroid Build Coastguard Worker 
deinit(void)4924*35238bceSAndroid Build Coastguard Worker void DrawInstancedGeometryInstancedCase::deinit(void)
4925*35238bceSAndroid Build Coastguard Worker {
4926*35238bceSAndroid Build Coastguard Worker     if (m_program)
4927*35238bceSAndroid Build Coastguard Worker     {
4928*35238bceSAndroid Build Coastguard Worker         delete m_program;
4929*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
4930*35238bceSAndroid Build Coastguard Worker     }
4931*35238bceSAndroid Build Coastguard Worker 
4932*35238bceSAndroid Build Coastguard Worker     GeometryShaderRenderTest::deinit();
4933*35238bceSAndroid Build Coastguard Worker }
4934*35238bceSAndroid Build Coastguard Worker 
getProgram(void)4935*35238bceSAndroid Build Coastguard Worker sglr::ShaderProgram &DrawInstancedGeometryInstancedCase::getProgram(void)
4936*35238bceSAndroid Build Coastguard Worker {
4937*35238bceSAndroid Build Coastguard Worker     return *m_program;
4938*35238bceSAndroid Build Coastguard Worker }
4939*35238bceSAndroid Build Coastguard Worker 
genVertexAttribData(void)4940*35238bceSAndroid Build Coastguard Worker void DrawInstancedGeometryInstancedCase::genVertexAttribData(void)
4941*35238bceSAndroid Build Coastguard Worker {
4942*35238bceSAndroid Build Coastguard Worker     m_numDrawVertices   = 1;
4943*35238bceSAndroid Build Coastguard Worker     m_numDrawInstances  = m_numInstances;
4944*35238bceSAndroid Build Coastguard Worker     m_vertexAttrDivisor = 1;
4945*35238bceSAndroid Build Coastguard Worker 
4946*35238bceSAndroid Build Coastguard Worker     m_vertexPosData.resize(1);
4947*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData.resize(8);
4948*35238bceSAndroid Build Coastguard Worker 
4949*35238bceSAndroid Build Coastguard Worker     m_vertexPosData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
4950*35238bceSAndroid Build Coastguard Worker 
4951*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
4952*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 0.0f);
4953*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 0.0f);
4954*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 0.0f);
4955*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[4] = tcu::Vec4(-0.8f, -0.7f, 0.0f, 0.0f);
4956*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[5] = tcu::Vec4(-0.9f, 0.6f, 0.0f, 0.0f);
4957*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[6] = tcu::Vec4(-0.8f, 0.3f, 0.0f, 0.0f);
4958*35238bceSAndroid Build Coastguard Worker     m_vertexAttrData[7] = tcu::Vec4(-0.1f, 0.1f, 0.0f, 0.0f);
4959*35238bceSAndroid Build Coastguard Worker 
4960*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_numInstances <= (int)m_vertexAttrData.size());
4961*35238bceSAndroid Build Coastguard Worker }
4962*35238bceSAndroid Build Coastguard Worker 
4963*35238bceSAndroid Build Coastguard Worker class GeometryProgramLimitCase : public TestCase
4964*35238bceSAndroid Build Coastguard Worker {
4965*35238bceSAndroid Build Coastguard Worker public:
4966*35238bceSAndroid Build Coastguard Worker     GeometryProgramLimitCase(Context &context, const char *name, const char *description, glw::GLenum apiName,
4967*35238bceSAndroid Build Coastguard Worker                              const std::string &glslName, int limit);
4968*35238bceSAndroid Build Coastguard Worker 
4969*35238bceSAndroid Build Coastguard Worker private:
4970*35238bceSAndroid Build Coastguard Worker     void init(void);
4971*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
4972*35238bceSAndroid Build Coastguard Worker 
4973*35238bceSAndroid Build Coastguard Worker     const glw::GLenum m_apiName;
4974*35238bceSAndroid Build Coastguard Worker     const std::string m_glslName;
4975*35238bceSAndroid Build Coastguard Worker     const int m_limit;
4976*35238bceSAndroid Build Coastguard Worker };
4977*35238bceSAndroid Build Coastguard Worker 
GeometryProgramLimitCase(Context & context,const char * name,const char * description,glw::GLenum apiName,const std::string & glslName,int limit)4978*35238bceSAndroid Build Coastguard Worker GeometryProgramLimitCase::GeometryProgramLimitCase(Context &context, const char *name, const char *description,
4979*35238bceSAndroid Build Coastguard Worker                                                    glw::GLenum apiName, const std::string &glslName, int limit)
4980*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
4981*35238bceSAndroid Build Coastguard Worker     , m_apiName(apiName)
4982*35238bceSAndroid Build Coastguard Worker     , m_glslName(glslName)
4983*35238bceSAndroid Build Coastguard Worker     , m_limit(limit)
4984*35238bceSAndroid Build Coastguard Worker {
4985*35238bceSAndroid Build Coastguard Worker }
4986*35238bceSAndroid Build Coastguard Worker 
init(void)4987*35238bceSAndroid Build Coastguard Worker void GeometryProgramLimitCase::init(void)
4988*35238bceSAndroid Build Coastguard Worker {
4989*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
4990*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
4991*35238bceSAndroid Build Coastguard Worker }
4992*35238bceSAndroid Build Coastguard Worker 
iterate(void)4993*35238bceSAndroid Build Coastguard Worker GeometryProgramLimitCase::IterateResult GeometryProgramLimitCase::iterate(void)
4994*35238bceSAndroid Build Coastguard Worker {
4995*35238bceSAndroid Build Coastguard Worker     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
4996*35238bceSAndroid Build Coastguard Worker     int limit;
4997*35238bceSAndroid Build Coastguard Worker 
4998*35238bceSAndroid Build Coastguard Worker     // query limit
4999*35238bceSAndroid Build Coastguard Worker     {
5000*35238bceSAndroid Build Coastguard Worker         gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> state;
5001*35238bceSAndroid Build Coastguard Worker         glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5002*35238bceSAndroid Build Coastguard Worker 
5003*35238bceSAndroid Build Coastguard Worker         gl.enableLogging(true);
5004*35238bceSAndroid Build Coastguard Worker         gl.glGetIntegerv(m_apiName, &state);
5005*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "getIntegerv()");
5006*35238bceSAndroid Build Coastguard Worker 
5007*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << glu::getGettableStateStr(m_apiName) << " = " << state
5008*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5009*35238bceSAndroid Build Coastguard Worker 
5010*35238bceSAndroid Build Coastguard Worker         if (!state.verifyValidity(result))
5011*35238bceSAndroid Build Coastguard Worker         {
5012*35238bceSAndroid Build Coastguard Worker             result.setTestContextResult(m_testCtx);
5013*35238bceSAndroid Build Coastguard Worker             return STOP;
5014*35238bceSAndroid Build Coastguard Worker         }
5015*35238bceSAndroid Build Coastguard Worker 
5016*35238bceSAndroid Build Coastguard Worker         if (state < m_limit)
5017*35238bceSAndroid Build Coastguard Worker         {
5018*35238bceSAndroid Build Coastguard Worker             result.fail("Minimum value = " + de::toString(m_limit) + ", got " + de::toString(state.get()));
5019*35238bceSAndroid Build Coastguard Worker             result.setTestContextResult(m_testCtx);
5020*35238bceSAndroid Build Coastguard Worker             return STOP;
5021*35238bceSAndroid Build Coastguard Worker         }
5022*35238bceSAndroid Build Coastguard Worker 
5023*35238bceSAndroid Build Coastguard Worker         limit = state;
5024*35238bceSAndroid Build Coastguard Worker 
5025*35238bceSAndroid Build Coastguard Worker         // verify other getters
5026*35238bceSAndroid Build Coastguard Worker         {
5027*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries");
5028*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, m_apiName, limit, QUERY_BOOLEAN);
5029*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, m_apiName, limit, QUERY_INTEGER64);
5030*35238bceSAndroid Build Coastguard Worker             verifyStateInteger(result, gl, m_apiName, limit, QUERY_FLOAT);
5031*35238bceSAndroid Build Coastguard Worker         }
5032*35238bceSAndroid Build Coastguard Worker     }
5033*35238bceSAndroid Build Coastguard Worker 
5034*35238bceSAndroid Build Coastguard Worker     // verify limit is the same in GLSL
5035*35238bceSAndroid Build Coastguard Worker     {
5036*35238bceSAndroid Build Coastguard Worker         static const char *const vertexSource   = "${GLSL_VERSION_DECL}\n"
5037*35238bceSAndroid Build Coastguard Worker                                                   "void main ()\n"
5038*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
5039*35238bceSAndroid Build Coastguard Worker                                                   "    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
5040*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
5041*35238bceSAndroid Build Coastguard Worker         static const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
5042*35238bceSAndroid Build Coastguard Worker                                                   "layout(location = 0) out mediump vec4 fragColor;\n"
5043*35238bceSAndroid Build Coastguard Worker                                                   "void main ()\n"
5044*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
5045*35238bceSAndroid Build Coastguard Worker                                                   "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
5046*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
5047*35238bceSAndroid Build Coastguard Worker         const std::string geometrySource =
5048*35238bceSAndroid Build Coastguard Worker             "${GLSL_VERSION_DECL}\n"
5049*35238bceSAndroid Build Coastguard Worker             "${GLSL_EXT_GEOMETRY_SHADER}"
5050*35238bceSAndroid Build Coastguard Worker             "layout(points) in;\n"
5051*35238bceSAndroid Build Coastguard Worker             "layout(points, max_vertices = 1) out;\n"
5052*35238bceSAndroid Build Coastguard Worker             "void main ()\n"
5053*35238bceSAndroid Build Coastguard Worker             "{\n"
5054*35238bceSAndroid Build Coastguard Worker             "    // Building the shader will fail if the constant value is not the expected\n"
5055*35238bceSAndroid Build Coastguard Worker             "    const mediump int cArraySize = (gl_" +
5056*35238bceSAndroid Build Coastguard Worker             m_glslName + " == " + de::toString(limit) +
5057*35238bceSAndroid Build Coastguard Worker             ") ? (1) : (-1);\n"
5058*35238bceSAndroid Build Coastguard Worker             "    float[cArraySize] fArray;\n"
5059*35238bceSAndroid Build Coastguard Worker             "    fArray[0] = 0.0f;\n"
5060*35238bceSAndroid Build Coastguard Worker             "    gl_Position = vec4(0.0, 0.0, 0.0, fArray[0]);\n"
5061*35238bceSAndroid Build Coastguard Worker             "    EmitVertex();\n"
5062*35238bceSAndroid Build Coastguard Worker             "}\n";
5063*35238bceSAndroid Build Coastguard Worker 
5064*35238bceSAndroid Build Coastguard Worker         const de::UniquePtr<glu::ShaderProgram> program(new glu::ShaderProgram(
5065*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(),
5066*35238bceSAndroid Build Coastguard Worker             glu::ProgramSources() << glu::VertexSource(
5067*35238bceSAndroid Build Coastguard Worker                                          specializeShader(vertexSource, m_context.getRenderContext().getType()))
5068*35238bceSAndroid Build Coastguard Worker                                   << glu::FragmentSource(
5069*35238bceSAndroid Build Coastguard Worker                                          specializeShader(fragmentSource, m_context.getRenderContext().getType()))
5070*35238bceSAndroid Build Coastguard Worker                                   << glu::GeometrySource(
5071*35238bceSAndroid Build Coastguard Worker                                          specializeShader(geometrySource, m_context.getRenderContext().getType()))));
5072*35238bceSAndroid Build Coastguard Worker 
5073*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Building a test shader to verify GLSL constant " << m_glslName
5074*35238bceSAndroid Build Coastguard Worker                            << " value." << tcu::TestLog::EndMessage;
5075*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *program;
5076*35238bceSAndroid Build Coastguard Worker 
5077*35238bceSAndroid Build Coastguard Worker         if (!program->isOk())
5078*35238bceSAndroid Build Coastguard Worker         {
5079*35238bceSAndroid Build Coastguard Worker             // compile failed, assume static assert failed
5080*35238bceSAndroid Build Coastguard Worker             result.fail("Shader build failed");
5081*35238bceSAndroid Build Coastguard Worker             result.setTestContextResult(m_testCtx);
5082*35238bceSAndroid Build Coastguard Worker             return STOP;
5083*35238bceSAndroid Build Coastguard Worker         }
5084*35238bceSAndroid Build Coastguard Worker 
5085*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Build ok" << tcu::TestLog::EndMessage;
5086*35238bceSAndroid Build Coastguard Worker     }
5087*35238bceSAndroid Build Coastguard Worker 
5088*35238bceSAndroid Build Coastguard Worker     result.setTestContextResult(m_testCtx);
5089*35238bceSAndroid Build Coastguard Worker     return STOP;
5090*35238bceSAndroid Build Coastguard Worker }
5091*35238bceSAndroid Build Coastguard Worker 
5092*35238bceSAndroid Build Coastguard Worker class PrimitivesGeneratedQueryCase : public TestCase
5093*35238bceSAndroid Build Coastguard Worker {
5094*35238bceSAndroid Build Coastguard Worker public:
5095*35238bceSAndroid Build Coastguard Worker     enum QueryTest
5096*35238bceSAndroid Build Coastguard Worker     {
5097*35238bceSAndroid Build Coastguard Worker         TEST_NO_GEOMETRY = 0,
5098*35238bceSAndroid Build Coastguard Worker         TEST_NO_AMPLIFICATION,
5099*35238bceSAndroid Build Coastguard Worker         TEST_AMPLIFICATION,
5100*35238bceSAndroid Build Coastguard Worker         TEST_PARTIAL_PRIMITIVES,
5101*35238bceSAndroid Build Coastguard Worker         TEST_INSTANCED,
5102*35238bceSAndroid Build Coastguard Worker 
5103*35238bceSAndroid Build Coastguard Worker         TEST_LAST
5104*35238bceSAndroid Build Coastguard Worker     };
5105*35238bceSAndroid Build Coastguard Worker 
5106*35238bceSAndroid Build Coastguard Worker     PrimitivesGeneratedQueryCase(Context &context, const char *name, const char *description, QueryTest test);
5107*35238bceSAndroid Build Coastguard Worker     ~PrimitivesGeneratedQueryCase(void);
5108*35238bceSAndroid Build Coastguard Worker 
5109*35238bceSAndroid Build Coastguard Worker private:
5110*35238bceSAndroid Build Coastguard Worker     void init(void);
5111*35238bceSAndroid Build Coastguard Worker     void deinit(void);
5112*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5113*35238bceSAndroid Build Coastguard Worker 
5114*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *genProgram(void);
5115*35238bceSAndroid Build Coastguard Worker 
5116*35238bceSAndroid Build Coastguard Worker     const QueryTest m_test;
5117*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_program;
5118*35238bceSAndroid Build Coastguard Worker };
5119*35238bceSAndroid Build Coastguard Worker 
PrimitivesGeneratedQueryCase(Context & context,const char * name,const char * description,QueryTest test)5120*35238bceSAndroid Build Coastguard Worker PrimitivesGeneratedQueryCase::PrimitivesGeneratedQueryCase(Context &context, const char *name, const char *description,
5121*35238bceSAndroid Build Coastguard Worker                                                            QueryTest test)
5122*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
5123*35238bceSAndroid Build Coastguard Worker     , m_test(test)
5124*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
5125*35238bceSAndroid Build Coastguard Worker {
5126*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_test < TEST_LAST);
5127*35238bceSAndroid Build Coastguard Worker }
5128*35238bceSAndroid Build Coastguard Worker 
~PrimitivesGeneratedQueryCase(void)5129*35238bceSAndroid Build Coastguard Worker PrimitivesGeneratedQueryCase::~PrimitivesGeneratedQueryCase(void)
5130*35238bceSAndroid Build Coastguard Worker {
5131*35238bceSAndroid Build Coastguard Worker     deinit();
5132*35238bceSAndroid Build Coastguard Worker }
5133*35238bceSAndroid Build Coastguard Worker 
init(void)5134*35238bceSAndroid Build Coastguard Worker void PrimitivesGeneratedQueryCase::init(void)
5135*35238bceSAndroid Build Coastguard Worker {
5136*35238bceSAndroid Build Coastguard Worker     // requirements
5137*35238bceSAndroid Build Coastguard Worker 
5138*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
5139*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
5140*35238bceSAndroid Build Coastguard Worker 
5141*35238bceSAndroid Build Coastguard Worker     // log what test tries to do
5142*35238bceSAndroid Build Coastguard Worker 
5143*35238bceSAndroid Build Coastguard Worker     if (m_test == TEST_NO_GEOMETRY)
5144*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5145*35238bceSAndroid Build Coastguard Worker                            << "Querying PRIMITIVES_GENERATED while rendering without a geometry shader."
5146*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5147*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_NO_AMPLIFICATION)
5148*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5149*35238bceSAndroid Build Coastguard Worker                            << "Querying PRIMITIVES_GENERATED while rendering with a non-amplifying geometry shader."
5150*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5151*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_AMPLIFICATION)
5152*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5153*35238bceSAndroid Build Coastguard Worker                            << "Querying PRIMITIVES_GENERATED while rendering with a (3x) amplifying geometry shader."
5154*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5155*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_PARTIAL_PRIMITIVES)
5156*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5157*35238bceSAndroid Build Coastguard Worker                            << "Querying PRIMITIVES_GENERATED while rendering with a geometry shader that emits also "
5158*35238bceSAndroid Build Coastguard Worker                               "partial primitives."
5159*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5160*35238bceSAndroid Build Coastguard Worker     else if (m_test == TEST_INSTANCED)
5161*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5162*35238bceSAndroid Build Coastguard Worker                            << "Querying PRIMITIVES_GENERATED while rendering with a instanced geometry shader."
5163*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5164*35238bceSAndroid Build Coastguard Worker     else
5165*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
5166*35238bceSAndroid Build Coastguard Worker 
5167*35238bceSAndroid Build Coastguard Worker     // resources
5168*35238bceSAndroid Build Coastguard Worker 
5169*35238bceSAndroid Build Coastguard Worker     m_program = genProgram();
5170*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_program;
5171*35238bceSAndroid Build Coastguard Worker 
5172*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
5173*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("could not build program");
5174*35238bceSAndroid Build Coastguard Worker }
5175*35238bceSAndroid Build Coastguard Worker 
deinit(void)5176*35238bceSAndroid Build Coastguard Worker void PrimitivesGeneratedQueryCase::deinit(void)
5177*35238bceSAndroid Build Coastguard Worker {
5178*35238bceSAndroid Build Coastguard Worker     delete m_program;
5179*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
5180*35238bceSAndroid Build Coastguard Worker }
5181*35238bceSAndroid Build Coastguard Worker 
iterate(void)5182*35238bceSAndroid Build Coastguard Worker PrimitivesGeneratedQueryCase::IterateResult PrimitivesGeneratedQueryCase::iterate(void)
5183*35238bceSAndroid Build Coastguard Worker {
5184*35238bceSAndroid Build Coastguard Worker     glw::GLuint primitivesGenerated = 0xDEBADBAD;
5185*35238bceSAndroid Build Coastguard Worker 
5186*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
5187*35238bceSAndroid Build Coastguard Worker                        << "Drawing 8 points, setting a_one for each to value (1.0, 1.0, 1.0, 1.0)"
5188*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
5189*35238bceSAndroid Build Coastguard Worker 
5190*35238bceSAndroid Build Coastguard Worker     {
5191*35238bceSAndroid Build Coastguard Worker         static const tcu::Vec4 vertexData[8 * 2] = {
5192*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f),
5193*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
5194*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.3f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f),
5195*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
5196*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.6f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.7f, 0.0f, 0.0f, 1.0f),
5197*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
5198*35238bceSAndroid Build Coastguard Worker         };
5199*35238bceSAndroid Build Coastguard Worker 
5200*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5201*35238bceSAndroid Build Coastguard Worker         const glu::VertexArray vao(m_context.getRenderContext());
5202*35238bceSAndroid Build Coastguard Worker         const glu::Buffer buffer(m_context.getRenderContext());
5203*35238bceSAndroid Build Coastguard Worker         const glu::Query query(m_context.getRenderContext());
5204*35238bceSAndroid Build Coastguard Worker         const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position");
5205*35238bceSAndroid Build Coastguard Worker         const int oneLocation      = gl.getAttribLocation(m_program->getProgram(), "a_one");
5206*35238bceSAndroid Build Coastguard Worker 
5207*35238bceSAndroid Build Coastguard Worker         gl.bindVertexArray(*vao);
5208*35238bceSAndroid Build Coastguard Worker 
5209*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, *buffer);
5210*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, (int)sizeof(vertexData), vertexData, GL_STATIC_DRAW);
5211*35238bceSAndroid Build Coastguard Worker 
5212*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 2 * (int)sizeof(tcu::Vec4), DE_NULL);
5213*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLocation);
5214*35238bceSAndroid Build Coastguard Worker 
5215*35238bceSAndroid Build Coastguard Worker         if (oneLocation != -1)
5216*35238bceSAndroid Build Coastguard Worker         {
5217*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(oneLocation, 4, GL_FLOAT, GL_FALSE, 2 * (int)sizeof(tcu::Vec4),
5218*35238bceSAndroid Build Coastguard Worker                                    glu::BufferOffsetAsPointer(1 * sizeof(tcu::Vec4)));
5219*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(oneLocation);
5220*35238bceSAndroid Build Coastguard Worker         }
5221*35238bceSAndroid Build Coastguard Worker 
5222*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
5223*35238bceSAndroid Build Coastguard Worker 
5224*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "setup render");
5225*35238bceSAndroid Build Coastguard Worker 
5226*35238bceSAndroid Build Coastguard Worker         gl.beginQuery(GL_PRIMITIVES_GENERATED, *query);
5227*35238bceSAndroid Build Coastguard Worker         gl.drawArrays(GL_POINTS, 0, 8);
5228*35238bceSAndroid Build Coastguard Worker         gl.endQuery(GL_PRIMITIVES_GENERATED);
5229*35238bceSAndroid Build Coastguard Worker 
5230*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "render and query");
5231*35238bceSAndroid Build Coastguard Worker 
5232*35238bceSAndroid Build Coastguard Worker         gl.getQueryObjectuiv(*query, GL_QUERY_RESULT, &primitivesGenerated);
5233*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "get query result");
5234*35238bceSAndroid Build Coastguard Worker     }
5235*35238bceSAndroid Build Coastguard Worker 
5236*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "GL_PRIMITIVES_GENERATED = " << primitivesGenerated
5237*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
5238*35238bceSAndroid Build Coastguard Worker 
5239*35238bceSAndroid Build Coastguard Worker     {
5240*35238bceSAndroid Build Coastguard Worker         const uint32_t expectedGenerated = (m_test == TEST_AMPLIFICATION) ? (3 * 8) :
5241*35238bceSAndroid Build Coastguard Worker                                            (m_test == TEST_INSTANCED)     ? (8 * (3 + 1)) :
5242*35238bceSAndroid Build Coastguard Worker                                                                             (8);
5243*35238bceSAndroid Build Coastguard Worker 
5244*35238bceSAndroid Build Coastguard Worker         if (expectedGenerated == primitivesGenerated)
5245*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5246*35238bceSAndroid Build Coastguard Worker         else
5247*35238bceSAndroid Build Coastguard Worker         {
5248*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong result for GL_PRIMITIVES_GENERATED");
5249*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
5250*35238bceSAndroid Build Coastguard Worker                                << "Got unexpected result for GL_PRIMITIVES_GENERATED. Expected " << expectedGenerated
5251*35238bceSAndroid Build Coastguard Worker                                << ", got " << primitivesGenerated << tcu::TestLog::EndMessage;
5252*35238bceSAndroid Build Coastguard Worker         }
5253*35238bceSAndroid Build Coastguard Worker     }
5254*35238bceSAndroid Build Coastguard Worker 
5255*35238bceSAndroid Build Coastguard Worker     return STOP;
5256*35238bceSAndroid Build Coastguard Worker }
5257*35238bceSAndroid Build Coastguard Worker 
genProgram(void)5258*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *PrimitivesGeneratedQueryCase::genProgram(void)
5259*35238bceSAndroid Build Coastguard Worker {
5260*35238bceSAndroid Build Coastguard Worker     static const char *const vertexSource   = "${GLSL_VERSION_DECL}\n"
5261*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_position;\n"
5262*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_one;\n"
5263*35238bceSAndroid Build Coastguard Worker                                               "out highp vec4 v_one;\n"
5264*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
5265*35238bceSAndroid Build Coastguard Worker                                               "{\n"
5266*35238bceSAndroid Build Coastguard Worker                                               "    gl_Position = a_position;\n"
5267*35238bceSAndroid Build Coastguard Worker                                               "    v_one = a_one;\n"
5268*35238bceSAndroid Build Coastguard Worker                                               "}\n";
5269*35238bceSAndroid Build Coastguard Worker     static const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
5270*35238bceSAndroid Build Coastguard Worker                                               "layout(location = 0) out mediump vec4 fragColor;\n"
5271*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
5272*35238bceSAndroid Build Coastguard Worker                                               "{\n"
5273*35238bceSAndroid Build Coastguard Worker                                               "    fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
5274*35238bceSAndroid Build Coastguard Worker                                               "}\n";
5275*35238bceSAndroid Build Coastguard Worker     std::ostringstream geometrySource;
5276*35238bceSAndroid Build Coastguard Worker     glu::ProgramSources sources;
5277*35238bceSAndroid Build Coastguard Worker 
5278*35238bceSAndroid Build Coastguard Worker     if (m_test != TEST_NO_GEOMETRY)
5279*35238bceSAndroid Build Coastguard Worker     {
5280*35238bceSAndroid Build Coastguard Worker         geometrySource << "${GLSL_VERSION_DECL}\n"
5281*35238bceSAndroid Build Coastguard Worker                           "${GLSL_EXT_GEOMETRY_SHADER}"
5282*35238bceSAndroid Build Coastguard Worker                           "layout(points"
5283*35238bceSAndroid Build Coastguard Worker                        << ((m_test == TEST_INSTANCED) ? (", invocations = 3") : (""))
5284*35238bceSAndroid Build Coastguard Worker                        << ") in;\n"
5285*35238bceSAndroid Build Coastguard Worker                           "layout(triangle_strip, max_vertices = 7) out;\n"
5286*35238bceSAndroid Build Coastguard Worker                           "in highp vec4 v_one[];\n"
5287*35238bceSAndroid Build Coastguard Worker                           "void main (void)\n"
5288*35238bceSAndroid Build Coastguard Worker                           "{\n"
5289*35238bceSAndroid Build Coastguard Worker                           "    // always taken\n"
5290*35238bceSAndroid Build Coastguard Worker                           "    if (v_one[0].x != 0.0)\n"
5291*35238bceSAndroid Build Coastguard Worker                           "    {\n"
5292*35238bceSAndroid Build Coastguard Worker                           "        gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0);\n"
5293*35238bceSAndroid Build Coastguard Worker                           "        EmitVertex();\n"
5294*35238bceSAndroid Build Coastguard Worker                           "        gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);\n"
5295*35238bceSAndroid Build Coastguard Worker                           "        EmitVertex();\n"
5296*35238bceSAndroid Build Coastguard Worker                           "        gl_Position = gl_in[0].gl_Position - vec4(0.1, 0.0, 0.0, 0.0);\n"
5297*35238bceSAndroid Build Coastguard Worker                           "        EmitVertex();\n"
5298*35238bceSAndroid Build Coastguard Worker                           "        EndPrimitive();\n"
5299*35238bceSAndroid Build Coastguard Worker                           "    }\n";
5300*35238bceSAndroid Build Coastguard Worker 
5301*35238bceSAndroid Build Coastguard Worker         if (m_test == TEST_AMPLIFICATION)
5302*35238bceSAndroid Build Coastguard Worker         {
5303*35238bceSAndroid Build Coastguard Worker             geometrySource << "\n"
5304*35238bceSAndroid Build Coastguard Worker                               "    // always taken\n"
5305*35238bceSAndroid Build Coastguard Worker                               "    if (v_one[0].y != 0.0)\n"
5306*35238bceSAndroid Build Coastguard Worker                               "    {\n"
5307*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0);\n"
5308*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5309*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);\n"
5310*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5311*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position - vec4(0.0, 0.1, 0.0, 0.0);\n"
5312*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5313*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position - vec4(0.1, 0.0, 0.0, 0.0);\n"
5314*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5315*35238bceSAndroid Build Coastguard Worker                               "    }\n";
5316*35238bceSAndroid Build Coastguard Worker         }
5317*35238bceSAndroid Build Coastguard Worker         else if (m_test == TEST_PARTIAL_PRIMITIVES)
5318*35238bceSAndroid Build Coastguard Worker         {
5319*35238bceSAndroid Build Coastguard Worker             geometrySource << "\n"
5320*35238bceSAndroid Build Coastguard Worker                               "    // always taken\n"
5321*35238bceSAndroid Build Coastguard Worker                               "    if (v_one[0].y != 0.0)\n"
5322*35238bceSAndroid Build Coastguard Worker                               "    {\n"
5323*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0);\n"
5324*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5325*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);\n"
5326*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5327*35238bceSAndroid Build Coastguard Worker                               "\n"
5328*35238bceSAndroid Build Coastguard Worker                               "        // never taken\n"
5329*35238bceSAndroid Build Coastguard Worker                               "        if (v_one[0].z < 0.0)\n"
5330*35238bceSAndroid Build Coastguard Worker                               "        {\n"
5331*35238bceSAndroid Build Coastguard Worker                               "            gl_Position = gl_in[0].gl_Position - vec4(0.1, 0.0, 0.0, 0.0);\n"
5332*35238bceSAndroid Build Coastguard Worker                               "            EmitVertex();\n"
5333*35238bceSAndroid Build Coastguard Worker                               "        }\n"
5334*35238bceSAndroid Build Coastguard Worker                               "    }\n";
5335*35238bceSAndroid Build Coastguard Worker         }
5336*35238bceSAndroid Build Coastguard Worker         else if (m_test == TEST_INSTANCED)
5337*35238bceSAndroid Build Coastguard Worker         {
5338*35238bceSAndroid Build Coastguard Worker             geometrySource << "\n"
5339*35238bceSAndroid Build Coastguard Worker                               "    // taken once\n"
5340*35238bceSAndroid Build Coastguard Worker                               "    if (v_one[0].y > float(gl_InvocationID) + 0.5)\n"
5341*35238bceSAndroid Build Coastguard Worker                               "    {\n"
5342*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0);\n"
5343*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5344*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);\n"
5345*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5346*35238bceSAndroid Build Coastguard Worker                               "        gl_Position = gl_in[0].gl_Position - vec4(0.1, 0.0, 0.0, 0.0);\n"
5347*35238bceSAndroid Build Coastguard Worker                               "        EmitVertex();\n"
5348*35238bceSAndroid Build Coastguard Worker                               "    }\n";
5349*35238bceSAndroid Build Coastguard Worker         }
5350*35238bceSAndroid Build Coastguard Worker 
5351*35238bceSAndroid Build Coastguard Worker         geometrySource << "}\n";
5352*35238bceSAndroid Build Coastguard Worker     }
5353*35238bceSAndroid Build Coastguard Worker 
5354*35238bceSAndroid Build Coastguard Worker     sources << glu::VertexSource(specializeShader(vertexSource, m_context.getRenderContext().getType()));
5355*35238bceSAndroid Build Coastguard Worker     sources << glu::FragmentSource(specializeShader(fragmentSource, m_context.getRenderContext().getType()));
5356*35238bceSAndroid Build Coastguard Worker 
5357*35238bceSAndroid Build Coastguard Worker     if (!geometrySource.str().empty())
5358*35238bceSAndroid Build Coastguard Worker         sources << glu::GeometrySource(specializeShader(geometrySource.str(), m_context.getRenderContext().getType()));
5359*35238bceSAndroid Build Coastguard Worker 
5360*35238bceSAndroid Build Coastguard Worker     return new glu::ShaderProgram(m_context.getRenderContext(), sources);
5361*35238bceSAndroid Build Coastguard Worker }
5362*35238bceSAndroid Build Coastguard Worker 
5363*35238bceSAndroid Build Coastguard Worker class PrimitivesGeneratedQueryObjectQueryCase : public TestCase
5364*35238bceSAndroid Build Coastguard Worker {
5365*35238bceSAndroid Build Coastguard Worker public:
5366*35238bceSAndroid Build Coastguard Worker     PrimitivesGeneratedQueryObjectQueryCase(Context &context, const char *name, const char *description);
5367*35238bceSAndroid Build Coastguard Worker 
5368*35238bceSAndroid Build Coastguard Worker     void init(void);
5369*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5370*35238bceSAndroid Build Coastguard Worker };
5371*35238bceSAndroid Build Coastguard Worker 
PrimitivesGeneratedQueryObjectQueryCase(Context & context,const char * name,const char * description)5372*35238bceSAndroid Build Coastguard Worker PrimitivesGeneratedQueryObjectQueryCase::PrimitivesGeneratedQueryObjectQueryCase(Context &context, const char *name,
5373*35238bceSAndroid Build Coastguard Worker                                                                                  const char *description)
5374*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
5375*35238bceSAndroid Build Coastguard Worker {
5376*35238bceSAndroid Build Coastguard Worker }
5377*35238bceSAndroid Build Coastguard Worker 
init(void)5378*35238bceSAndroid Build Coastguard Worker void PrimitivesGeneratedQueryObjectQueryCase::init(void)
5379*35238bceSAndroid Build Coastguard Worker {
5380*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
5381*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
5382*35238bceSAndroid Build Coastguard Worker }
5383*35238bceSAndroid Build Coastguard Worker 
iterate(void)5384*35238bceSAndroid Build Coastguard Worker PrimitivesGeneratedQueryObjectQueryCase::IterateResult PrimitivesGeneratedQueryObjectQueryCase::iterate(void)
5385*35238bceSAndroid Build Coastguard Worker {
5386*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5387*35238bceSAndroid Build Coastguard Worker     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
5388*35238bceSAndroid Build Coastguard Worker 
5389*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
5390*35238bceSAndroid Build Coastguard Worker 
5391*35238bceSAndroid Build Coastguard Worker     {
5392*35238bceSAndroid Build Coastguard Worker         glw::GLuint query = 0;
5393*35238bceSAndroid Build Coastguard Worker 
5394*35238bceSAndroid Build Coastguard Worker         verifyStateQueryInteger(result, gl, GL_PRIMITIVES_GENERATED, GL_CURRENT_QUERY, 0, QUERY_QUERY);
5395*35238bceSAndroid Build Coastguard Worker 
5396*35238bceSAndroid Build Coastguard Worker         gl.glGenQueries(1, &query);
5397*35238bceSAndroid Build Coastguard Worker         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGenQueries");
5398*35238bceSAndroid Build Coastguard Worker 
5399*35238bceSAndroid Build Coastguard Worker         gl.glBeginQuery(GL_PRIMITIVES_GENERATED, query);
5400*35238bceSAndroid Build Coastguard Worker         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "beginQuery");
5401*35238bceSAndroid Build Coastguard Worker 
5402*35238bceSAndroid Build Coastguard Worker         verifyStateQueryInteger(result, gl, GL_PRIMITIVES_GENERATED, GL_CURRENT_QUERY, (int)query, QUERY_QUERY);
5403*35238bceSAndroid Build Coastguard Worker 
5404*35238bceSAndroid Build Coastguard Worker         gl.glEndQuery(GL_PRIMITIVES_GENERATED);
5405*35238bceSAndroid Build Coastguard Worker         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "endQuery");
5406*35238bceSAndroid Build Coastguard Worker     }
5407*35238bceSAndroid Build Coastguard Worker 
5408*35238bceSAndroid Build Coastguard Worker     result.setTestContextResult(m_testCtx);
5409*35238bceSAndroid Build Coastguard Worker     return STOP;
5410*35238bceSAndroid Build Coastguard Worker }
5411*35238bceSAndroid Build Coastguard Worker 
5412*35238bceSAndroid Build Coastguard Worker class GeometryShaderFeartureTestCase : public TestCase
5413*35238bceSAndroid Build Coastguard Worker {
5414*35238bceSAndroid Build Coastguard Worker public:
5415*35238bceSAndroid Build Coastguard Worker     GeometryShaderFeartureTestCase(Context &context, const char *name, const char *description);
5416*35238bceSAndroid Build Coastguard Worker 
5417*35238bceSAndroid Build Coastguard Worker     void init(void);
5418*35238bceSAndroid Build Coastguard Worker };
5419*35238bceSAndroid Build Coastguard Worker 
GeometryShaderFeartureTestCase(Context & context,const char * name,const char * description)5420*35238bceSAndroid Build Coastguard Worker GeometryShaderFeartureTestCase::GeometryShaderFeartureTestCase(Context &context, const char *name,
5421*35238bceSAndroid Build Coastguard Worker                                                                const char *description)
5422*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
5423*35238bceSAndroid Build Coastguard Worker {
5424*35238bceSAndroid Build Coastguard Worker }
5425*35238bceSAndroid Build Coastguard Worker 
init(void)5426*35238bceSAndroid Build Coastguard Worker void GeometryShaderFeartureTestCase::init(void)
5427*35238bceSAndroid Build Coastguard Worker {
5428*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
5429*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
5430*35238bceSAndroid Build Coastguard Worker }
5431*35238bceSAndroid Build Coastguard Worker 
5432*35238bceSAndroid Build Coastguard Worker class FramebufferDefaultLayersCase : public GeometryShaderFeartureTestCase
5433*35238bceSAndroid Build Coastguard Worker {
5434*35238bceSAndroid Build Coastguard Worker public:
5435*35238bceSAndroid Build Coastguard Worker     FramebufferDefaultLayersCase(Context &context, const char *name, const char *description);
5436*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5437*35238bceSAndroid Build Coastguard Worker };
5438*35238bceSAndroid Build Coastguard Worker 
FramebufferDefaultLayersCase(Context & context,const char * name,const char * description)5439*35238bceSAndroid Build Coastguard Worker FramebufferDefaultLayersCase::FramebufferDefaultLayersCase(Context &context, const char *name, const char *description)
5440*35238bceSAndroid Build Coastguard Worker     : GeometryShaderFeartureTestCase(context, name, description)
5441*35238bceSAndroid Build Coastguard Worker {
5442*35238bceSAndroid Build Coastguard Worker }
5443*35238bceSAndroid Build Coastguard Worker 
iterate(void)5444*35238bceSAndroid Build Coastguard Worker FramebufferDefaultLayersCase::IterateResult FramebufferDefaultLayersCase::iterate(void)
5445*35238bceSAndroid Build Coastguard Worker {
5446*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5447*35238bceSAndroid Build Coastguard Worker 
5448*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
5449*35238bceSAndroid Build Coastguard Worker 
5450*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5451*35238bceSAndroid Build Coastguard Worker 
5452*35238bceSAndroid Build Coastguard Worker     {
5453*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Default", "Default value");
5454*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(m_context.getRenderContext());
5455*35238bceSAndroid Build Coastguard Worker         glw::GLint defaultLayers = -1;
5456*35238bceSAndroid Build Coastguard Worker 
5457*35238bceSAndroid Build Coastguard Worker         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *fbo);
5458*35238bceSAndroid Build Coastguard Worker         gl.glGetFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, &defaultLayers);
5459*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "getFramebufferParameteriv");
5460*35238bceSAndroid Build Coastguard Worker 
5461*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_FRAMEBUFFER_DEFAULT_LAYERS = " << defaultLayers
5462*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5463*35238bceSAndroid Build Coastguard Worker 
5464*35238bceSAndroid Build Coastguard Worker         if (defaultLayers != 0)
5465*35238bceSAndroid Build Coastguard Worker         {
5466*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected 0, got " << defaultLayers
5467*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
5468*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid layer count");
5469*35238bceSAndroid Build Coastguard Worker         }
5470*35238bceSAndroid Build Coastguard Worker     }
5471*35238bceSAndroid Build Coastguard Worker 
5472*35238bceSAndroid Build Coastguard Worker     {
5473*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "SetTo12", "Set default layers to 12");
5474*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(m_context.getRenderContext());
5475*35238bceSAndroid Build Coastguard Worker         glw::GLint defaultLayers = -1;
5476*35238bceSAndroid Build Coastguard Worker 
5477*35238bceSAndroid Build Coastguard Worker         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *fbo);
5478*35238bceSAndroid Build Coastguard Worker         gl.glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, 12);
5479*35238bceSAndroid Build Coastguard Worker         gl.glGetFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, &defaultLayers);
5480*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "getFramebufferParameteriv");
5481*35238bceSAndroid Build Coastguard Worker 
5482*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_FRAMEBUFFER_DEFAULT_LAYERS = " << defaultLayers
5483*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5484*35238bceSAndroid Build Coastguard Worker 
5485*35238bceSAndroid Build Coastguard Worker         if (defaultLayers != 12)
5486*35238bceSAndroid Build Coastguard Worker         {
5487*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected 12, got " << defaultLayers
5488*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
5489*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid layer count");
5490*35238bceSAndroid Build Coastguard Worker         }
5491*35238bceSAndroid Build Coastguard Worker     }
5492*35238bceSAndroid Build Coastguard Worker 
5493*35238bceSAndroid Build Coastguard Worker     return STOP;
5494*35238bceSAndroid Build Coastguard Worker }
5495*35238bceSAndroid Build Coastguard Worker 
5496*35238bceSAndroid Build Coastguard Worker class FramebufferAttachmentLayeredCase : public GeometryShaderFeartureTestCase
5497*35238bceSAndroid Build Coastguard Worker {
5498*35238bceSAndroid Build Coastguard Worker public:
5499*35238bceSAndroid Build Coastguard Worker     FramebufferAttachmentLayeredCase(Context &context, const char *name, const char *description);
5500*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5501*35238bceSAndroid Build Coastguard Worker };
5502*35238bceSAndroid Build Coastguard Worker 
FramebufferAttachmentLayeredCase(Context & context,const char * name,const char * description)5503*35238bceSAndroid Build Coastguard Worker FramebufferAttachmentLayeredCase::FramebufferAttachmentLayeredCase(Context &context, const char *name,
5504*35238bceSAndroid Build Coastguard Worker                                                                    const char *description)
5505*35238bceSAndroid Build Coastguard Worker     : GeometryShaderFeartureTestCase(context, name, description)
5506*35238bceSAndroid Build Coastguard Worker {
5507*35238bceSAndroid Build Coastguard Worker }
5508*35238bceSAndroid Build Coastguard Worker 
iterate(void)5509*35238bceSAndroid Build Coastguard Worker FramebufferAttachmentLayeredCase::IterateResult FramebufferAttachmentLayeredCase::iterate(void)
5510*35238bceSAndroid Build Coastguard Worker {
5511*35238bceSAndroid Build Coastguard Worker     enum CaseType
5512*35238bceSAndroid Build Coastguard Worker     {
5513*35238bceSAndroid Build Coastguard Worker         TEXTURE_3D,
5514*35238bceSAndroid Build Coastguard Worker         TEXTURE_2D_ARRAY,
5515*35238bceSAndroid Build Coastguard Worker         TEXTURE_CUBE,
5516*35238bceSAndroid Build Coastguard Worker         TEXTURE_2D_MS_ARRAY,
5517*35238bceSAndroid Build Coastguard Worker         TEXTURE_3D_LAYER,
5518*35238bceSAndroid Build Coastguard Worker         TEXTURE_2D_ARRAY_LAYER,
5519*35238bceSAndroid Build Coastguard Worker     };
5520*35238bceSAndroid Build Coastguard Worker 
5521*35238bceSAndroid Build Coastguard Worker     static const struct TextureType
5522*35238bceSAndroid Build Coastguard Worker     {
5523*35238bceSAndroid Build Coastguard Worker         const char *name;
5524*35238bceSAndroid Build Coastguard Worker         const char *description;
5525*35238bceSAndroid Build Coastguard Worker         bool layered;
5526*35238bceSAndroid Build Coastguard Worker         CaseType type;
5527*35238bceSAndroid Build Coastguard Worker     } textureTypes[] = {
5528*35238bceSAndroid Build Coastguard Worker         {"3D", "3D texture", true, TEXTURE_3D},
5529*35238bceSAndroid Build Coastguard Worker         {"2DArray", "2D array", true, TEXTURE_2D_ARRAY},
5530*35238bceSAndroid Build Coastguard Worker         {"Cube", "Cube map", true, TEXTURE_CUBE},
5531*35238bceSAndroid Build Coastguard Worker         {"2DMSArray", "2D multisample array", true, TEXTURE_2D_MS_ARRAY},
5532*35238bceSAndroid Build Coastguard Worker         {"3DLayer", "3D texture layer ", false, TEXTURE_3D_LAYER},
5533*35238bceSAndroid Build Coastguard Worker         {"2DArrayLayer", "2D array layer ", false, TEXTURE_2D_ARRAY_LAYER},
5534*35238bceSAndroid Build Coastguard Worker     };
5535*35238bceSAndroid Build Coastguard Worker 
5536*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5537*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
5538*35238bceSAndroid Build Coastguard Worker 
5539*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5540*35238bceSAndroid Build Coastguard Worker 
5541*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureTypes); ++ndx)
5542*35238bceSAndroid Build Coastguard Worker     {
5543*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), textureTypes[ndx].name, textureTypes[ndx].description);
5544*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(m_context.getRenderContext());
5545*35238bceSAndroid Build Coastguard Worker         const glu::Texture texture(m_context.getRenderContext());
5546*35238bceSAndroid Build Coastguard Worker         glw::GLint layered = -1;
5547*35238bceSAndroid Build Coastguard Worker 
5548*35238bceSAndroid Build Coastguard Worker         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *fbo);
5549*35238bceSAndroid Build Coastguard Worker 
5550*35238bceSAndroid Build Coastguard Worker         if (textureTypes[ndx].type == TEXTURE_3D || textureTypes[ndx].type == TEXTURE_3D_LAYER)
5551*35238bceSAndroid Build Coastguard Worker         {
5552*35238bceSAndroid Build Coastguard Worker             gl.glBindTexture(GL_TEXTURE_3D, *texture);
5553*35238bceSAndroid Build Coastguard Worker             gl.glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5554*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5555*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5556*35238bceSAndroid Build Coastguard Worker 
5557*35238bceSAndroid Build Coastguard Worker             if (textureTypes[ndx].type == TEXTURE_3D)
5558*35238bceSAndroid Build Coastguard Worker                 gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0);
5559*35238bceSAndroid Build Coastguard Worker             else
5560*35238bceSAndroid Build Coastguard Worker                 gl.glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0, 2);
5561*35238bceSAndroid Build Coastguard Worker         }
5562*35238bceSAndroid Build Coastguard Worker         else if (textureTypes[ndx].type == TEXTURE_2D_ARRAY || textureTypes[ndx].type == TEXTURE_2D_ARRAY_LAYER)
5563*35238bceSAndroid Build Coastguard Worker         {
5564*35238bceSAndroid Build Coastguard Worker             gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *texture);
5565*35238bceSAndroid Build Coastguard Worker             gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5566*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5567*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5568*35238bceSAndroid Build Coastguard Worker 
5569*35238bceSAndroid Build Coastguard Worker             if (textureTypes[ndx].type == TEXTURE_2D_ARRAY)
5570*35238bceSAndroid Build Coastguard Worker                 gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0);
5571*35238bceSAndroid Build Coastguard Worker             else
5572*35238bceSAndroid Build Coastguard Worker                 gl.glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0, 3);
5573*35238bceSAndroid Build Coastguard Worker         }
5574*35238bceSAndroid Build Coastguard Worker         else if (textureTypes[ndx].type == TEXTURE_CUBE)
5575*35238bceSAndroid Build Coastguard Worker         {
5576*35238bceSAndroid Build Coastguard Worker             gl.glBindTexture(GL_TEXTURE_CUBE_MAP, *texture);
5577*35238bceSAndroid Build Coastguard Worker             for (int face = 0; face < 6; ++face)
5578*35238bceSAndroid Build Coastguard Worker                 gl.glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA8, 32, 32, 0, GL_RGBA,
5579*35238bceSAndroid Build Coastguard Worker                                 GL_UNSIGNED_BYTE, DE_NULL);
5580*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5581*35238bceSAndroid Build Coastguard Worker             gl.glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5582*35238bceSAndroid Build Coastguard Worker             gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0);
5583*35238bceSAndroid Build Coastguard Worker         }
5584*35238bceSAndroid Build Coastguard Worker         else if (textureTypes[ndx].type == TEXTURE_2D_MS_ARRAY)
5585*35238bceSAndroid Build Coastguard Worker         {
5586*35238bceSAndroid Build Coastguard Worker             const bool supportES32 =
5587*35238bceSAndroid Build Coastguard Worker                 glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
5588*35238bceSAndroid Build Coastguard Worker             const bool supportGL45 =
5589*35238bceSAndroid Build Coastguard Worker                 glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
5590*35238bceSAndroid Build Coastguard Worker 
5591*35238bceSAndroid Build Coastguard Worker             // check extension
5592*35238bceSAndroid Build Coastguard Worker             if (!(supportGL45 || (supportES32 && m_context.getContextInfo().isExtensionSupported(
5593*35238bceSAndroid Build Coastguard Worker                                                      "GL_OES_texture_storage_multisample_2d_array"))))
5594*35238bceSAndroid Build Coastguard Worker             {
5595*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
5596*35238bceSAndroid Build Coastguard Worker                                    << "Context is not equal or greather than 3.2 and "
5597*35238bceSAndroid Build Coastguard Worker                                       "GL_OES_texture_storage_multisample_2d_array not supported, skipping."
5598*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
5599*35238bceSAndroid Build Coastguard Worker                 continue;
5600*35238bceSAndroid Build Coastguard Worker             }
5601*35238bceSAndroid Build Coastguard Worker 
5602*35238bceSAndroid Build Coastguard Worker             gl.glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, *texture);
5603*35238bceSAndroid Build Coastguard Worker             gl.glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 32, 32, 32, GL_FALSE);
5604*35238bceSAndroid Build Coastguard Worker             gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture, 0);
5605*35238bceSAndroid Build Coastguard Worker         }
5606*35238bceSAndroid Build Coastguard Worker 
5607*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup attachment");
5608*35238bceSAndroid Build Coastguard Worker 
5609*35238bceSAndroid Build Coastguard Worker         gl.glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5610*35238bceSAndroid Build Coastguard Worker                                                  GL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered);
5611*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "getFramebufferParameteriv");
5612*35238bceSAndroid Build Coastguard Worker 
5613*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
5614*35238bceSAndroid Build Coastguard Worker                            << "GL_FRAMEBUFFER_ATTACHMENT_LAYERED = " << glu::getBooleanStr(layered)
5615*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5616*35238bceSAndroid Build Coastguard Worker 
5617*35238bceSAndroid Build Coastguard Worker         if (layered != GL_TRUE && layered != GL_FALSE)
5618*35238bceSAndroid Build Coastguard Worker         {
5619*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected boolean, got " << layered
5620*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
5621*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid boolean");
5622*35238bceSAndroid Build Coastguard Worker         }
5623*35238bceSAndroid Build Coastguard Worker         else if ((layered == GL_TRUE) != textureTypes[ndx].layered)
5624*35238bceSAndroid Build Coastguard Worker         {
5625*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected "
5626*35238bceSAndroid Build Coastguard Worker                                << ((textureTypes[ndx].layered) ? ("GL_TRUE") : ("GL_FALSE")) << ", got "
5627*35238bceSAndroid Build Coastguard Worker                                << glu::getBooleanStr(layered) << tcu::TestLog::EndMessage;
5628*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid layer count");
5629*35238bceSAndroid Build Coastguard Worker         }
5630*35238bceSAndroid Build Coastguard Worker     }
5631*35238bceSAndroid Build Coastguard Worker 
5632*35238bceSAndroid Build Coastguard Worker     return STOP;
5633*35238bceSAndroid Build Coastguard Worker }
5634*35238bceSAndroid Build Coastguard Worker 
5635*35238bceSAndroid Build Coastguard Worker class FramebufferIncompleteLayereTargetsCase : public GeometryShaderFeartureTestCase
5636*35238bceSAndroid Build Coastguard Worker {
5637*35238bceSAndroid Build Coastguard Worker public:
5638*35238bceSAndroid Build Coastguard Worker     FramebufferIncompleteLayereTargetsCase(Context &context, const char *name, const char *description);
5639*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5640*35238bceSAndroid Build Coastguard Worker };
5641*35238bceSAndroid Build Coastguard Worker 
FramebufferIncompleteLayereTargetsCase(Context & context,const char * name,const char * description)5642*35238bceSAndroid Build Coastguard Worker FramebufferIncompleteLayereTargetsCase::FramebufferIncompleteLayereTargetsCase(Context &context, const char *name,
5643*35238bceSAndroid Build Coastguard Worker                                                                                const char *description)
5644*35238bceSAndroid Build Coastguard Worker     : GeometryShaderFeartureTestCase(context, name, description)
5645*35238bceSAndroid Build Coastguard Worker {
5646*35238bceSAndroid Build Coastguard Worker }
5647*35238bceSAndroid Build Coastguard Worker 
iterate(void)5648*35238bceSAndroid Build Coastguard Worker FramebufferIncompleteLayereTargetsCase::IterateResult FramebufferIncompleteLayereTargetsCase::iterate(void)
5649*35238bceSAndroid Build Coastguard Worker {
5650*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5651*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
5652*35238bceSAndroid Build Coastguard Worker 
5653*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5654*35238bceSAndroid Build Coastguard Worker 
5655*35238bceSAndroid Build Coastguard Worker     {
5656*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "LayerAndNonLayer", "Layered and non-layered");
5657*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(m_context.getRenderContext());
5658*35238bceSAndroid Build Coastguard Worker         const glu::Texture texture0(m_context.getRenderContext());
5659*35238bceSAndroid Build Coastguard Worker         const glu::Texture texture1(m_context.getRenderContext());
5660*35238bceSAndroid Build Coastguard Worker 
5661*35238bceSAndroid Build Coastguard Worker         glw::GLint fboStatus;
5662*35238bceSAndroid Build Coastguard Worker 
5663*35238bceSAndroid Build Coastguard Worker         gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *texture0);
5664*35238bceSAndroid Build Coastguard Worker         gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5665*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5666*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5667*35238bceSAndroid Build Coastguard Worker 
5668*35238bceSAndroid Build Coastguard Worker         gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *texture1);
5669*35238bceSAndroid Build Coastguard Worker         gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5670*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5671*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5672*35238bceSAndroid Build Coastguard Worker 
5673*35238bceSAndroid Build Coastguard Worker         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *fbo);
5674*35238bceSAndroid Build Coastguard Worker         gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture0, 0);
5675*35238bceSAndroid Build Coastguard Worker         gl.glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, *texture1, 0, 0);
5676*35238bceSAndroid Build Coastguard Worker 
5677*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup fbo");
5678*35238bceSAndroid Build Coastguard Worker 
5679*35238bceSAndroid Build Coastguard Worker         fboStatus = gl.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
5680*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer status: " << glu::getFramebufferStatusStr(fboStatus)
5681*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5682*35238bceSAndroid Build Coastguard Worker 
5683*35238bceSAndroid Build Coastguard Worker         if (fboStatus != GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS)
5684*35238bceSAndroid Build Coastguard Worker         {
5685*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
5686*35238bceSAndroid Build Coastguard Worker                                << "Error, expected GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, got "
5687*35238bceSAndroid Build Coastguard Worker                                << glu::getFramebufferStatusStr(fboStatus) << tcu::TestLog::EndMessage;
5688*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid layer count");
5689*35238bceSAndroid Build Coastguard Worker         }
5690*35238bceSAndroid Build Coastguard Worker     }
5691*35238bceSAndroid Build Coastguard Worker 
5692*35238bceSAndroid Build Coastguard Worker     {
5693*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "DifferentTarget", "Different target");
5694*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(m_context.getRenderContext());
5695*35238bceSAndroid Build Coastguard Worker         const glu::Texture texture0(m_context.getRenderContext());
5696*35238bceSAndroid Build Coastguard Worker         const glu::Texture texture1(m_context.getRenderContext());
5697*35238bceSAndroid Build Coastguard Worker 
5698*35238bceSAndroid Build Coastguard Worker         glw::GLint fboStatus;
5699*35238bceSAndroid Build Coastguard Worker 
5700*35238bceSAndroid Build Coastguard Worker         gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *texture0);
5701*35238bceSAndroid Build Coastguard Worker         gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5702*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5703*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5704*35238bceSAndroid Build Coastguard Worker 
5705*35238bceSAndroid Build Coastguard Worker         gl.glBindTexture(GL_TEXTURE_3D, *texture1);
5706*35238bceSAndroid Build Coastguard Worker         gl.glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5707*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5708*35238bceSAndroid Build Coastguard Worker         gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5709*35238bceSAndroid Build Coastguard Worker 
5710*35238bceSAndroid Build Coastguard Worker         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *fbo);
5711*35238bceSAndroid Build Coastguard Worker         gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *texture0, 0);
5712*35238bceSAndroid Build Coastguard Worker         gl.glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, *texture1, 0);
5713*35238bceSAndroid Build Coastguard Worker 
5714*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup fbo");
5715*35238bceSAndroid Build Coastguard Worker 
5716*35238bceSAndroid Build Coastguard Worker         fboStatus = gl.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
5717*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer status: " << glu::getFramebufferStatusStr(fboStatus)
5718*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
5719*35238bceSAndroid Build Coastguard Worker 
5720*35238bceSAndroid Build Coastguard Worker         if (fboStatus != GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS)
5721*35238bceSAndroid Build Coastguard Worker         {
5722*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
5723*35238bceSAndroid Build Coastguard Worker                                << "Error, expected GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, got "
5724*35238bceSAndroid Build Coastguard Worker                                << glu::getFramebufferStatusStr(fboStatus) << tcu::TestLog::EndMessage;
5725*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid layer count");
5726*35238bceSAndroid Build Coastguard Worker         }
5727*35238bceSAndroid Build Coastguard Worker     }
5728*35238bceSAndroid Build Coastguard Worker 
5729*35238bceSAndroid Build Coastguard Worker     return STOP;
5730*35238bceSAndroid Build Coastguard Worker }
5731*35238bceSAndroid Build Coastguard Worker 
5732*35238bceSAndroid Build Coastguard Worker class ReferencedByGeometryShaderCase : public GeometryShaderFeartureTestCase
5733*35238bceSAndroid Build Coastguard Worker {
5734*35238bceSAndroid Build Coastguard Worker public:
5735*35238bceSAndroid Build Coastguard Worker     ReferencedByGeometryShaderCase(Context &context, const char *name, const char *description);
5736*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5737*35238bceSAndroid Build Coastguard Worker };
5738*35238bceSAndroid Build Coastguard Worker 
ReferencedByGeometryShaderCase(Context & context,const char * name,const char * description)5739*35238bceSAndroid Build Coastguard Worker ReferencedByGeometryShaderCase::ReferencedByGeometryShaderCase(Context &context, const char *name,
5740*35238bceSAndroid Build Coastguard Worker                                                                const char *description)
5741*35238bceSAndroid Build Coastguard Worker     : GeometryShaderFeartureTestCase(context, name, description)
5742*35238bceSAndroid Build Coastguard Worker {
5743*35238bceSAndroid Build Coastguard Worker }
5744*35238bceSAndroid Build Coastguard Worker 
iterate(void)5745*35238bceSAndroid Build Coastguard Worker ReferencedByGeometryShaderCase::IterateResult ReferencedByGeometryShaderCase::iterate(void)
5746*35238bceSAndroid Build Coastguard Worker {
5747*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5748*35238bceSAndroid Build Coastguard Worker 
5749*35238bceSAndroid Build Coastguard Worker     {
5750*35238bceSAndroid Build Coastguard Worker         static const char *const vertexSource   = "${GLSL_VERSION_DECL}\n"
5751*35238bceSAndroid Build Coastguard Worker                                                   "uniform highp vec4 u_position;\n"
5752*35238bceSAndroid Build Coastguard Worker                                                   "void main (void)\n"
5753*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
5754*35238bceSAndroid Build Coastguard Worker                                                   "    gl_Position = u_position;\n"
5755*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
5756*35238bceSAndroid Build Coastguard Worker         static const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
5757*35238bceSAndroid Build Coastguard Worker                                                   "layout(location = 0) out mediump vec4 fragColor;\n"
5758*35238bceSAndroid Build Coastguard Worker                                                   "void main (void)\n"
5759*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
5760*35238bceSAndroid Build Coastguard Worker                                                   "    fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
5761*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
5762*35238bceSAndroid Build Coastguard Worker         static const char *const geometrySource = "${GLSL_VERSION_DECL}\n"
5763*35238bceSAndroid Build Coastguard Worker                                                   "${GLSL_EXT_GEOMETRY_SHADER}"
5764*35238bceSAndroid Build Coastguard Worker                                                   "layout(points) in;\n"
5765*35238bceSAndroid Build Coastguard Worker                                                   "layout(points, max_vertices=1) out;\n"
5766*35238bceSAndroid Build Coastguard Worker                                                   "uniform highp vec4 u_offset;\n"
5767*35238bceSAndroid Build Coastguard Worker                                                   "void main (void)\n"
5768*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
5769*35238bceSAndroid Build Coastguard Worker                                                   "    gl_Position = gl_in[0].gl_Position + u_offset;\n"
5770*35238bceSAndroid Build Coastguard Worker                                                   "    EmitVertex();\n"
5771*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
5772*35238bceSAndroid Build Coastguard Worker 
5773*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(
5774*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(),
5775*35238bceSAndroid Build Coastguard Worker             glu::ProgramSources() << glu::VertexSource(
5776*35238bceSAndroid Build Coastguard Worker                                          specializeShader(vertexSource, m_context.getRenderContext().getType()))
5777*35238bceSAndroid Build Coastguard Worker                                   << glu::FragmentSource(
5778*35238bceSAndroid Build Coastguard Worker                                          specializeShader(fragmentSource, m_context.getRenderContext().getType()))
5779*35238bceSAndroid Build Coastguard Worker                                   << glu::GeometrySource(
5780*35238bceSAndroid Build Coastguard Worker                                          specializeShader(geometrySource, m_context.getRenderContext().getType())));
5781*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
5782*35238bceSAndroid Build Coastguard Worker 
5783*35238bceSAndroid Build Coastguard Worker         {
5784*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "ReferencedUniform", "Referenced uniform u_offset");
5785*35238bceSAndroid Build Coastguard Worker             glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5786*35238bceSAndroid Build Coastguard Worker             const uint32_t props[1] = {GL_REFERENCED_BY_GEOMETRY_SHADER};
5787*35238bceSAndroid Build Coastguard Worker             uint32_t resourcePos;
5788*35238bceSAndroid Build Coastguard Worker             glw::GLsizei length   = 0;
5789*35238bceSAndroid Build Coastguard Worker             glw::GLint referenced = 0;
5790*35238bceSAndroid Build Coastguard Worker 
5791*35238bceSAndroid Build Coastguard Worker             gl.enableLogging(true);
5792*35238bceSAndroid Build Coastguard Worker 
5793*35238bceSAndroid Build Coastguard Worker             resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_offset");
5794*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "u_offset resource index: " << resourcePos
5795*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
5796*35238bceSAndroid Build Coastguard Worker 
5797*35238bceSAndroid Build Coastguard Worker             gl.glGetProgramResourceiv(program.getProgram(), GL_UNIFORM, resourcePos, 1, props, 1, &length, &referenced);
5798*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Query GL_REFERENCED_BY_GEOMETRY_SHADER, got " << length
5799*35238bceSAndroid Build Coastguard Worker                                << " value(s), value[0] = " << glu::getBooleanStr(referenced)
5800*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
5801*35238bceSAndroid Build Coastguard Worker 
5802*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.glGetError(), "query resource");
5803*35238bceSAndroid Build Coastguard Worker 
5804*35238bceSAndroid Build Coastguard Worker             if (length == 0 || referenced != GL_TRUE)
5805*35238bceSAndroid Build Coastguard Worker             {
5806*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected GL_TRUE." << tcu::TestLog::EndMessage;
5807*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected value");
5808*35238bceSAndroid Build Coastguard Worker             }
5809*35238bceSAndroid Build Coastguard Worker         }
5810*35238bceSAndroid Build Coastguard Worker     }
5811*35238bceSAndroid Build Coastguard Worker 
5812*35238bceSAndroid Build Coastguard Worker     return STOP;
5813*35238bceSAndroid Build Coastguard Worker }
5814*35238bceSAndroid Build Coastguard Worker 
5815*35238bceSAndroid Build Coastguard Worker class CombinedGeometryUniformLimitCase : public GeometryShaderFeartureTestCase
5816*35238bceSAndroid Build Coastguard Worker {
5817*35238bceSAndroid Build Coastguard Worker public:
5818*35238bceSAndroid Build Coastguard Worker     CombinedGeometryUniformLimitCase(Context &context, const char *name, const char *desc);
5819*35238bceSAndroid Build Coastguard Worker 
5820*35238bceSAndroid Build Coastguard Worker private:
5821*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5822*35238bceSAndroid Build Coastguard Worker };
5823*35238bceSAndroid Build Coastguard Worker 
CombinedGeometryUniformLimitCase(Context & context,const char * name,const char * desc)5824*35238bceSAndroid Build Coastguard Worker CombinedGeometryUniformLimitCase::CombinedGeometryUniformLimitCase(Context &context, const char *name, const char *desc)
5825*35238bceSAndroid Build Coastguard Worker     : GeometryShaderFeartureTestCase(context, name, desc)
5826*35238bceSAndroid Build Coastguard Worker {
5827*35238bceSAndroid Build Coastguard Worker }
5828*35238bceSAndroid Build Coastguard Worker 
iterate(void)5829*35238bceSAndroid Build Coastguard Worker CombinedGeometryUniformLimitCase::IterateResult CombinedGeometryUniformLimitCase::iterate(void)
5830*35238bceSAndroid Build Coastguard Worker {
5831*35238bceSAndroid Build Coastguard Worker     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
5832*35238bceSAndroid Build Coastguard Worker     tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
5833*35238bceSAndroid Build Coastguard Worker 
5834*35238bceSAndroid Build Coastguard Worker     gl.enableLogging(true);
5835*35238bceSAndroid Build Coastguard Worker 
5836*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
5837*35238bceSAndroid Build Coastguard Worker                        << "The minimum value of MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS is "
5838*35238bceSAndroid Build Coastguard Worker                           "MAX_GEOMETRY_UNIFORM_BLOCKS x MAX_UNIFORM_BLOCK_SIZE / 4 + MAX_GEOMETRY_UNIFORM_COMPONENTS"
5839*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
5840*35238bceSAndroid Build Coastguard Worker 
5841*35238bceSAndroid Build Coastguard Worker     StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlocks;
5842*35238bceSAndroid Build Coastguard Worker     gl.glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &maxUniformBlocks);
5843*35238bceSAndroid Build Coastguard Worker     GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
5844*35238bceSAndroid Build Coastguard Worker 
5845*35238bceSAndroid Build Coastguard Worker     StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlockSize;
5846*35238bceSAndroid Build Coastguard Worker     gl.glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
5847*35238bceSAndroid Build Coastguard Worker     GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
5848*35238bceSAndroid Build Coastguard Worker 
5849*35238bceSAndroid Build Coastguard Worker     StateQueryMemoryWriteGuard<glw::GLint> maxUniformComponents;
5850*35238bceSAndroid Build Coastguard Worker     gl.glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, &maxUniformComponents);
5851*35238bceSAndroid Build Coastguard Worker     GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
5852*35238bceSAndroid Build Coastguard Worker 
5853*35238bceSAndroid Build Coastguard Worker     if (maxUniformBlocks.verifyValidity(result) && maxUniformBlockSize.verifyValidity(result) &&
5854*35238bceSAndroid Build Coastguard Worker         maxUniformComponents.verifyValidity(result))
5855*35238bceSAndroid Build Coastguard Worker     {
5856*35238bceSAndroid Build Coastguard Worker         const int limit = ((int)maxUniformBlocks) * ((int)maxUniformBlockSize) / 4 + (int)maxUniformComponents;
5857*35238bceSAndroid Build Coastguard Worker         verifyStateIntegerMin(result, gl, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, limit, QUERY_INTEGER);
5858*35238bceSAndroid Build Coastguard Worker 
5859*35238bceSAndroid Build Coastguard Worker         {
5860*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries");
5861*35238bceSAndroid Build Coastguard Worker             verifyStateIntegerMin(result, gl, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, limit, QUERY_BOOLEAN);
5862*35238bceSAndroid Build Coastguard Worker             verifyStateIntegerMin(result, gl, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, limit, QUERY_INTEGER64);
5863*35238bceSAndroid Build Coastguard Worker             verifyStateIntegerMin(result, gl, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, limit, QUERY_FLOAT);
5864*35238bceSAndroid Build Coastguard Worker         }
5865*35238bceSAndroid Build Coastguard Worker     }
5866*35238bceSAndroid Build Coastguard Worker 
5867*35238bceSAndroid Build Coastguard Worker     result.setTestContextResult(m_testCtx);
5868*35238bceSAndroid Build Coastguard Worker     return STOP;
5869*35238bceSAndroid Build Coastguard Worker }
5870*35238bceSAndroid Build Coastguard Worker 
5871*35238bceSAndroid Build Coastguard Worker class VertexFeedbackCase : public TestCase
5872*35238bceSAndroid Build Coastguard Worker {
5873*35238bceSAndroid Build Coastguard Worker public:
5874*35238bceSAndroid Build Coastguard Worker     enum DrawMethod
5875*35238bceSAndroid Build Coastguard Worker     {
5876*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ARRAYS = 0,
5877*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ARRAYS_INSTANCED,
5878*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ARRAYS_INDIRECT,
5879*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ELEMENTS,
5880*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ELEMENTS_INSTANCED,
5881*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ELEMENTS_INDIRECT,
5882*35238bceSAndroid Build Coastguard Worker 
5883*35238bceSAndroid Build Coastguard Worker         METHOD_LAST
5884*35238bceSAndroid Build Coastguard Worker     };
5885*35238bceSAndroid Build Coastguard Worker     enum PrimitiveType
5886*35238bceSAndroid Build Coastguard Worker     {
5887*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_LINE_LOOP = 0,
5888*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_LINE_STRIP,
5889*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_TRIANGLE_STRIP,
5890*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_TRIANGLE_FAN,
5891*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_POINTS,
5892*35238bceSAndroid Build Coastguard Worker 
5893*35238bceSAndroid Build Coastguard Worker         PRIMITIVE_LAST
5894*35238bceSAndroid Build Coastguard Worker     };
5895*35238bceSAndroid Build Coastguard Worker 
5896*35238bceSAndroid Build Coastguard Worker     VertexFeedbackCase(Context &context, const char *name, const char *description, DrawMethod method,
5897*35238bceSAndroid Build Coastguard Worker                        PrimitiveType output);
5898*35238bceSAndroid Build Coastguard Worker     ~VertexFeedbackCase(void);
5899*35238bceSAndroid Build Coastguard Worker 
5900*35238bceSAndroid Build Coastguard Worker private:
5901*35238bceSAndroid Build Coastguard Worker     void init(void);
5902*35238bceSAndroid Build Coastguard Worker     void deinit(void);
5903*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
5904*35238bceSAndroid Build Coastguard Worker 
5905*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *genProgram(void);
5906*35238bceSAndroid Build Coastguard Worker     uint32_t getOutputPrimitive(void);
5907*35238bceSAndroid Build Coastguard Worker     uint32_t getBasePrimitive(void);
5908*35238bceSAndroid Build Coastguard Worker 
5909*35238bceSAndroid Build Coastguard Worker     const DrawMethod m_method;
5910*35238bceSAndroid Build Coastguard Worker     const PrimitiveType m_output;
5911*35238bceSAndroid Build Coastguard Worker 
5912*35238bceSAndroid Build Coastguard Worker     uint32_t m_elementBuf;
5913*35238bceSAndroid Build Coastguard Worker     uint32_t m_arrayBuf;
5914*35238bceSAndroid Build Coastguard Worker     uint32_t m_offsetBuf;
5915*35238bceSAndroid Build Coastguard Worker     uint32_t m_feedbackBuf;
5916*35238bceSAndroid Build Coastguard Worker     uint32_t m_indirectBuffer;
5917*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_program;
5918*35238bceSAndroid Build Coastguard Worker     glu::VertexArray *m_vao;
5919*35238bceSAndroid Build Coastguard Worker };
5920*35238bceSAndroid Build Coastguard Worker 
VertexFeedbackCase(Context & context,const char * name,const char * description,DrawMethod method,PrimitiveType output)5921*35238bceSAndroid Build Coastguard Worker VertexFeedbackCase::VertexFeedbackCase(Context &context, const char *name, const char *description, DrawMethod method,
5922*35238bceSAndroid Build Coastguard Worker                                        PrimitiveType output)
5923*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
5924*35238bceSAndroid Build Coastguard Worker     , m_method(method)
5925*35238bceSAndroid Build Coastguard Worker     , m_output(output)
5926*35238bceSAndroid Build Coastguard Worker     , m_elementBuf(0)
5927*35238bceSAndroid Build Coastguard Worker     , m_arrayBuf(0)
5928*35238bceSAndroid Build Coastguard Worker     , m_offsetBuf(0)
5929*35238bceSAndroid Build Coastguard Worker     , m_feedbackBuf(0)
5930*35238bceSAndroid Build Coastguard Worker     , m_indirectBuffer(0)
5931*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
5932*35238bceSAndroid Build Coastguard Worker     , m_vao(DE_NULL)
5933*35238bceSAndroid Build Coastguard Worker {
5934*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(method < METHOD_LAST);
5935*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(output < PRIMITIVE_LAST);
5936*35238bceSAndroid Build Coastguard Worker }
5937*35238bceSAndroid Build Coastguard Worker 
~VertexFeedbackCase(void)5938*35238bceSAndroid Build Coastguard Worker VertexFeedbackCase::~VertexFeedbackCase(void)
5939*35238bceSAndroid Build Coastguard Worker {
5940*35238bceSAndroid Build Coastguard Worker     deinit();
5941*35238bceSAndroid Build Coastguard Worker }
5942*35238bceSAndroid Build Coastguard Worker 
init(void)5943*35238bceSAndroid Build Coastguard Worker void VertexFeedbackCase::init(void)
5944*35238bceSAndroid Build Coastguard Worker {
5945*35238bceSAndroid Build Coastguard Worker     // requirements
5946*35238bceSAndroid Build Coastguard Worker 
5947*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
5948*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
5949*35238bceSAndroid Build Coastguard Worker 
5950*35238bceSAndroid Build Coastguard Worker     // log what test tries to do
5951*35238bceSAndroid Build Coastguard Worker 
5952*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Testing GL_EXT_geometry_shader transform feedback relaxations.\n"
5953*35238bceSAndroid Build Coastguard Worker                        << "Capturing vertex shader varying, no geometry shader. Invoke with:"
5954*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
5955*35238bceSAndroid Build Coastguard Worker 
5956*35238bceSAndroid Build Coastguard Worker     switch (m_method)
5957*35238bceSAndroid Build Coastguard Worker     {
5958*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS:
5959*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawArrays" << tcu::TestLog::EndMessage;
5960*35238bceSAndroid Build Coastguard Worker         break;
5961*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS_INSTANCED:
5962*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawArraysInstanced" << tcu::TestLog::EndMessage;
5963*35238bceSAndroid Build Coastguard Worker         break;
5964*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS_INDIRECT:
5965*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawArraysIndirect" << tcu::TestLog::EndMessage;
5966*35238bceSAndroid Build Coastguard Worker         break;
5967*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS:
5968*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawElements" << tcu::TestLog::EndMessage;
5969*35238bceSAndroid Build Coastguard Worker         break;
5970*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS_INSTANCED:
5971*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawElementsInstanced" << tcu::TestLog::EndMessage;
5972*35238bceSAndroid Build Coastguard Worker         break;
5973*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS_INDIRECT:
5974*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw method: drawElementsIndirect" << tcu::TestLog::EndMessage;
5975*35238bceSAndroid Build Coastguard Worker         break;
5976*35238bceSAndroid Build Coastguard Worker     default:
5977*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
5978*35238bceSAndroid Build Coastguard Worker     }
5979*35238bceSAndroid Build Coastguard Worker     switch (m_output)
5980*35238bceSAndroid Build Coastguard Worker     {
5981*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_LOOP:
5982*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw primitive: line loop" << tcu::TestLog::EndMessage;
5983*35238bceSAndroid Build Coastguard Worker         break;
5984*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_STRIP:
5985*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw primitive: line strip" << tcu::TestLog::EndMessage;
5986*35238bceSAndroid Build Coastguard Worker         break;
5987*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_STRIP:
5988*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw primitive: triangle strip" << tcu::TestLog::EndMessage;
5989*35238bceSAndroid Build Coastguard Worker         break;
5990*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_FAN:
5991*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw primitive: triangle fan" << tcu::TestLog::EndMessage;
5992*35238bceSAndroid Build Coastguard Worker         break;
5993*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_POINTS:
5994*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Draw primitive: points" << tcu::TestLog::EndMessage;
5995*35238bceSAndroid Build Coastguard Worker         break;
5996*35238bceSAndroid Build Coastguard Worker     default:
5997*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
5998*35238bceSAndroid Build Coastguard Worker     }
5999*35238bceSAndroid Build Coastguard Worker 
6000*35238bceSAndroid Build Coastguard Worker     // resources
6001*35238bceSAndroid Build Coastguard Worker 
6002*35238bceSAndroid Build Coastguard Worker     {
6003*35238bceSAndroid Build Coastguard Worker         static const uint16_t elementData[] = {
6004*35238bceSAndroid Build Coastguard Worker             0,
6005*35238bceSAndroid Build Coastguard Worker             1,
6006*35238bceSAndroid Build Coastguard Worker             2,
6007*35238bceSAndroid Build Coastguard Worker             3,
6008*35238bceSAndroid Build Coastguard Worker         };
6009*35238bceSAndroid Build Coastguard Worker         static const tcu::Vec4 arrayData[] = {
6010*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6011*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
6012*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f),
6013*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f),
6014*35238bceSAndroid Build Coastguard Worker         };
6015*35238bceSAndroid Build Coastguard Worker         static const tcu::Vec4 offsetData[] = {
6016*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6017*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6018*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6019*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6020*35238bceSAndroid Build Coastguard Worker         };
6021*35238bceSAndroid Build Coastguard Worker 
6022*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
6023*35238bceSAndroid Build Coastguard Worker         const int feedbackSize   = 8 * (int)sizeof(float[4]);
6024*35238bceSAndroid Build Coastguard Worker 
6025*35238bceSAndroid Build Coastguard Worker         m_vao = new glu::VertexArray(m_context.getRenderContext());
6026*35238bceSAndroid Build Coastguard Worker         gl.bindVertexArray(**m_vao);
6027*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set up vao");
6028*35238bceSAndroid Build Coastguard Worker 
6029*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_elementBuf);
6030*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuf);
6031*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), &elementData[0], GL_STATIC_DRAW);
6032*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6033*35238bceSAndroid Build Coastguard Worker 
6034*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_arrayBuf);
6035*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuf);
6036*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, sizeof(arrayData), &arrayData[0], GL_STATIC_DRAW);
6037*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6038*35238bceSAndroid Build Coastguard Worker 
6039*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_offsetBuf);
6040*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, m_offsetBuf);
6041*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, sizeof(offsetData), &offsetData[0], GL_STATIC_DRAW);
6042*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6043*35238bceSAndroid Build Coastguard Worker 
6044*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_feedbackBuf);
6045*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_feedbackBuf);
6046*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackSize, DE_NULL, GL_DYNAMIC_COPY);
6047*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6048*35238bceSAndroid Build Coastguard Worker 
6049*35238bceSAndroid Build Coastguard Worker         m_program = genProgram();
6050*35238bceSAndroid Build Coastguard Worker 
6051*35238bceSAndroid Build Coastguard Worker         if (!m_program->isOk())
6052*35238bceSAndroid Build Coastguard Worker         {
6053*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << *m_program;
6054*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("could not build program");
6055*35238bceSAndroid Build Coastguard Worker         }
6056*35238bceSAndroid Build Coastguard Worker     }
6057*35238bceSAndroid Build Coastguard Worker }
6058*35238bceSAndroid Build Coastguard Worker 
deinit(void)6059*35238bceSAndroid Build Coastguard Worker void VertexFeedbackCase::deinit(void)
6060*35238bceSAndroid Build Coastguard Worker {
6061*35238bceSAndroid Build Coastguard Worker     if (m_elementBuf)
6062*35238bceSAndroid Build Coastguard Worker     {
6063*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_elementBuf);
6064*35238bceSAndroid Build Coastguard Worker         m_elementBuf = 0;
6065*35238bceSAndroid Build Coastguard Worker     }
6066*35238bceSAndroid Build Coastguard Worker 
6067*35238bceSAndroid Build Coastguard Worker     if (m_arrayBuf)
6068*35238bceSAndroid Build Coastguard Worker     {
6069*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_arrayBuf);
6070*35238bceSAndroid Build Coastguard Worker         m_arrayBuf = 0;
6071*35238bceSAndroid Build Coastguard Worker     }
6072*35238bceSAndroid Build Coastguard Worker 
6073*35238bceSAndroid Build Coastguard Worker     if (m_offsetBuf)
6074*35238bceSAndroid Build Coastguard Worker     {
6075*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_offsetBuf);
6076*35238bceSAndroid Build Coastguard Worker         m_offsetBuf = 0;
6077*35238bceSAndroid Build Coastguard Worker     }
6078*35238bceSAndroid Build Coastguard Worker 
6079*35238bceSAndroid Build Coastguard Worker     if (m_feedbackBuf)
6080*35238bceSAndroid Build Coastguard Worker     {
6081*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_feedbackBuf);
6082*35238bceSAndroid Build Coastguard Worker         m_feedbackBuf = 0;
6083*35238bceSAndroid Build Coastguard Worker     }
6084*35238bceSAndroid Build Coastguard Worker 
6085*35238bceSAndroid Build Coastguard Worker     if (m_indirectBuffer)
6086*35238bceSAndroid Build Coastguard Worker     {
6087*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indirectBuffer);
6088*35238bceSAndroid Build Coastguard Worker         m_indirectBuffer = 0;
6089*35238bceSAndroid Build Coastguard Worker     }
6090*35238bceSAndroid Build Coastguard Worker 
6091*35238bceSAndroid Build Coastguard Worker     delete m_program;
6092*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
6093*35238bceSAndroid Build Coastguard Worker 
6094*35238bceSAndroid Build Coastguard Worker     delete m_vao;
6095*35238bceSAndroid Build Coastguard Worker     m_vao = DE_NULL;
6096*35238bceSAndroid Build Coastguard Worker }
6097*35238bceSAndroid Build Coastguard Worker 
iterate(void)6098*35238bceSAndroid Build Coastguard Worker VertexFeedbackCase::IterateResult VertexFeedbackCase::iterate(void)
6099*35238bceSAndroid Build Coastguard Worker {
6100*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl       = m_context.getRenderContext().getFunctions();
6101*35238bceSAndroid Build Coastguard Worker     const uint32_t outputPrimitive = getOutputPrimitive();
6102*35238bceSAndroid Build Coastguard Worker     const uint32_t basePrimitive   = getBasePrimitive();
6103*35238bceSAndroid Build Coastguard Worker 
6104*35238bceSAndroid Build Coastguard Worker     const int posLocation    = gl.getAttribLocation(m_program->getProgram(), "a_position");
6105*35238bceSAndroid Build Coastguard Worker     const int offsetLocation = gl.getAttribLocation(m_program->getProgram(), "a_offset");
6106*35238bceSAndroid Build Coastguard Worker 
6107*35238bceSAndroid Build Coastguard Worker     if (posLocation == -1)
6108*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("a_position location was -1");
6109*35238bceSAndroid Build Coastguard Worker     if (offsetLocation == -1)
6110*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("a_offset location was -1");
6111*35238bceSAndroid Build Coastguard Worker 
6112*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_program->getProgram());
6113*35238bceSAndroid Build Coastguard Worker 
6114*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuf);
6115*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6116*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(posLocation);
6117*35238bceSAndroid Build Coastguard Worker 
6118*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, m_offsetBuf);
6119*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(offsetLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6120*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(offsetLocation);
6121*35238bceSAndroid Build Coastguard Worker 
6122*35238bceSAndroid Build Coastguard Worker     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_feedbackBuf);
6123*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "bind buffer base");
6124*35238bceSAndroid Build Coastguard Worker 
6125*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Calling BeginTransformFeedback("
6126*35238bceSAndroid Build Coastguard Worker                        << glu::getPrimitiveTypeStr(basePrimitive) << ")" << tcu::TestLog::EndMessage;
6127*35238bceSAndroid Build Coastguard Worker     gl.beginTransformFeedback(basePrimitive);
6128*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "beginTransformFeedback");
6129*35238bceSAndroid Build Coastguard Worker 
6130*35238bceSAndroid Build Coastguard Worker     switch (m_method)
6131*35238bceSAndroid Build Coastguard Worker     {
6132*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS:
6133*35238bceSAndroid Build Coastguard Worker     {
6134*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawArrays("
6135*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6136*35238bceSAndroid Build Coastguard Worker         gl.drawArrays(outputPrimitive, 0, 4);
6137*35238bceSAndroid Build Coastguard Worker         break;
6138*35238bceSAndroid Build Coastguard Worker     }
6139*35238bceSAndroid Build Coastguard Worker 
6140*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS_INSTANCED:
6141*35238bceSAndroid Build Coastguard Worker     {
6142*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawArraysInstanced("
6143*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6144*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribDivisor(offsetLocation, 2);
6145*35238bceSAndroid Build Coastguard Worker         gl.drawArraysInstanced(outputPrimitive, 0, 3, 2);
6146*35238bceSAndroid Build Coastguard Worker         break;
6147*35238bceSAndroid Build Coastguard Worker     }
6148*35238bceSAndroid Build Coastguard Worker 
6149*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS:
6150*35238bceSAndroid Build Coastguard Worker     {
6151*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawElements("
6152*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6153*35238bceSAndroid Build Coastguard Worker         gl.drawElements(outputPrimitive, 4, GL_UNSIGNED_SHORT, DE_NULL);
6154*35238bceSAndroid Build Coastguard Worker         break;
6155*35238bceSAndroid Build Coastguard Worker     }
6156*35238bceSAndroid Build Coastguard Worker 
6157*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS_INSTANCED:
6158*35238bceSAndroid Build Coastguard Worker     {
6159*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawElementsInstanced("
6160*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6161*35238bceSAndroid Build Coastguard Worker         gl.drawElementsInstanced(outputPrimitive, 3, GL_UNSIGNED_SHORT, DE_NULL, 2);
6162*35238bceSAndroid Build Coastguard Worker         break;
6163*35238bceSAndroid Build Coastguard Worker     }
6164*35238bceSAndroid Build Coastguard Worker 
6165*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ARRAYS_INDIRECT:
6166*35238bceSAndroid Build Coastguard Worker     {
6167*35238bceSAndroid Build Coastguard Worker         struct DrawArraysIndirectCommand
6168*35238bceSAndroid Build Coastguard Worker         {
6169*35238bceSAndroid Build Coastguard Worker             uint32_t count;
6170*35238bceSAndroid Build Coastguard Worker             uint32_t instanceCount;
6171*35238bceSAndroid Build Coastguard Worker             uint32_t first;
6172*35238bceSAndroid Build Coastguard Worker             uint32_t reservedMustBeZero;
6173*35238bceSAndroid Build Coastguard Worker         } params;
6174*35238bceSAndroid Build Coastguard Worker 
6175*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(DrawArraysIndirectCommand) == sizeof(uint32_t[4]));
6176*35238bceSAndroid Build Coastguard Worker 
6177*35238bceSAndroid Build Coastguard Worker         params.count              = 4;
6178*35238bceSAndroid Build Coastguard Worker         params.instanceCount      = 1;
6179*35238bceSAndroid Build Coastguard Worker         params.first              = 0;
6180*35238bceSAndroid Build Coastguard Worker         params.reservedMustBeZero = 0;
6181*35238bceSAndroid Build Coastguard Worker 
6182*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_indirectBuffer);
6183*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirectBuffer);
6184*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(params), &params, GL_STATIC_DRAW);
6185*35238bceSAndroid Build Coastguard Worker 
6186*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawElementsIndirect("
6187*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6188*35238bceSAndroid Build Coastguard Worker         gl.drawArraysIndirect(outputPrimitive, DE_NULL);
6189*35238bceSAndroid Build Coastguard Worker         break;
6190*35238bceSAndroid Build Coastguard Worker     }
6191*35238bceSAndroid Build Coastguard Worker 
6192*35238bceSAndroid Build Coastguard Worker     case METHOD_DRAW_ELEMENTS_INDIRECT:
6193*35238bceSAndroid Build Coastguard Worker     {
6194*35238bceSAndroid Build Coastguard Worker         struct DrawElementsIndirectCommand
6195*35238bceSAndroid Build Coastguard Worker         {
6196*35238bceSAndroid Build Coastguard Worker             uint32_t count;
6197*35238bceSAndroid Build Coastguard Worker             uint32_t instanceCount;
6198*35238bceSAndroid Build Coastguard Worker             uint32_t firstIndex;
6199*35238bceSAndroid Build Coastguard Worker             int32_t baseVertex;
6200*35238bceSAndroid Build Coastguard Worker             uint32_t reservedMustBeZero;
6201*35238bceSAndroid Build Coastguard Worker         } params;
6202*35238bceSAndroid Build Coastguard Worker 
6203*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(DrawElementsIndirectCommand) == sizeof(uint32_t[5]));
6204*35238bceSAndroid Build Coastguard Worker 
6205*35238bceSAndroid Build Coastguard Worker         params.count              = 4;
6206*35238bceSAndroid Build Coastguard Worker         params.instanceCount      = 1;
6207*35238bceSAndroid Build Coastguard Worker         params.firstIndex         = 0;
6208*35238bceSAndroid Build Coastguard Worker         params.baseVertex         = 0;
6209*35238bceSAndroid Build Coastguard Worker         params.reservedMustBeZero = 0;
6210*35238bceSAndroid Build Coastguard Worker 
6211*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_indirectBuffer);
6212*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirectBuffer);
6213*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(params), &params, GL_STATIC_DRAW);
6214*35238bceSAndroid Build Coastguard Worker 
6215*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Calling DrawElementsIndirect("
6216*35238bceSAndroid Build Coastguard Worker                            << glu::getPrimitiveTypeStr(outputPrimitive) << ", ...)" << tcu::TestLog::EndMessage;
6217*35238bceSAndroid Build Coastguard Worker         gl.drawElementsIndirect(outputPrimitive, GL_UNSIGNED_SHORT, DE_NULL);
6218*35238bceSAndroid Build Coastguard Worker         break;
6219*35238bceSAndroid Build Coastguard Worker     }
6220*35238bceSAndroid Build Coastguard Worker 
6221*35238bceSAndroid Build Coastguard Worker     default:
6222*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6223*35238bceSAndroid Build Coastguard Worker     }
6224*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
6225*35238bceSAndroid Build Coastguard Worker 
6226*35238bceSAndroid Build Coastguard Worker     gl.endTransformFeedback();
6227*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "endTransformFeedback");
6228*35238bceSAndroid Build Coastguard Worker 
6229*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "No errors." << tcu::TestLog::EndMessage;
6230*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6231*35238bceSAndroid Build Coastguard Worker 
6232*35238bceSAndroid Build Coastguard Worker     return STOP;
6233*35238bceSAndroid Build Coastguard Worker }
6234*35238bceSAndroid Build Coastguard Worker 
genProgram(void)6235*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *VertexFeedbackCase::genProgram(void)
6236*35238bceSAndroid Build Coastguard Worker {
6237*35238bceSAndroid Build Coastguard Worker     static const char *const vertexSource   = "${GLSL_VERSION_DECL}\n"
6238*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_position;\n"
6239*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_offset;\n"
6240*35238bceSAndroid Build Coastguard Worker                                               "out highp vec4 tf_value;\n"
6241*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
6242*35238bceSAndroid Build Coastguard Worker                                               "{\n"
6243*35238bceSAndroid Build Coastguard Worker                                               "    gl_Position = a_position;\n"
6244*35238bceSAndroid Build Coastguard Worker                                               "    tf_value = a_position + a_offset;\n"
6245*35238bceSAndroid Build Coastguard Worker                                               "}\n";
6246*35238bceSAndroid Build Coastguard Worker     static const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
6247*35238bceSAndroid Build Coastguard Worker                                               "layout(location = 0) out mediump vec4 fragColor;\n"
6248*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
6249*35238bceSAndroid Build Coastguard Worker                                               "{\n"
6250*35238bceSAndroid Build Coastguard Worker                                               "    fragColor = vec4(1.0);\n"
6251*35238bceSAndroid Build Coastguard Worker                                               "}\n";
6252*35238bceSAndroid Build Coastguard Worker 
6253*35238bceSAndroid Build Coastguard Worker     return new glu::ShaderProgram(m_context.getRenderContext(),
6254*35238bceSAndroid Build Coastguard Worker                                   glu::ProgramSources() << glu::VertexSource(specializeShader(
6255*35238bceSAndroid Build Coastguard Worker                                                                vertexSource, m_context.getRenderContext().getType()))
6256*35238bceSAndroid Build Coastguard Worker                                                         << glu::FragmentSource(specializeShader(
6257*35238bceSAndroid Build Coastguard Worker                                                                fragmentSource, m_context.getRenderContext().getType()))
6258*35238bceSAndroid Build Coastguard Worker                                                         << glu::TransformFeedbackVarying("tf_value")
6259*35238bceSAndroid Build Coastguard Worker                                                         << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS));
6260*35238bceSAndroid Build Coastguard Worker }
6261*35238bceSAndroid Build Coastguard Worker 
getOutputPrimitive(void)6262*35238bceSAndroid Build Coastguard Worker uint32_t VertexFeedbackCase::getOutputPrimitive(void)
6263*35238bceSAndroid Build Coastguard Worker {
6264*35238bceSAndroid Build Coastguard Worker     switch (m_output)
6265*35238bceSAndroid Build Coastguard Worker     {
6266*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_LOOP:
6267*35238bceSAndroid Build Coastguard Worker         return GL_LINE_LOOP;
6268*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_STRIP:
6269*35238bceSAndroid Build Coastguard Worker         return GL_LINE_STRIP;
6270*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_STRIP:
6271*35238bceSAndroid Build Coastguard Worker         return GL_TRIANGLE_STRIP;
6272*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_FAN:
6273*35238bceSAndroid Build Coastguard Worker         return GL_TRIANGLE_FAN;
6274*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_POINTS:
6275*35238bceSAndroid Build Coastguard Worker         return GL_POINTS;
6276*35238bceSAndroid Build Coastguard Worker     default:
6277*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6278*35238bceSAndroid Build Coastguard Worker         return 0;
6279*35238bceSAndroid Build Coastguard Worker     }
6280*35238bceSAndroid Build Coastguard Worker }
6281*35238bceSAndroid Build Coastguard Worker 
getBasePrimitive(void)6282*35238bceSAndroid Build Coastguard Worker uint32_t VertexFeedbackCase::getBasePrimitive(void)
6283*35238bceSAndroid Build Coastguard Worker {
6284*35238bceSAndroid Build Coastguard Worker     switch (m_output)
6285*35238bceSAndroid Build Coastguard Worker     {
6286*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_LOOP:
6287*35238bceSAndroid Build Coastguard Worker         return GL_LINES;
6288*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_LINE_STRIP:
6289*35238bceSAndroid Build Coastguard Worker         return GL_LINES;
6290*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_STRIP:
6291*35238bceSAndroid Build Coastguard Worker         return GL_TRIANGLES;
6292*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_TRIANGLE_FAN:
6293*35238bceSAndroid Build Coastguard Worker         return GL_TRIANGLES;
6294*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_POINTS:
6295*35238bceSAndroid Build Coastguard Worker         return GL_POINTS;
6296*35238bceSAndroid Build Coastguard Worker     default:
6297*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6298*35238bceSAndroid Build Coastguard Worker         return 0;
6299*35238bceSAndroid Build Coastguard Worker     }
6300*35238bceSAndroid Build Coastguard Worker }
6301*35238bceSAndroid Build Coastguard Worker 
6302*35238bceSAndroid Build Coastguard Worker class VertexFeedbackOverflowCase : public TestCase
6303*35238bceSAndroid Build Coastguard Worker {
6304*35238bceSAndroid Build Coastguard Worker public:
6305*35238bceSAndroid Build Coastguard Worker     enum Method
6306*35238bceSAndroid Build Coastguard Worker     {
6307*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ARRAYS = 0,
6308*35238bceSAndroid Build Coastguard Worker         METHOD_DRAW_ELEMENTS,
6309*35238bceSAndroid Build Coastguard Worker     };
6310*35238bceSAndroid Build Coastguard Worker 
6311*35238bceSAndroid Build Coastguard Worker     VertexFeedbackOverflowCase(Context &context, const char *name, const char *description, Method method);
6312*35238bceSAndroid Build Coastguard Worker     ~VertexFeedbackOverflowCase(void);
6313*35238bceSAndroid Build Coastguard Worker 
6314*35238bceSAndroid Build Coastguard Worker private:
6315*35238bceSAndroid Build Coastguard Worker     void init(void);
6316*35238bceSAndroid Build Coastguard Worker     void deinit(void);
6317*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
6318*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *genProgram(void);
6319*35238bceSAndroid Build Coastguard Worker 
6320*35238bceSAndroid Build Coastguard Worker     const Method m_method;
6321*35238bceSAndroid Build Coastguard Worker 
6322*35238bceSAndroid Build Coastguard Worker     uint32_t m_elementBuf;
6323*35238bceSAndroid Build Coastguard Worker     uint32_t m_arrayBuf;
6324*35238bceSAndroid Build Coastguard Worker     uint32_t m_feedbackBuf;
6325*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_program;
6326*35238bceSAndroid Build Coastguard Worker     glu::VertexArray *m_vao;
6327*35238bceSAndroid Build Coastguard Worker };
6328*35238bceSAndroid Build Coastguard Worker 
VertexFeedbackOverflowCase(Context & context,const char * name,const char * description,Method method)6329*35238bceSAndroid Build Coastguard Worker VertexFeedbackOverflowCase::VertexFeedbackOverflowCase(Context &context, const char *name, const char *description,
6330*35238bceSAndroid Build Coastguard Worker                                                        Method method)
6331*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
6332*35238bceSAndroid Build Coastguard Worker     , m_method(method)
6333*35238bceSAndroid Build Coastguard Worker     , m_elementBuf(0)
6334*35238bceSAndroid Build Coastguard Worker     , m_arrayBuf(0)
6335*35238bceSAndroid Build Coastguard Worker     , m_feedbackBuf(0)
6336*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
6337*35238bceSAndroid Build Coastguard Worker     , m_vao(DE_NULL)
6338*35238bceSAndroid Build Coastguard Worker {
6339*35238bceSAndroid Build Coastguard Worker }
6340*35238bceSAndroid Build Coastguard Worker 
~VertexFeedbackOverflowCase(void)6341*35238bceSAndroid Build Coastguard Worker VertexFeedbackOverflowCase::~VertexFeedbackOverflowCase(void)
6342*35238bceSAndroid Build Coastguard Worker {
6343*35238bceSAndroid Build Coastguard Worker     deinit();
6344*35238bceSAndroid Build Coastguard Worker }
6345*35238bceSAndroid Build Coastguard Worker 
init(void)6346*35238bceSAndroid Build Coastguard Worker void VertexFeedbackOverflowCase::init(void)
6347*35238bceSAndroid Build Coastguard Worker {
6348*35238bceSAndroid Build Coastguard Worker     // requirements
6349*35238bceSAndroid Build Coastguard Worker 
6350*35238bceSAndroid Build Coastguard Worker     if (!checkSupport(m_context))
6351*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
6352*35238bceSAndroid Build Coastguard Worker 
6353*35238bceSAndroid Build Coastguard Worker     // log what test tries to do
6354*35238bceSAndroid Build Coastguard Worker 
6355*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog()
6356*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Message << "Testing GL_EXT_geometry_shader transform feedback overflow behavior.\n"
6357*35238bceSAndroid Build Coastguard Worker         << "Capturing vertex shader varying, rendering 2 triangles. Allocating feedback buffer for 5 vertices."
6358*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::EndMessage;
6359*35238bceSAndroid Build Coastguard Worker 
6360*35238bceSAndroid Build Coastguard Worker     // resources
6361*35238bceSAndroid Build Coastguard Worker 
6362*35238bceSAndroid Build Coastguard Worker     {
6363*35238bceSAndroid Build Coastguard Worker         static const uint16_t elementData[] = {
6364*35238bceSAndroid Build Coastguard Worker             0, 1, 2, 0, 1, 2,
6365*35238bceSAndroid Build Coastguard Worker         };
6366*35238bceSAndroid Build Coastguard Worker         static const tcu::Vec4 arrayData[] = {
6367*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
6368*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
6369*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
6370*35238bceSAndroid Build Coastguard Worker             tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
6371*35238bceSAndroid Build Coastguard Worker         };
6372*35238bceSAndroid Build Coastguard Worker 
6373*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
6374*35238bceSAndroid Build Coastguard Worker 
6375*35238bceSAndroid Build Coastguard Worker         m_vao = new glu::VertexArray(m_context.getRenderContext());
6376*35238bceSAndroid Build Coastguard Worker         gl.bindVertexArray(**m_vao);
6377*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "set up vao");
6378*35238bceSAndroid Build Coastguard Worker 
6379*35238bceSAndroid Build Coastguard Worker         if (m_method == METHOD_DRAW_ELEMENTS)
6380*35238bceSAndroid Build Coastguard Worker         {
6381*35238bceSAndroid Build Coastguard Worker             gl.genBuffers(1, &m_elementBuf);
6382*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuf);
6383*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), &elementData[0], GL_STATIC_DRAW);
6384*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6385*35238bceSAndroid Build Coastguard Worker         }
6386*35238bceSAndroid Build Coastguard Worker 
6387*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_arrayBuf);
6388*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuf);
6389*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, sizeof(arrayData), &arrayData[0], GL_STATIC_DRAW);
6390*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6391*35238bceSAndroid Build Coastguard Worker 
6392*35238bceSAndroid Build Coastguard Worker         {
6393*35238bceSAndroid Build Coastguard Worker             const int feedbackCount = 5 * 4; // 5x vec4
6394*35238bceSAndroid Build Coastguard Worker             const std::vector<float> initialBufferContents(feedbackCount, -1.0f);
6395*35238bceSAndroid Build Coastguard Worker 
6396*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Filling feeback buffer with unused value (-1.0)."
6397*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
6398*35238bceSAndroid Build Coastguard Worker 
6399*35238bceSAndroid Build Coastguard Worker             gl.genBuffers(1, &m_feedbackBuf);
6400*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_feedbackBuf);
6401*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (int)(sizeof(float) * initialBufferContents.size()),
6402*35238bceSAndroid Build Coastguard Worker                           &initialBufferContents[0], GL_DYNAMIC_COPY);
6403*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "gen buf");
6404*35238bceSAndroid Build Coastguard Worker         }
6405*35238bceSAndroid Build Coastguard Worker 
6406*35238bceSAndroid Build Coastguard Worker         m_program = genProgram();
6407*35238bceSAndroid Build Coastguard Worker 
6408*35238bceSAndroid Build Coastguard Worker         if (!m_program->isOk())
6409*35238bceSAndroid Build Coastguard Worker         {
6410*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << *m_program;
6411*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("could not build program");
6412*35238bceSAndroid Build Coastguard Worker         }
6413*35238bceSAndroid Build Coastguard Worker     }
6414*35238bceSAndroid Build Coastguard Worker }
6415*35238bceSAndroid Build Coastguard Worker 
deinit(void)6416*35238bceSAndroid Build Coastguard Worker void VertexFeedbackOverflowCase::deinit(void)
6417*35238bceSAndroid Build Coastguard Worker {
6418*35238bceSAndroid Build Coastguard Worker     if (m_elementBuf)
6419*35238bceSAndroid Build Coastguard Worker     {
6420*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_elementBuf);
6421*35238bceSAndroid Build Coastguard Worker         m_elementBuf = 0;
6422*35238bceSAndroid Build Coastguard Worker     }
6423*35238bceSAndroid Build Coastguard Worker 
6424*35238bceSAndroid Build Coastguard Worker     if (m_arrayBuf)
6425*35238bceSAndroid Build Coastguard Worker     {
6426*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_arrayBuf);
6427*35238bceSAndroid Build Coastguard Worker         m_arrayBuf = 0;
6428*35238bceSAndroid Build Coastguard Worker     }
6429*35238bceSAndroid Build Coastguard Worker 
6430*35238bceSAndroid Build Coastguard Worker     if (m_feedbackBuf)
6431*35238bceSAndroid Build Coastguard Worker     {
6432*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_feedbackBuf);
6433*35238bceSAndroid Build Coastguard Worker         m_feedbackBuf = 0;
6434*35238bceSAndroid Build Coastguard Worker     }
6435*35238bceSAndroid Build Coastguard Worker 
6436*35238bceSAndroid Build Coastguard Worker     delete m_program;
6437*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
6438*35238bceSAndroid Build Coastguard Worker 
6439*35238bceSAndroid Build Coastguard Worker     delete m_vao;
6440*35238bceSAndroid Build Coastguard Worker     m_vao = DE_NULL;
6441*35238bceSAndroid Build Coastguard Worker }
6442*35238bceSAndroid Build Coastguard Worker 
iterate(void)6443*35238bceSAndroid Build Coastguard Worker VertexFeedbackOverflowCase::IterateResult VertexFeedbackOverflowCase::iterate(void)
6444*35238bceSAndroid Build Coastguard Worker {
6445*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
6446*35238bceSAndroid Build Coastguard Worker     const int posLocation    = gl.getAttribLocation(m_program->getProgram(), "a_position");
6447*35238bceSAndroid Build Coastguard Worker 
6448*35238bceSAndroid Build Coastguard Worker     if (posLocation == -1)
6449*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("a_position location was -1");
6450*35238bceSAndroid Build Coastguard Worker 
6451*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_program->getProgram());
6452*35238bceSAndroid Build Coastguard Worker 
6453*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuf);
6454*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
6455*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(posLocation);
6456*35238bceSAndroid Build Coastguard Worker 
6457*35238bceSAndroid Build Coastguard Worker     if (m_method == METHOD_DRAW_ELEMENTS)
6458*35238bceSAndroid Build Coastguard Worker     {
6459*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuf);
6460*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "bind buffers");
6461*35238bceSAndroid Build Coastguard Worker     }
6462*35238bceSAndroid Build Coastguard Worker 
6463*35238bceSAndroid Build Coastguard Worker     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_feedbackBuf);
6464*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "bind buffer base");
6465*35238bceSAndroid Build Coastguard Worker 
6466*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Capturing 2 triangles." << tcu::TestLog::EndMessage;
6467*35238bceSAndroid Build Coastguard Worker 
6468*35238bceSAndroid Build Coastguard Worker     gl.beginTransformFeedback(GL_TRIANGLES);
6469*35238bceSAndroid Build Coastguard Worker 
6470*35238bceSAndroid Build Coastguard Worker     if (m_method == METHOD_DRAW_ELEMENTS)
6471*35238bceSAndroid Build Coastguard Worker         gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
6472*35238bceSAndroid Build Coastguard Worker     else if (m_method == METHOD_DRAW_ARRAYS)
6473*35238bceSAndroid Build Coastguard Worker         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
6474*35238bceSAndroid Build Coastguard Worker     else
6475*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6476*35238bceSAndroid Build Coastguard Worker 
6477*35238bceSAndroid Build Coastguard Worker     gl.endTransformFeedback();
6478*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "capture");
6479*35238bceSAndroid Build Coastguard Worker 
6480*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
6481*35238bceSAndroid Build Coastguard Worker                        << "Verifying final triangle was not partially written to the feedback buffer."
6482*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
6483*35238bceSAndroid Build Coastguard Worker 
6484*35238bceSAndroid Build Coastguard Worker     {
6485*35238bceSAndroid Build Coastguard Worker         const void *ptr = gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(float[4]) * 5, GL_MAP_READ_BIT);
6486*35238bceSAndroid Build Coastguard Worker         std::vector<float> feedback;
6487*35238bceSAndroid Build Coastguard Worker         bool error = false;
6488*35238bceSAndroid Build Coastguard Worker 
6489*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "mapBufferRange");
6490*35238bceSAndroid Build Coastguard Worker         if (!ptr)
6491*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("mapBufferRange returned null");
6492*35238bceSAndroid Build Coastguard Worker 
6493*35238bceSAndroid Build Coastguard Worker         feedback.resize(5 * 4);
6494*35238bceSAndroid Build Coastguard Worker         deMemcpy(&feedback[0], ptr, sizeof(float[4]) * 5);
6495*35238bceSAndroid Build Coastguard Worker 
6496*35238bceSAndroid Build Coastguard Worker         if (gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER) != GL_TRUE)
6497*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("unmapBuffer returned false");
6498*35238bceSAndroid Build Coastguard Worker 
6499*35238bceSAndroid Build Coastguard Worker         // Verify vertices 0 - 2
6500*35238bceSAndroid Build Coastguard Worker         for (int vertex = 0; vertex < 3; ++vertex)
6501*35238bceSAndroid Build Coastguard Worker         {
6502*35238bceSAndroid Build Coastguard Worker             for (int component = 0; component < 4; ++component)
6503*35238bceSAndroid Build Coastguard Worker             {
6504*35238bceSAndroid Build Coastguard Worker                 if (feedback[vertex * 4 + component] != 1.0f)
6505*35238bceSAndroid Build Coastguard Worker                 {
6506*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Feedback buffer vertex " << vertex << ", component "
6507*35238bceSAndroid Build Coastguard Worker                                        << component << ": unexpected value, expected 1.0, got "
6508*35238bceSAndroid Build Coastguard Worker                                        << feedback[vertex * 4 + component] << tcu::TestLog::EndMessage;
6509*35238bceSAndroid Build Coastguard Worker                     error = true;
6510*35238bceSAndroid Build Coastguard Worker                 }
6511*35238bceSAndroid Build Coastguard Worker             }
6512*35238bceSAndroid Build Coastguard Worker         }
6513*35238bceSAndroid Build Coastguard Worker 
6514*35238bceSAndroid Build Coastguard Worker         // Verify vertices 3 - 4
6515*35238bceSAndroid Build Coastguard Worker         for (int vertex = 3; vertex < 5; ++vertex)
6516*35238bceSAndroid Build Coastguard Worker         {
6517*35238bceSAndroid Build Coastguard Worker             for (int component = 0; component < 4; ++component)
6518*35238bceSAndroid Build Coastguard Worker             {
6519*35238bceSAndroid Build Coastguard Worker                 if (feedback[vertex * 4 + component] != -1.0f)
6520*35238bceSAndroid Build Coastguard Worker                 {
6521*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Feedback buffer vertex " << vertex << ", component "
6522*35238bceSAndroid Build Coastguard Worker                                        << component << ": unexpected value, expected -1.0, got "
6523*35238bceSAndroid Build Coastguard Worker                                        << feedback[vertex * 4 + component] << tcu::TestLog::EndMessage;
6524*35238bceSAndroid Build Coastguard Worker                     error = true;
6525*35238bceSAndroid Build Coastguard Worker                 }
6526*35238bceSAndroid Build Coastguard Worker             }
6527*35238bceSAndroid Build Coastguard Worker         }
6528*35238bceSAndroid Build Coastguard Worker 
6529*35238bceSAndroid Build Coastguard Worker         if (error)
6530*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Feedback result validation failed");
6531*35238bceSAndroid Build Coastguard Worker         else
6532*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6533*35238bceSAndroid Build Coastguard Worker     }
6534*35238bceSAndroid Build Coastguard Worker 
6535*35238bceSAndroid Build Coastguard Worker     return STOP;
6536*35238bceSAndroid Build Coastguard Worker }
6537*35238bceSAndroid Build Coastguard Worker 
genProgram(void)6538*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *VertexFeedbackOverflowCase::genProgram(void)
6539*35238bceSAndroid Build Coastguard Worker {
6540*35238bceSAndroid Build Coastguard Worker     static const char *const vertexSource   = "${GLSL_VERSION_DECL}\n"
6541*35238bceSAndroid Build Coastguard Worker                                               "in highp vec4 a_position;\n"
6542*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
6543*35238bceSAndroid Build Coastguard Worker                                               "{\n"
6544*35238bceSAndroid Build Coastguard Worker                                               "    gl_Position = a_position;\n"
6545*35238bceSAndroid Build Coastguard Worker                                               "}\n";
6546*35238bceSAndroid Build Coastguard Worker     static const char *const fragmentSource = "${GLSL_VERSION_DECL}\n"
6547*35238bceSAndroid Build Coastguard Worker                                               "layout(location = 0) out mediump vec4 fragColor;\n"
6548*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
6549*35238bceSAndroid Build Coastguard Worker                                               "{\n"
6550*35238bceSAndroid Build Coastguard Worker                                               "    fragColor = vec4(1.0);\n"
6551*35238bceSAndroid Build Coastguard Worker                                               "}\n";
6552*35238bceSAndroid Build Coastguard Worker 
6553*35238bceSAndroid Build Coastguard Worker     return new glu::ShaderProgram(m_context.getRenderContext(),
6554*35238bceSAndroid Build Coastguard Worker                                   glu::ProgramSources() << glu::VertexSource(specializeShader(
6555*35238bceSAndroid Build Coastguard Worker                                                                vertexSource, m_context.getRenderContext().getType()))
6556*35238bceSAndroid Build Coastguard Worker                                                         << glu::FragmentSource(specializeShader(
6557*35238bceSAndroid Build Coastguard Worker                                                                fragmentSource, m_context.getRenderContext().getType()))
6558*35238bceSAndroid Build Coastguard Worker                                                         << glu::TransformFeedbackVarying("gl_Position")
6559*35238bceSAndroid Build Coastguard Worker                                                         << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS));
6560*35238bceSAndroid Build Coastguard Worker }
6561*35238bceSAndroid Build Coastguard Worker 
6562*35238bceSAndroid Build Coastguard Worker } // namespace
6563*35238bceSAndroid Build Coastguard Worker 
GeometryShaderTests(Context & context,bool isGL45)6564*35238bceSAndroid Build Coastguard Worker GeometryShaderTests::GeometryShaderTests(Context &context, bool isGL45)
6565*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "geometry_shading", "Geometry shader tests")
6566*35238bceSAndroid Build Coastguard Worker     , m_isGL45(isGL45)
6567*35238bceSAndroid Build Coastguard Worker {
6568*35238bceSAndroid Build Coastguard Worker }
6569*35238bceSAndroid Build Coastguard Worker 
~GeometryShaderTests(void)6570*35238bceSAndroid Build Coastguard Worker GeometryShaderTests::~GeometryShaderTests(void)
6571*35238bceSAndroid Build Coastguard Worker {
6572*35238bceSAndroid Build Coastguard Worker }
6573*35238bceSAndroid Build Coastguard Worker 
init(void)6574*35238bceSAndroid Build Coastguard Worker void GeometryShaderTests::init(void)
6575*35238bceSAndroid Build Coastguard Worker {
6576*35238bceSAndroid Build Coastguard Worker     struct PrimitiveTestSpec
6577*35238bceSAndroid Build Coastguard Worker     {
6578*35238bceSAndroid Build Coastguard Worker         uint32_t primitiveType;
6579*35238bceSAndroid Build Coastguard Worker         const char *name;
6580*35238bceSAndroid Build Coastguard Worker         uint32_t outputType;
6581*35238bceSAndroid Build Coastguard Worker     };
6582*35238bceSAndroid Build Coastguard Worker 
6583*35238bceSAndroid Build Coastguard Worker     struct EmitTestSpec
6584*35238bceSAndroid Build Coastguard Worker     {
6585*35238bceSAndroid Build Coastguard Worker         uint32_t outputType;
6586*35238bceSAndroid Build Coastguard Worker         int emitCountA; //!< primitive A emit count
6587*35238bceSAndroid Build Coastguard Worker         int endCountA;  //!< primitive A end count
6588*35238bceSAndroid Build Coastguard Worker         int emitCountB; //!<
6589*35238bceSAndroid Build Coastguard Worker         int endCountB;  //!<
6590*35238bceSAndroid Build Coastguard Worker         const char *name;
6591*35238bceSAndroid Build Coastguard Worker     };
6592*35238bceSAndroid Build Coastguard Worker 
6593*35238bceSAndroid Build Coastguard Worker     static const struct LayeredTarget
6594*35238bceSAndroid Build Coastguard Worker     {
6595*35238bceSAndroid Build Coastguard Worker         LayeredRenderCase::LayeredRenderTargetType target;
6596*35238bceSAndroid Build Coastguard Worker         const char *name;
6597*35238bceSAndroid Build Coastguard Worker         const char *desc;
6598*35238bceSAndroid Build Coastguard Worker     } layerTargets[] = {
6599*35238bceSAndroid Build Coastguard Worker         {LayeredRenderCase::TARGET_CUBE, "cubemap", "cubemap"},
6600*35238bceSAndroid Build Coastguard Worker         {LayeredRenderCase::TARGET_3D, "3d", "3D texture"},
6601*35238bceSAndroid Build Coastguard Worker         {LayeredRenderCase::TARGET_2D_ARRAY, "2d_array", "2D array texture"},
6602*35238bceSAndroid Build Coastguard Worker         {LayeredRenderCase::TARGET_2D_MS_ARRAY, "2d_multisample_array", "2D multisample array texture"},
6603*35238bceSAndroid Build Coastguard Worker     };
6604*35238bceSAndroid Build Coastguard Worker 
6605*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const queryGroup = new tcu::TestCaseGroup(m_testCtx, "query", "Query tests.");
6606*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic tests.");
6607*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const inputPrimitiveGroup =
6608*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "input", "Different input primitives.");
6609*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const conversionPrimitiveGroup =
6610*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "conversion", "Different input and output primitives.");
6611*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const emitGroup      = new tcu::TestCaseGroup(m_testCtx, "emit", "Different emit counts.");
6612*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const varyingGroup   = new tcu::TestCaseGroup(m_testCtx, "varying", "Test varyings.");
6613*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const layeredGroup   = new tcu::TestCaseGroup(m_testCtx, "layered", "Layered rendering.");
6614*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const instancedGroup = new tcu::TestCaseGroup(m_testCtx, "instanced", "Instanced rendering.");
6615*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const negativeGroup  = new tcu::TestCaseGroup(m_testCtx, "negative", "Negative tests.");
6616*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const feedbackGroup =
6617*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "vertex_transform_feedback", "Transform feedback.");
6618*35238bceSAndroid Build Coastguard Worker 
6619*35238bceSAndroid Build Coastguard Worker     this->addChild(queryGroup);
6620*35238bceSAndroid Build Coastguard Worker     this->addChild(basicGroup);
6621*35238bceSAndroid Build Coastguard Worker     this->addChild(inputPrimitiveGroup);
6622*35238bceSAndroid Build Coastguard Worker     this->addChild(conversionPrimitiveGroup);
6623*35238bceSAndroid Build Coastguard Worker     this->addChild(emitGroup);
6624*35238bceSAndroid Build Coastguard Worker     this->addChild(varyingGroup);
6625*35238bceSAndroid Build Coastguard Worker     this->addChild(layeredGroup);
6626*35238bceSAndroid Build Coastguard Worker     this->addChild(instancedGroup);
6627*35238bceSAndroid Build Coastguard Worker     this->addChild(negativeGroup);
6628*35238bceSAndroid Build Coastguard Worker     this->addChild(feedbackGroup);
6629*35238bceSAndroid Build Coastguard Worker 
6630*35238bceSAndroid Build Coastguard Worker     // query test
6631*35238bceSAndroid Build Coastguard Worker     {
6632*35238bceSAndroid Build Coastguard Worker         // limits with a corresponding glsl constant
6633*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_input_components", "",
6634*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_INPUT_COMPONENTS,
6635*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryInputComponents", 64));
6636*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_output_components", "",
6637*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_OUTPUT_COMPONENTS,
6638*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryOutputComponents", 64));
6639*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_image_uniforms", "",
6640*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_IMAGE_UNIFORMS, "MaxGeometryImageUniforms",
6641*35238bceSAndroid Build Coastguard Worker                                                           0));
6642*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_texture_image_units", "",
6643*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,
6644*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryTextureImageUnits", 16));
6645*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_output_vertices", "",
6646*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_OUTPUT_VERTICES, "MaxGeometryOutputVertices",
6647*35238bceSAndroid Build Coastguard Worker                                                           256));
6648*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_total_output_components", "",
6649*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
6650*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryTotalOutputComponents", 1024));
6651*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_uniform_components", "",
6652*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_UNIFORM_COMPONENTS,
6653*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryUniformComponents", 1024));
6654*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_atomic_counters", "",
6655*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_ATOMIC_COUNTERS, "MaxGeometryAtomicCounters",
6656*35238bceSAndroid Build Coastguard Worker                                                           0));
6657*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new GeometryProgramLimitCase(m_context, "max_geometry_atomic_counter_buffers", "",
6658*35238bceSAndroid Build Coastguard Worker                                                           GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
6659*35238bceSAndroid Build Coastguard Worker                                                           "MaxGeometryAtomicCounterBuffers", 0));
6660*35238bceSAndroid Build Coastguard Worker 
6661*35238bceSAndroid Build Coastguard Worker         // program queries
6662*35238bceSAndroid Build Coastguard Worker         // ES only
6663*35238bceSAndroid Build Coastguard Worker         if (!m_isGL45)
6664*35238bceSAndroid Build Coastguard Worker         {
6665*35238bceSAndroid Build Coastguard Worker             queryGroup->addChild(new GeometryShaderVerticesQueryCase(m_context, "geometry_linked_vertices_out",
6666*35238bceSAndroid Build Coastguard Worker                                                                      "GL_GEOMETRY_LINKED_VERTICES_OUT"));
6667*35238bceSAndroid Build Coastguard Worker             queryGroup->addChild(new GeometryShaderInputQueryCase(m_context, "geometry_linked_input_type",
6668*35238bceSAndroid Build Coastguard Worker                                                                   "GL_GEOMETRY_LINKED_INPUT_TYPE"));
6669*35238bceSAndroid Build Coastguard Worker             queryGroup->addChild(new GeometryShaderOutputQueryCase(m_context, "geometry_linked_output_type",
6670*35238bceSAndroid Build Coastguard Worker                                                                    "GL_GEOMETRY_LINKED_OUTPUT_TYPE"));
6671*35238bceSAndroid Build Coastguard Worker             queryGroup->addChild(new GeometryShaderInvocationsQueryCase(m_context, "geometry_shader_invocations",
6672*35238bceSAndroid Build Coastguard Worker                                                                         "GL_GEOMETRY_SHADER_INVOCATIONS"));
6673*35238bceSAndroid Build Coastguard Worker         }
6674*35238bceSAndroid Build Coastguard Worker 
6675*35238bceSAndroid Build Coastguard Worker         // limits
6676*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new ImplementationLimitCase(m_context, "max_geometry_shader_invocations", "",
6677*35238bceSAndroid Build Coastguard Worker                                                          GL_MAX_GEOMETRY_SHADER_INVOCATIONS, 32));
6678*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new ImplementationLimitCase(m_context, "max_geometry_uniform_blocks", "",
6679*35238bceSAndroid Build Coastguard Worker                                                          GL_MAX_GEOMETRY_UNIFORM_BLOCKS, 12));
6680*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new ImplementationLimitCase(m_context, "max_geometry_shader_storage_blocks", "",
6681*35238bceSAndroid Build Coastguard Worker                                                          GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, 0));
6682*35238bceSAndroid Build Coastguard Worker 
6683*35238bceSAndroid Build Coastguard Worker         // layer_provoking_vertex_ext
6684*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(
6685*35238bceSAndroid Build Coastguard Worker             new LayerProvokingVertexQueryCase(m_context, "layer_provoking_vertex", "GL_LAYER_PROVOKING_VERTEX"));
6686*35238bceSAndroid Build Coastguard Worker 
6687*35238bceSAndroid Build Coastguard Worker         // primitives_generated
6688*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new PrimitivesGeneratedQueryCase(m_context, "primitives_generated_no_geometry",
6689*35238bceSAndroid Build Coastguard Worker                                                               "PRIMITIVES_GENERATED query with no geometry shader",
6690*35238bceSAndroid Build Coastguard Worker                                                               PrimitivesGeneratedQueryCase::TEST_NO_GEOMETRY));
6691*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(
6692*35238bceSAndroid Build Coastguard Worker             new PrimitivesGeneratedQueryCase(m_context, "primitives_generated_no_amplification",
6693*35238bceSAndroid Build Coastguard Worker                                              "PRIMITIVES_GENERATED query with non amplifying geometry shader",
6694*35238bceSAndroid Build Coastguard Worker                                              PrimitivesGeneratedQueryCase::TEST_NO_AMPLIFICATION));
6695*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(
6696*35238bceSAndroid Build Coastguard Worker             new PrimitivesGeneratedQueryCase(m_context, "primitives_generated_amplification",
6697*35238bceSAndroid Build Coastguard Worker                                              "PRIMITIVES_GENERATED query with amplifying geometry shader",
6698*35238bceSAndroid Build Coastguard Worker                                              PrimitivesGeneratedQueryCase::TEST_AMPLIFICATION));
6699*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new PrimitivesGeneratedQueryCase(
6700*35238bceSAndroid Build Coastguard Worker             m_context, "primitives_generated_partial_primitives",
6701*35238bceSAndroid Build Coastguard Worker             "PRIMITIVES_GENERATED query with geometry shader emitting partial primitives",
6702*35238bceSAndroid Build Coastguard Worker             PrimitivesGeneratedQueryCase::TEST_PARTIAL_PRIMITIVES));
6703*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new PrimitivesGeneratedQueryCase(
6704*35238bceSAndroid Build Coastguard Worker             m_context, "primitives_generated_instanced", "PRIMITIVES_GENERATED query with instanced geometry shader",
6705*35238bceSAndroid Build Coastguard Worker             PrimitivesGeneratedQueryCase::TEST_INSTANCED));
6706*35238bceSAndroid Build Coastguard Worker 
6707*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new PrimitivesGeneratedQueryObjectQueryCase(m_context, "primitives_generated",
6708*35238bceSAndroid Build Coastguard Worker                                                                          "Query bound PRIMITIVES_GENERATED query"));
6709*35238bceSAndroid Build Coastguard Worker 
6710*35238bceSAndroid Build Coastguard Worker         // fbo
6711*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(
6712*35238bceSAndroid Build Coastguard Worker             new ImplementationLimitCase(m_context, "max_framebuffer_layers", "", GL_MAX_FRAMEBUFFER_LAYERS, 256));
6713*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new FramebufferDefaultLayersCase(m_context, "framebuffer_default_layers", ""));
6714*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new FramebufferAttachmentLayeredCase(m_context, "framebuffer_attachment_layered", ""));
6715*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(
6716*35238bceSAndroid Build Coastguard Worker             new FramebufferIncompleteLayereTargetsCase(m_context, "framebuffer_incomplete_layer_targets", ""));
6717*35238bceSAndroid Build Coastguard Worker 
6718*35238bceSAndroid Build Coastguard Worker         // resource query
6719*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new ReferencedByGeometryShaderCase(m_context, "referenced_by_geometry_shader", ""));
6720*35238bceSAndroid Build Coastguard Worker 
6721*35238bceSAndroid Build Coastguard Worker         // combined limits
6722*35238bceSAndroid Build Coastguard Worker         queryGroup->addChild(new CombinedGeometryUniformLimitCase(m_context, "max_combined_geometry_uniform_components",
6723*35238bceSAndroid Build Coastguard Worker                                                                   "MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS"));
6724*35238bceSAndroid Build Coastguard Worker     }
6725*35238bceSAndroid Build Coastguard Worker 
6726*35238bceSAndroid Build Coastguard Worker     // basic tests
6727*35238bceSAndroid Build Coastguard Worker     {
6728*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(
6729*35238bceSAndroid Build Coastguard Worker             new OutputCountCase(m_context, "output_10", "Output 10 vertices", OutputCountPatternSpec(10)));
6730*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(
6731*35238bceSAndroid Build Coastguard Worker             new OutputCountCase(m_context, "output_128", "Output 128 vertices", OutputCountPatternSpec(128)));
6732*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(
6733*35238bceSAndroid Build Coastguard Worker             new OutputCountCase(m_context, "output_256", "Output 256 vertices", OutputCountPatternSpec(256)));
6734*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(
6735*35238bceSAndroid Build Coastguard Worker             new OutputCountCase(m_context, "output_max", "Output max vertices", OutputCountPatternSpec(-1)));
6736*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new OutputCountCase(m_context, "output_10_and_100",
6737*35238bceSAndroid Build Coastguard Worker                                                  "Output 10 and 100 vertices in two invocations",
6738*35238bceSAndroid Build Coastguard Worker                                                  OutputCountPatternSpec(10, 100)));
6739*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new OutputCountCase(m_context, "output_100_and_10",
6740*35238bceSAndroid Build Coastguard Worker                                                  "Output 100 and 10 vertices in two invocations",
6741*35238bceSAndroid Build Coastguard Worker                                                  OutputCountPatternSpec(100, 10)));
6742*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new OutputCountCase(m_context, "output_0_and_128",
6743*35238bceSAndroid Build Coastguard Worker                                                  "Output 0 and 128 vertices in two invocations",
6744*35238bceSAndroid Build Coastguard Worker                                                  OutputCountPatternSpec(0, 128)));
6745*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new OutputCountCase(m_context, "output_128_and_0",
6746*35238bceSAndroid Build Coastguard Worker                                                  "Output 128 and 0 vertices in two invocations",
6747*35238bceSAndroid Build Coastguard Worker                                                  OutputCountPatternSpec(128, 0)));
6748*35238bceSAndroid Build Coastguard Worker 
6749*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new VaryingOutputCountCase(
6750*35238bceSAndroid Build Coastguard Worker             m_context, "output_vary_by_attribute", "Output varying number of vertices",
6751*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_ATTRIBUTE, VaryingOutputCountCase::MODE_WITHOUT_INSTANCING));
6752*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new VaryingOutputCountCase(
6753*35238bceSAndroid Build Coastguard Worker             m_context, "output_vary_by_uniform", "Output varying number of vertices",
6754*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_UNIFORM, VaryingOutputCountCase::MODE_WITHOUT_INSTANCING));
6755*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new VaryingOutputCountCase(
6756*35238bceSAndroid Build Coastguard Worker             m_context, "output_vary_by_texture", "Output varying number of vertices",
6757*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_TEXTURE, VaryingOutputCountCase::MODE_WITHOUT_INSTANCING));
6758*35238bceSAndroid Build Coastguard Worker 
6759*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new BuiltinVariableRenderTest(m_context, "point_size", "test gl_PointSize",
6760*35238bceSAndroid Build Coastguard Worker                                                            BuiltinVariableShader::TEST_POINT_SIZE));
6761*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new BuiltinVariableRenderTest(m_context, "primitive_id_in", "test gl_PrimitiveIDIn",
6762*35238bceSAndroid Build Coastguard Worker                                                            BuiltinVariableShader::TEST_PRIMITIVE_ID_IN));
6763*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new BuiltinVariableRenderTest(
6764*35238bceSAndroid Build Coastguard Worker             m_context, "primitive_id_in_restarted", "test gl_PrimitiveIDIn with primitive restart",
6765*35238bceSAndroid Build Coastguard Worker             BuiltinVariableShader::TEST_PRIMITIVE_ID_IN,
6766*35238bceSAndroid Build Coastguard Worker             GeometryShaderRenderTest::FLAG_USE_RESTART_INDEX | GeometryShaderRenderTest::FLAG_USE_INDICES));
6767*35238bceSAndroid Build Coastguard Worker         basicGroup->addChild(new BuiltinVariableRenderTest(m_context, "primitive_id", "test gl_PrimitiveID",
6768*35238bceSAndroid Build Coastguard Worker                                                            BuiltinVariableShader::TEST_PRIMITIVE_ID));
6769*35238bceSAndroid Build Coastguard Worker     }
6770*35238bceSAndroid Build Coastguard Worker 
6771*35238bceSAndroid Build Coastguard Worker     // input primitives
6772*35238bceSAndroid Build Coastguard Worker     {
6773*35238bceSAndroid Build Coastguard Worker         static const PrimitiveTestSpec inputPrimitives[] = {
6774*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, "points", GL_POINTS},
6775*35238bceSAndroid Build Coastguard Worker             {GL_LINES, "lines", GL_LINE_STRIP},
6776*35238bceSAndroid Build Coastguard Worker             {GL_LINE_LOOP, "line_loop", GL_LINE_STRIP},
6777*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, "line_strip", GL_LINE_STRIP},
6778*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES, "triangles", GL_TRIANGLE_STRIP},
6779*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, "triangle_strip", GL_TRIANGLE_STRIP},
6780*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_FAN, "triangle_fan", GL_TRIANGLE_STRIP},
6781*35238bceSAndroid Build Coastguard Worker             {GL_LINES_ADJACENCY, "lines_adjacency", GL_LINE_STRIP},
6782*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP_ADJACENCY, "line_strip_adjacency", GL_LINE_STRIP},
6783*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES_ADJACENCY, "triangles_adjacency", GL_TRIANGLE_STRIP}};
6784*35238bceSAndroid Build Coastguard Worker 
6785*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const basicPrimitiveGroup =
6786*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "basic_primitive", "Different input and output primitives.");
6787*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const triStripAdjacencyGroup = new tcu::TestCaseGroup(
6788*35238bceSAndroid Build Coastguard Worker             m_testCtx, "triangle_strip_adjacency", "Different triangle_strip_adjacency vertex counts.");
6789*35238bceSAndroid Build Coastguard Worker 
6790*35238bceSAndroid Build Coastguard Worker         // more basic types
6791*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(inputPrimitives); ++ndx)
6792*35238bceSAndroid Build Coastguard Worker             basicPrimitiveGroup->addChild(
6793*35238bceSAndroid Build Coastguard Worker                 new GeometryExpanderRenderTest(m_context, inputPrimitives[ndx].name, inputPrimitives[ndx].name,
6794*35238bceSAndroid Build Coastguard Worker                                                inputPrimitives[ndx].primitiveType, inputPrimitives[ndx].outputType));
6795*35238bceSAndroid Build Coastguard Worker 
6796*35238bceSAndroid Build Coastguard Worker         // triangle strip adjacency with different vtx counts
6797*35238bceSAndroid Build Coastguard Worker         for (int vtxCount = 0; vtxCount <= 12; ++vtxCount)
6798*35238bceSAndroid Build Coastguard Worker         {
6799*35238bceSAndroid Build Coastguard Worker             const std::string name = "vertex_count_" + de::toString(vtxCount);
6800*35238bceSAndroid Build Coastguard Worker             const std::string desc = "Vertex count is " + de::toString(vtxCount);
6801*35238bceSAndroid Build Coastguard Worker 
6802*35238bceSAndroid Build Coastguard Worker             triStripAdjacencyGroup->addChild(
6803*35238bceSAndroid Build Coastguard Worker                 new TriangleStripAdjacencyVertexCountTest(m_context, name.c_str(), desc.c_str(), vtxCount));
6804*35238bceSAndroid Build Coastguard Worker         }
6805*35238bceSAndroid Build Coastguard Worker 
6806*35238bceSAndroid Build Coastguard Worker         inputPrimitiveGroup->addChild(basicPrimitiveGroup);
6807*35238bceSAndroid Build Coastguard Worker         inputPrimitiveGroup->addChild(triStripAdjacencyGroup);
6808*35238bceSAndroid Build Coastguard Worker     }
6809*35238bceSAndroid Build Coastguard Worker 
6810*35238bceSAndroid Build Coastguard Worker     // different type conversions
6811*35238bceSAndroid Build Coastguard Worker     {
6812*35238bceSAndroid Build Coastguard Worker         static const PrimitiveTestSpec conversionPrimitives[] = {
6813*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES, "triangles_to_points", GL_POINTS},      {GL_LINES, "lines_to_points", GL_POINTS},
6814*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, "points_to_lines", GL_LINE_STRIP},         {GL_TRIANGLES, "triangles_to_lines", GL_LINE_STRIP},
6815*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, "points_to_triangles", GL_TRIANGLE_STRIP}, {GL_LINES, "lines_to_triangles", GL_TRIANGLE_STRIP}};
6816*35238bceSAndroid Build Coastguard Worker 
6817*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(conversionPrimitives); ++ndx)
6818*35238bceSAndroid Build Coastguard Worker             conversionPrimitiveGroup->addChild(new GeometryExpanderRenderTest(
6819*35238bceSAndroid Build Coastguard Worker                 m_context, conversionPrimitives[ndx].name, conversionPrimitives[ndx].name,
6820*35238bceSAndroid Build Coastguard Worker                 conversionPrimitives[ndx].primitiveType, conversionPrimitives[ndx].outputType));
6821*35238bceSAndroid Build Coastguard Worker     }
6822*35238bceSAndroid Build Coastguard Worker 
6823*35238bceSAndroid Build Coastguard Worker     // emit different amounts
6824*35238bceSAndroid Build Coastguard Worker     {
6825*35238bceSAndroid Build Coastguard Worker         static const EmitTestSpec emitTests[] = {
6826*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, 0, 0, 0, 0, "points"},
6827*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, 0, 1, 0, 0, "points"},
6828*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, 1, 1, 0, 0, "points"},
6829*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, 0, 2, 0, 0, "points"},
6830*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, 1, 2, 0, 0, "points"},
6831*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 0, 0, 0, 0, "line_strip"},
6832*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 0, 1, 0, 0, "line_strip"},
6833*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 1, 1, 0, 0, "line_strip"},
6834*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 2, 1, 0, 0, "line_strip"},
6835*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 0, 2, 0, 0, "line_strip"},
6836*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 1, 2, 0, 0, "line_strip"},
6837*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 2, 2, 0, 0, "line_strip"},
6838*35238bceSAndroid Build Coastguard Worker             {GL_LINE_STRIP, 2, 2, 2, 0, "line_strip"},
6839*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 0, 0, 0, 0, "triangle_strip"},
6840*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 0, 1, 0, 0, "triangle_strip"},
6841*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 1, 1, 0, 0, "triangle_strip"},
6842*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 2, 1, 0, 0, "triangle_strip"},
6843*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 3, 1, 0, 0, "triangle_strip"},
6844*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 0, 2, 0, 0, "triangle_strip"},
6845*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 1, 2, 0, 0, "triangle_strip"},
6846*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 2, 2, 0, 0, "triangle_strip"},
6847*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 3, 2, 0, 0, "triangle_strip"},
6848*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLE_STRIP, 3, 2, 3, 0, "triangle_strip"},
6849*35238bceSAndroid Build Coastguard Worker         };
6850*35238bceSAndroid Build Coastguard Worker 
6851*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(emitTests); ++ndx)
6852*35238bceSAndroid Build Coastguard Worker         {
6853*35238bceSAndroid Build Coastguard Worker             std::string name = std::string(emitTests[ndx].name) + "_emit_" + de::toString(emitTests[ndx].emitCountA) +
6854*35238bceSAndroid Build Coastguard Worker                                "_end_" + de::toString(emitTests[ndx].endCountA);
6855*35238bceSAndroid Build Coastguard Worker             std::string desc = std::string(emitTests[ndx].name) + " output, emit " +
6856*35238bceSAndroid Build Coastguard Worker                                de::toString(emitTests[ndx].emitCountA) + " vertices, call EndPrimitive " +
6857*35238bceSAndroid Build Coastguard Worker                                de::toString(emitTests[ndx].endCountA) + " times";
6858*35238bceSAndroid Build Coastguard Worker 
6859*35238bceSAndroid Build Coastguard Worker             if (emitTests[ndx].emitCountB)
6860*35238bceSAndroid Build Coastguard Worker             {
6861*35238bceSAndroid Build Coastguard Worker                 name += "_emit_" + de::toString(emitTests[ndx].emitCountB) + "_end_" +
6862*35238bceSAndroid Build Coastguard Worker                         de::toString(emitTests[ndx].endCountB);
6863*35238bceSAndroid Build Coastguard Worker                 desc += ", emit " + de::toString(emitTests[ndx].emitCountB) + " vertices, call EndPrimitive " +
6864*35238bceSAndroid Build Coastguard Worker                         de::toString(emitTests[ndx].endCountB) + " times";
6865*35238bceSAndroid Build Coastguard Worker             }
6866*35238bceSAndroid Build Coastguard Worker 
6867*35238bceSAndroid Build Coastguard Worker             emitGroup->addChild(new EmitTest(m_context, name.c_str(), desc.c_str(), emitTests[ndx].emitCountA,
6868*35238bceSAndroid Build Coastguard Worker                                              emitTests[ndx].endCountA, emitTests[ndx].emitCountB,
6869*35238bceSAndroid Build Coastguard Worker                                              emitTests[ndx].endCountB, emitTests[ndx].outputType));
6870*35238bceSAndroid Build Coastguard Worker         }
6871*35238bceSAndroid Build Coastguard Worker     }
6872*35238bceSAndroid Build Coastguard Worker 
6873*35238bceSAndroid Build Coastguard Worker     // varying
6874*35238bceSAndroid Build Coastguard Worker     {
6875*35238bceSAndroid Build Coastguard Worker         struct VaryingTestSpec
6876*35238bceSAndroid Build Coastguard Worker         {
6877*35238bceSAndroid Build Coastguard Worker             int vertexOutputs;
6878*35238bceSAndroid Build Coastguard Worker             int geometryOutputs;
6879*35238bceSAndroid Build Coastguard Worker             const char *name;
6880*35238bceSAndroid Build Coastguard Worker             const char *desc;
6881*35238bceSAndroid Build Coastguard Worker         };
6882*35238bceSAndroid Build Coastguard Worker 
6883*35238bceSAndroid Build Coastguard Worker         static const VaryingTestSpec varyingTests[] = {
6884*35238bceSAndroid Build Coastguard Worker             {-1, 1, "vertex_no_op_geometry_out_1", "vertex_no_op_geometry_out_1"},
6885*35238bceSAndroid Build Coastguard Worker             {0, 1, "vertex_out_0_geometry_out_1", "vertex_out_0_geometry_out_1"},
6886*35238bceSAndroid Build Coastguard Worker             {0, 2, "vertex_out_0_geometry_out_2", "vertex_out_0_geometry_out_2"},
6887*35238bceSAndroid Build Coastguard Worker             {1, 0, "vertex_out_1_geometry_out_0", "vertex_out_1_geometry_out_0"},
6888*35238bceSAndroid Build Coastguard Worker             {1, 2, "vertex_out_1_geometry_out_2", "vertex_out_1_geometry_out_2"},
6889*35238bceSAndroid Build Coastguard Worker         };
6890*35238bceSAndroid Build Coastguard Worker 
6891*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx)
6892*35238bceSAndroid Build Coastguard Worker             varyingGroup->addChild(new VaryingTest(m_context, varyingTests[ndx].name, varyingTests[ndx].desc,
6893*35238bceSAndroid Build Coastguard Worker                                                    varyingTests[ndx].vertexOutputs, varyingTests[ndx].geometryOutputs));
6894*35238bceSAndroid Build Coastguard Worker     }
6895*35238bceSAndroid Build Coastguard Worker 
6896*35238bceSAndroid Build Coastguard Worker     // layered
6897*35238bceSAndroid Build Coastguard Worker     {
6898*35238bceSAndroid Build Coastguard Worker         static const struct TestType
6899*35238bceSAndroid Build Coastguard Worker         {
6900*35238bceSAndroid Build Coastguard Worker             LayeredRenderCase::TestType test;
6901*35238bceSAndroid Build Coastguard Worker             const char *testPrefix;
6902*35238bceSAndroid Build Coastguard Worker             const char *descPrefix;
6903*35238bceSAndroid Build Coastguard Worker         } tests[] = {
6904*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_DEFAULT_LAYER, "render_with_default_layer_", "Render to all layers of "},
6905*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_SINGLE_LAYER, "render_to_one_", "Render to one layer of "},
6906*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_ALL_LAYERS, "render_to_all_", "Render to all layers of "},
6907*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_DIFFERENT_LAYERS, "render_different_to_",
6908*35238bceSAndroid Build Coastguard Worker              "Render different data to different layers"},
6909*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_LAYER_ID, "fragment_layer_", "Read gl_Layer in fragment shader"},
6910*35238bceSAndroid Build Coastguard Worker             {LayeredRenderCase::TEST_LAYER_PROVOKING_VERTEX, "layer_provoking_vertex_",
6911*35238bceSAndroid Build Coastguard Worker              "Verify LAYER_PROVOKING_VERTEX"},
6912*35238bceSAndroid Build Coastguard Worker         };
6913*35238bceSAndroid Build Coastguard Worker 
6914*35238bceSAndroid Build Coastguard Worker         for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
6915*35238bceSAndroid Build Coastguard Worker             for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(layerTargets); ++targetNdx)
6916*35238bceSAndroid Build Coastguard Worker             {
6917*35238bceSAndroid Build Coastguard Worker                 const std::string name = std::string(tests[testNdx].testPrefix) + layerTargets[targetNdx].name;
6918*35238bceSAndroid Build Coastguard Worker                 const std::string desc = std::string(tests[testNdx].descPrefix) + layerTargets[targetNdx].desc;
6919*35238bceSAndroid Build Coastguard Worker 
6920*35238bceSAndroid Build Coastguard Worker                 layeredGroup->addChild(new LayeredRenderCase(m_context, name.c_str(), desc.c_str(),
6921*35238bceSAndroid Build Coastguard Worker                                                              layerTargets[targetNdx].target, tests[testNdx].test));
6922*35238bceSAndroid Build Coastguard Worker             }
6923*35238bceSAndroid Build Coastguard Worker     }
6924*35238bceSAndroid Build Coastguard Worker 
6925*35238bceSAndroid Build Coastguard Worker     // instanced
6926*35238bceSAndroid Build Coastguard Worker     {
6927*35238bceSAndroid Build Coastguard Worker         static const struct InvocationCase
6928*35238bceSAndroid Build Coastguard Worker         {
6929*35238bceSAndroid Build Coastguard Worker             const char *name;
6930*35238bceSAndroid Build Coastguard Worker             int numInvocations;
6931*35238bceSAndroid Build Coastguard Worker         } invocationCases[] = {
6932*35238bceSAndroid Build Coastguard Worker             {"1", 1}, {"2", 2}, {"8", 8}, {"32", 32}, {"max", -1},
6933*35238bceSAndroid Build Coastguard Worker         };
6934*35238bceSAndroid Build Coastguard Worker         static const int numDrawInstances[]   = {2, 4, 8};
6935*35238bceSAndroid Build Coastguard Worker         static const int numDrawInvocations[] = {2, 8};
6936*35238bceSAndroid Build Coastguard Worker 
6937*35238bceSAndroid Build Coastguard Worker         // same amount of content to all invocations
6938*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(invocationCases); ++ndx)
6939*35238bceSAndroid Build Coastguard Worker             instancedGroup->addChild(new GeometryInvocationCase(
6940*35238bceSAndroid Build Coastguard Worker                 m_context, (std::string("geometry_") + invocationCases[ndx].name + "_invocations").c_str(),
6941*35238bceSAndroid Build Coastguard Worker                 (std::string("Geometry shader with ") + invocationCases[ndx].name + " invocation(s)").c_str(),
6942*35238bceSAndroid Build Coastguard Worker                 invocationCases[ndx].numInvocations, GeometryInvocationCase::CASE_FIXED_OUTPUT_COUNTS));
6943*35238bceSAndroid Build Coastguard Worker 
6944*35238bceSAndroid Build Coastguard Worker         // different amount of content to each invocation
6945*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(invocationCases); ++ndx)
6946*35238bceSAndroid Build Coastguard Worker             if (invocationCases[ndx].numInvocations != 1)
6947*35238bceSAndroid Build Coastguard Worker                 instancedGroup->addChild(new GeometryInvocationCase(
6948*35238bceSAndroid Build Coastguard Worker                     m_context,
6949*35238bceSAndroid Build Coastguard Worker                     (std::string("geometry_output_different_") + invocationCases[ndx].name + "_invocations").c_str(),
6950*35238bceSAndroid Build Coastguard Worker                     "Geometry shader invocation(s) with different emit counts", invocationCases[ndx].numInvocations,
6951*35238bceSAndroid Build Coastguard Worker                     GeometryInvocationCase::CASE_DIFFERENT_OUTPUT_COUNTS));
6952*35238bceSAndroid Build Coastguard Worker 
6953*35238bceSAndroid Build Coastguard Worker         // invocation per layer
6954*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(layerTargets); ++targetNdx)
6955*35238bceSAndroid Build Coastguard Worker         {
6956*35238bceSAndroid Build Coastguard Worker             const std::string name = std::string("invocation_per_layer_") + layerTargets[targetNdx].name;
6957*35238bceSAndroid Build Coastguard Worker             const std::string desc =
6958*35238bceSAndroid Build Coastguard Worker                 std::string("Render to multiple layers with multiple invocations, one invocation per layer, target ") +
6959*35238bceSAndroid Build Coastguard Worker                 layerTargets[targetNdx].desc;
6960*35238bceSAndroid Build Coastguard Worker 
6961*35238bceSAndroid Build Coastguard Worker             instancedGroup->addChild(new LayeredRenderCase(m_context, name.c_str(), desc.c_str(),
6962*35238bceSAndroid Build Coastguard Worker                                                            layerTargets[targetNdx].target,
6963*35238bceSAndroid Build Coastguard Worker                                                            LayeredRenderCase::TEST_INVOCATION_PER_LAYER));
6964*35238bceSAndroid Build Coastguard Worker         }
6965*35238bceSAndroid Build Coastguard Worker 
6966*35238bceSAndroid Build Coastguard Worker         // multiple layers per invocation
6967*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(layerTargets); ++targetNdx)
6968*35238bceSAndroid Build Coastguard Worker         {
6969*35238bceSAndroid Build Coastguard Worker             const std::string name = std::string("multiple_layers_per_invocation_") + layerTargets[targetNdx].name;
6970*35238bceSAndroid Build Coastguard Worker             const std::string desc =
6971*35238bceSAndroid Build Coastguard Worker                 std::string(
6972*35238bceSAndroid Build Coastguard Worker                     "Render to multiple layers with multiple invocations, multiple layers per invocation, target ") +
6973*35238bceSAndroid Build Coastguard Worker                 layerTargets[targetNdx].desc;
6974*35238bceSAndroid Build Coastguard Worker 
6975*35238bceSAndroid Build Coastguard Worker             instancedGroup->addChild(new LayeredRenderCase(m_context, name.c_str(), desc.c_str(),
6976*35238bceSAndroid Build Coastguard Worker                                                            layerTargets[targetNdx].target,
6977*35238bceSAndroid Build Coastguard Worker                                                            LayeredRenderCase::TEST_MULTIPLE_LAYERS_PER_INVOCATION));
6978*35238bceSAndroid Build Coastguard Worker         }
6979*35238bceSAndroid Build Coastguard Worker 
6980*35238bceSAndroid Build Coastguard Worker         // different invocation output counts depending on {uniform, attrib, texture}
6981*35238bceSAndroid Build Coastguard Worker         instancedGroup->addChild(new VaryingOutputCountCase(
6982*35238bceSAndroid Build Coastguard Worker             m_context, "invocation_output_vary_by_attribute", "Output varying number of vertices",
6983*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_ATTRIBUTE, VaryingOutputCountCase::MODE_WITH_INSTANCING));
6984*35238bceSAndroid Build Coastguard Worker         instancedGroup->addChild(new VaryingOutputCountCase(
6985*35238bceSAndroid Build Coastguard Worker             m_context, "invocation_output_vary_by_uniform", "Output varying number of vertices",
6986*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_UNIFORM, VaryingOutputCountCase::MODE_WITH_INSTANCING));
6987*35238bceSAndroid Build Coastguard Worker         instancedGroup->addChild(new VaryingOutputCountCase(
6988*35238bceSAndroid Build Coastguard Worker             m_context, "invocation_output_vary_by_texture", "Output varying number of vertices",
6989*35238bceSAndroid Build Coastguard Worker             VaryingOutputCountShader::READ_TEXTURE, VaryingOutputCountCase::MODE_WITH_INSTANCING));
6990*35238bceSAndroid Build Coastguard Worker 
6991*35238bceSAndroid Build Coastguard Worker         // with drawInstanced
6992*35238bceSAndroid Build Coastguard Worker         for (int instanceNdx = 0; instanceNdx < DE_LENGTH_OF_ARRAY(numDrawInstances); ++instanceNdx)
6993*35238bceSAndroid Build Coastguard Worker             for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(numDrawInvocations); ++invocationNdx)
6994*35238bceSAndroid Build Coastguard Worker             {
6995*35238bceSAndroid Build Coastguard Worker                 const std::string name = std::string("draw_") + de::toString(numDrawInstances[instanceNdx]) +
6996*35238bceSAndroid Build Coastguard Worker                                          "_instances_geometry_" + de::toString(numDrawInvocations[invocationNdx]) +
6997*35238bceSAndroid Build Coastguard Worker                                          "_invocations";
6998*35238bceSAndroid Build Coastguard Worker                 const std::string desc = std::string("Draw ") + de::toString(numDrawInstances[instanceNdx]) +
6999*35238bceSAndroid Build Coastguard Worker                                          " instances, with " + de::toString(numDrawInvocations[invocationNdx]) +
7000*35238bceSAndroid Build Coastguard Worker                                          " geometry shader invocations.";
7001*35238bceSAndroid Build Coastguard Worker 
7002*35238bceSAndroid Build Coastguard Worker                 instancedGroup->addChild(new DrawInstancedGeometryInstancedCase(m_context, name.c_str(), desc.c_str(),
7003*35238bceSAndroid Build Coastguard Worker                                                                                 numDrawInstances[instanceNdx],
7004*35238bceSAndroid Build Coastguard Worker                                                                                 numDrawInvocations[invocationNdx]));
7005*35238bceSAndroid Build Coastguard Worker             }
7006*35238bceSAndroid Build Coastguard Worker     }
7007*35238bceSAndroid Build Coastguard Worker 
7008*35238bceSAndroid Build Coastguard Worker     // negative (wrong types)
7009*35238bceSAndroid Build Coastguard Worker     {
7010*35238bceSAndroid Build Coastguard Worker         struct PrimitiveToInputTypeConversion
7011*35238bceSAndroid Build Coastguard Worker         {
7012*35238bceSAndroid Build Coastguard Worker             GLenum inputType;
7013*35238bceSAndroid Build Coastguard Worker             GLenum primitiveType;
7014*35238bceSAndroid Build Coastguard Worker         };
7015*35238bceSAndroid Build Coastguard Worker 
7016*35238bceSAndroid Build Coastguard Worker         static const PrimitiveToInputTypeConversion legalConversions[] = {
7017*35238bceSAndroid Build Coastguard Worker             {GL_POINTS, GL_POINTS},
7018*35238bceSAndroid Build Coastguard Worker             {GL_LINES, GL_LINES},
7019*35238bceSAndroid Build Coastguard Worker             {GL_LINES, GL_LINE_LOOP},
7020*35238bceSAndroid Build Coastguard Worker             {GL_LINES, GL_LINE_STRIP},
7021*35238bceSAndroid Build Coastguard Worker             {GL_LINES_ADJACENCY, GL_LINES_ADJACENCY},
7022*35238bceSAndroid Build Coastguard Worker             {GL_LINES_ADJACENCY, GL_LINE_STRIP_ADJACENCY},
7023*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES, GL_TRIANGLES},
7024*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES, GL_TRIANGLE_STRIP},
7025*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES, GL_TRIANGLE_FAN},
7026*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES_ADJACENCY, GL_TRIANGLES_ADJACENCY},
7027*35238bceSAndroid Build Coastguard Worker             {GL_TRIANGLES_ADJACENCY, GL_TRIANGLE_STRIP_ADJACENCY},
7028*35238bceSAndroid Build Coastguard Worker         };
7029*35238bceSAndroid Build Coastguard Worker 
7030*35238bceSAndroid Build Coastguard Worker         static const GLenum inputTypes[] = {GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES,
7031*35238bceSAndroid Build Coastguard Worker                                             GL_TRIANGLES_ADJACENCY};
7032*35238bceSAndroid Build Coastguard Worker 
7033*35238bceSAndroid Build Coastguard Worker         static const GLenum primitiveTypes[] = {GL_POINTS,
7034*35238bceSAndroid Build Coastguard Worker                                                 GL_LINES,
7035*35238bceSAndroid Build Coastguard Worker                                                 GL_LINE_LOOP,
7036*35238bceSAndroid Build Coastguard Worker                                                 GL_LINE_STRIP,
7037*35238bceSAndroid Build Coastguard Worker                                                 GL_LINES_ADJACENCY,
7038*35238bceSAndroid Build Coastguard Worker                                                 GL_LINE_STRIP_ADJACENCY,
7039*35238bceSAndroid Build Coastguard Worker                                                 GL_TRIANGLES,
7040*35238bceSAndroid Build Coastguard Worker                                                 GL_TRIANGLE_STRIP,
7041*35238bceSAndroid Build Coastguard Worker                                                 GL_TRIANGLE_FAN,
7042*35238bceSAndroid Build Coastguard Worker                                                 GL_TRIANGLES_ADJACENCY,
7043*35238bceSAndroid Build Coastguard Worker                                                 GL_TRIANGLE_STRIP_ADJACENCY};
7044*35238bceSAndroid Build Coastguard Worker 
7045*35238bceSAndroid Build Coastguard Worker         for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); ++inputTypeNdx)
7046*35238bceSAndroid Build Coastguard Worker             for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
7047*35238bceSAndroid Build Coastguard Worker             {
7048*35238bceSAndroid Build Coastguard Worker                 const GLenum inputType     = inputTypes[inputTypeNdx];
7049*35238bceSAndroid Build Coastguard Worker                 const GLenum primitiveType = primitiveTypes[primitiveTypeNdx];
7050*35238bceSAndroid Build Coastguard Worker                 const std::string name     = std::string("type_") +
7051*35238bceSAndroid Build Coastguard Worker                                          inputTypeToGLString(sglr::rr_util::mapGLGeometryShaderInputType(inputType)) +
7052*35238bceSAndroid Build Coastguard Worker                                          "_primitive_" + primitiveTypeToString(primitiveType);
7053*35238bceSAndroid Build Coastguard Worker                 const std::string desc = std::string("Shader input type ") +
7054*35238bceSAndroid Build Coastguard Worker                                          inputTypeToGLString(sglr::rr_util::mapGLGeometryShaderInputType(inputType)) +
7055*35238bceSAndroid Build Coastguard Worker                                          ", draw primitive type " + primitiveTypeToString(primitiveType);
7056*35238bceSAndroid Build Coastguard Worker 
7057*35238bceSAndroid Build Coastguard Worker                 bool isLegal = false;
7058*35238bceSAndroid Build Coastguard Worker 
7059*35238bceSAndroid Build Coastguard Worker                 for (int legalNdx = 0; legalNdx < DE_LENGTH_OF_ARRAY(legalConversions); ++legalNdx)
7060*35238bceSAndroid Build Coastguard Worker                     if (legalConversions[legalNdx].inputType == inputType &&
7061*35238bceSAndroid Build Coastguard Worker                         legalConversions[legalNdx].primitiveType == primitiveType)
7062*35238bceSAndroid Build Coastguard Worker                         isLegal = true;
7063*35238bceSAndroid Build Coastguard Worker 
7064*35238bceSAndroid Build Coastguard Worker                 // only illegal
7065*35238bceSAndroid Build Coastguard Worker                 if (!isLegal)
7066*35238bceSAndroid Build Coastguard Worker                     negativeGroup->addChild(
7067*35238bceSAndroid Build Coastguard Worker                         new NegativeDrawCase(m_context, name.c_str(), desc.c_str(), inputType, primitiveType));
7068*35238bceSAndroid Build Coastguard Worker             }
7069*35238bceSAndroid Build Coastguard Worker     }
7070*35238bceSAndroid Build Coastguard Worker 
7071*35238bceSAndroid Build Coastguard Worker     // vertex transform feedback
7072*35238bceSAndroid Build Coastguard Worker     {
7073*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(m_context, "capture_vertex_line_loop", "Capture line loop lines",
7074*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::METHOD_DRAW_ARRAYS,
7075*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::PRIMITIVE_LINE_LOOP));
7076*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(
7077*35238bceSAndroid Build Coastguard Worker             new VertexFeedbackCase(m_context, "capture_vertex_line_strip", "Capture line strip lines",
7078*35238bceSAndroid Build Coastguard Worker                                    VertexFeedbackCase::METHOD_DRAW_ARRAYS, VertexFeedbackCase::PRIMITIVE_LINE_STRIP));
7079*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(
7080*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_triangle_strip", "Capture triangle strip triangles",
7081*35238bceSAndroid Build Coastguard Worker             VertexFeedbackCase::METHOD_DRAW_ARRAYS, VertexFeedbackCase::PRIMITIVE_TRIANGLE_STRIP));
7082*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(
7083*35238bceSAndroid Build Coastguard Worker             new VertexFeedbackCase(m_context, "capture_vertex_triangle_fan", "Capture triangle fan triangles",
7084*35238bceSAndroid Build Coastguard Worker                                    VertexFeedbackCase::METHOD_DRAW_ARRAYS, VertexFeedbackCase::PRIMITIVE_TRIANGLE_FAN));
7085*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(
7086*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_arrays", "Capture primitives generated with drawArrays",
7087*35238bceSAndroid Build Coastguard Worker             VertexFeedbackCase::METHOD_DRAW_ARRAYS, VertexFeedbackCase::PRIMITIVE_POINTS));
7088*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(
7089*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_arrays_instanced", "Capture primitives generated with drawArraysInstanced",
7090*35238bceSAndroid Build Coastguard Worker             VertexFeedbackCase::METHOD_DRAW_ARRAYS_INSTANCED, VertexFeedbackCase::PRIMITIVE_POINTS));
7091*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(
7092*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_arrays_indirect", "Capture primitives generated with drawArraysIndirect",
7093*35238bceSAndroid Build Coastguard Worker             VertexFeedbackCase::METHOD_DRAW_ARRAYS_INDIRECT, VertexFeedbackCase::PRIMITIVE_POINTS));
7094*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(
7095*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_elements", "Capture primitives generated with drawElements",
7096*35238bceSAndroid Build Coastguard Worker             VertexFeedbackCase::METHOD_DRAW_ELEMENTS, VertexFeedbackCase::PRIMITIVE_POINTS));
7097*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(m_context, "capture_vertex_draw_elements_instanced",
7098*35238bceSAndroid Build Coastguard Worker                                                        "Capture primitives generated with drawElementsInstanced",
7099*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::METHOD_DRAW_ELEMENTS_INSTANCED,
7100*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::PRIMITIVE_POINTS));
7101*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackCase(m_context, "capture_vertex_draw_elements_indirect",
7102*35238bceSAndroid Build Coastguard Worker                                                        "Capture primitives generated with drawElementsIndirect",
7103*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::METHOD_DRAW_ELEMENTS_INDIRECT,
7104*35238bceSAndroid Build Coastguard Worker                                                        VertexFeedbackCase::PRIMITIVE_POINTS));
7105*35238bceSAndroid Build Coastguard Worker 
7106*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackOverflowCase(
7107*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_arrays_overflow_single_buffer", "Capture triangles to too small a buffer",
7108*35238bceSAndroid Build Coastguard Worker             VertexFeedbackOverflowCase::METHOD_DRAW_ARRAYS));
7109*35238bceSAndroid Build Coastguard Worker         feedbackGroup->addChild(new VertexFeedbackOverflowCase(
7110*35238bceSAndroid Build Coastguard Worker             m_context, "capture_vertex_draw_elements_overflow_single_buffer", "Capture triangles to too small a buffer",
7111*35238bceSAndroid Build Coastguard Worker             VertexFeedbackOverflowCase::METHOD_DRAW_ELEMENTS));
7112*35238bceSAndroid Build Coastguard Worker     }
7113*35238bceSAndroid Build Coastguard Worker }
7114*35238bceSAndroid Build Coastguard Worker 
7115*35238bceSAndroid Build Coastguard Worker } // namespace Functional
7116*35238bceSAndroid Build Coastguard Worker } // namespace gles31
7117*35238bceSAndroid Build Coastguard Worker } // namespace deqp
7118