xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fProgramInterfaceQueryTests.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 Program interface query tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceQueryTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceQueryTestCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceDefinition.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceDefinitionUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluVarTypeUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deString.h"
38*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "deSTLUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deArrayUtil.hpp"
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker #include <set>
45*35238bceSAndroid Build Coastguard Worker #include <map>
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker namespace deqp
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker namespace gles31
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker namespace Functional
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker namespace
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker 
getTypeSize(glu::DataType type)56*35238bceSAndroid Build Coastguard Worker static int getTypeSize(glu::DataType type)
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker     if (type == glu::TYPE_FLOAT)
59*35238bceSAndroid Build Coastguard Worker         return 4;
60*35238bceSAndroid Build Coastguard Worker     else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
61*35238bceSAndroid Build Coastguard Worker         return 4;
62*35238bceSAndroid Build Coastguard Worker     else if (type == glu::TYPE_BOOL)
63*35238bceSAndroid Build Coastguard Worker         return 4; // uint
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
66*35238bceSAndroid Build Coastguard Worker     return 0;
67*35238bceSAndroid Build Coastguard Worker }
68*35238bceSAndroid Build Coastguard Worker 
getVarTypeSize(const glu::VarType & type)69*35238bceSAndroid Build Coastguard Worker static int getVarTypeSize(const glu::VarType &type)
70*35238bceSAndroid Build Coastguard Worker {
71*35238bceSAndroid Build Coastguard Worker     if (type.isBasicType())
72*35238bceSAndroid Build Coastguard Worker         return glu::getDataTypeScalarSize(type.getBasicType()) *
73*35238bceSAndroid Build Coastguard Worker                getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
74*35238bceSAndroid Build Coastguard Worker     else if (type.isStructType())
75*35238bceSAndroid Build Coastguard Worker     {
76*35238bceSAndroid Build Coastguard Worker         int size = 0;
77*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
78*35238bceSAndroid Build Coastguard Worker             size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
79*35238bceSAndroid Build Coastguard Worker         return size;
80*35238bceSAndroid Build Coastguard Worker     }
81*35238bceSAndroid Build Coastguard Worker     else if (type.isArrayType())
82*35238bceSAndroid Build Coastguard Worker     {
83*35238bceSAndroid Build Coastguard Worker         if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
84*35238bceSAndroid Build Coastguard Worker             return getVarTypeSize(type.getElementType());
85*35238bceSAndroid Build Coastguard Worker         else
86*35238bceSAndroid Build Coastguard Worker             return type.getArraySize() * getVarTypeSize(type.getElementType());
87*35238bceSAndroid Build Coastguard Worker     }
88*35238bceSAndroid Build Coastguard Worker     else
89*35238bceSAndroid Build Coastguard Worker     {
90*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
91*35238bceSAndroid Build Coastguard Worker         return 0;
92*35238bceSAndroid Build Coastguard Worker     }
93*35238bceSAndroid Build Coastguard Worker }
94*35238bceSAndroid Build Coastguard Worker 
convertGLTypeNameToTestName(const char * glName)95*35238bceSAndroid Build Coastguard Worker static std::string convertGLTypeNameToTestName(const char *glName)
96*35238bceSAndroid Build Coastguard Worker {
97*35238bceSAndroid Build Coastguard Worker     // vectors and matrices are fine as is
98*35238bceSAndroid Build Coastguard Worker     {
99*35238bceSAndroid Build Coastguard Worker         if (deStringBeginsWith(glName, "vec") == true || deStringBeginsWith(glName, "ivec") == true ||
100*35238bceSAndroid Build Coastguard Worker             deStringBeginsWith(glName, "uvec") == true || deStringBeginsWith(glName, "bvec") == true ||
101*35238bceSAndroid Build Coastguard Worker             deStringBeginsWith(glName, "mat") == true)
102*35238bceSAndroid Build Coastguard Worker             return std::string(glName);
103*35238bceSAndroid Build Coastguard Worker     }
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker     // convert camel case to use underscore
106*35238bceSAndroid Build Coastguard Worker     {
107*35238bceSAndroid Build Coastguard Worker         std::ostringstream buf;
108*35238bceSAndroid Build Coastguard Worker         std::istringstream name(glName);
109*35238bceSAndroid Build Coastguard Worker         bool mergeNextToken        = false;
110*35238bceSAndroid Build Coastguard Worker         bool previousTokenWasDigit = false;
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker         while (!name.eof())
113*35238bceSAndroid Build Coastguard Worker         {
114*35238bceSAndroid Build Coastguard Worker             std::ostringstream token;
115*35238bceSAndroid Build Coastguard Worker 
116*35238bceSAndroid Build Coastguard Worker             while (name.peek() != EOF)
117*35238bceSAndroid Build Coastguard Worker             {
118*35238bceSAndroid Build Coastguard Worker                 if ((de::isDigit((char)name.peek()) || de::isUpper((char)name.peek())) && token.tellp())
119*35238bceSAndroid Build Coastguard Worker                     break;
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker                 token << de::toLower((char)name.get());
122*35238bceSAndroid Build Coastguard Worker             }
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker             if (buf.str().empty() || mergeNextToken)
125*35238bceSAndroid Build Coastguard Worker                 buf << token.str();
126*35238bceSAndroid Build Coastguard Worker             else
127*35238bceSAndroid Build Coastguard Worker                 buf << '_' << token.str();
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker             // Single char causes next char to be merged (don't split initialisms or acronyms) unless it is 'D' after a number (split to ..._2d_acronym_aa
130*35238bceSAndroid Build Coastguard Worker             mergeNextToken = false;
131*35238bceSAndroid Build Coastguard Worker             if (token.tellp() == (std::streamoff)1)
132*35238bceSAndroid Build Coastguard Worker             {
133*35238bceSAndroid Build Coastguard Worker                 if (!previousTokenWasDigit || token.str()[0] != 'd')
134*35238bceSAndroid Build Coastguard Worker                     mergeNextToken = true;
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker                 previousTokenWasDigit = de::isDigit(token.str()[0]);
137*35238bceSAndroid Build Coastguard Worker             }
138*35238bceSAndroid Build Coastguard Worker             else
139*35238bceSAndroid Build Coastguard Worker                 previousTokenWasDigit = false;
140*35238bceSAndroid Build Coastguard Worker         }
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker         return buf.str();
143*35238bceSAndroid Build Coastguard Worker     }
144*35238bceSAndroid Build Coastguard Worker }
145*35238bceSAndroid Build Coastguard Worker 
getProgramInterfaceGLEnum(ProgramInterface interface)146*35238bceSAndroid Build Coastguard Worker static glw::GLenum getProgramInterfaceGLEnum(ProgramInterface interface)
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker     static const glw::GLenum s_enums[] = {
149*35238bceSAndroid Build Coastguard Worker         GL_UNIFORM,                    // PROGRAMINTERFACE_UNIFORM
150*35238bceSAndroid Build Coastguard Worker         GL_UNIFORM_BLOCK,              // PROGRAMINTERFACE_UNIFORM_BLOCK
151*35238bceSAndroid Build Coastguard Worker         GL_ATOMIC_COUNTER_BUFFER,      // PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER
152*35238bceSAndroid Build Coastguard Worker         GL_PROGRAM_INPUT,              // PROGRAMINTERFACE_PROGRAM_INPUT
153*35238bceSAndroid Build Coastguard Worker         GL_PROGRAM_OUTPUT,             // PROGRAMINTERFACE_PROGRAM_OUTPUT
154*35238bceSAndroid Build Coastguard Worker         GL_TRANSFORM_FEEDBACK_VARYING, // PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING
155*35238bceSAndroid Build Coastguard Worker         GL_BUFFER_VARIABLE,            // PROGRAMINTERFACE_BUFFER_VARIABLE
156*35238bceSAndroid Build Coastguard Worker         GL_SHADER_STORAGE_BLOCK,       // PROGRAMINTERFACE_SHADER_STORAGE_BLOCK
157*35238bceSAndroid Build Coastguard Worker     };
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<PROGRAMINTERFACE_LAST>(s_enums, interface);
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker 
getShaderMaskFirstStage(uint32_t mask)162*35238bceSAndroid Build Coastguard Worker static glu::ShaderType getShaderMaskFirstStage(uint32_t mask)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_COMPUTE))
165*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_COMPUTE;
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_VERTEX))
168*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_VERTEX;
169*35238bceSAndroid Build Coastguard Worker 
170*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
171*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_TESSELLATION_CONTROL;
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
174*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_TESSELLATION_EVALUATION;
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
177*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_GEOMETRY;
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
180*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_FRAGMENT;
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
183*35238bceSAndroid Build Coastguard Worker     return glu::SHADERTYPE_LAST;
184*35238bceSAndroid Build Coastguard Worker }
185*35238bceSAndroid Build Coastguard Worker 
getShaderMaskLastStage(uint32_t mask)186*35238bceSAndroid Build Coastguard Worker static glu::ShaderType getShaderMaskLastStage(uint32_t mask)
187*35238bceSAndroid Build Coastguard Worker {
188*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
189*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_FRAGMENT;
190*35238bceSAndroid Build Coastguard Worker 
191*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
192*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_GEOMETRY;
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
195*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_TESSELLATION_EVALUATION;
196*35238bceSAndroid Build Coastguard Worker 
197*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
198*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_TESSELLATION_CONTROL;
199*35238bceSAndroid Build Coastguard Worker 
200*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_VERTEX))
201*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_VERTEX;
202*35238bceSAndroid Build Coastguard Worker 
203*35238bceSAndroid Build Coastguard Worker     if (mask & (1u << glu::SHADERTYPE_COMPUTE))
204*35238bceSAndroid Build Coastguard Worker         return glu::SHADERTYPE_COMPUTE;
205*35238bceSAndroid Build Coastguard Worker 
206*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
207*35238bceSAndroid Build Coastguard Worker     return glu::SHADERTYPE_LAST;
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker 
checkSupport(Context & ctx)210*35238bceSAndroid Build Coastguard Worker static bool checkSupport(Context &ctx)
211*35238bceSAndroid Build Coastguard Worker {
212*35238bceSAndroid Build Coastguard Worker     auto ctxType = ctx.getRenderContext().getType();
213*35238bceSAndroid Build Coastguard Worker     return contextSupports(ctxType, glu::ApiType::es(3, 2)) || contextSupports(ctxType, glu::ApiType::core(4, 5));
214*35238bceSAndroid Build Coastguard Worker }
215*35238bceSAndroid Build Coastguard Worker 
specializeShader(Context & context,const char * code)216*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(Context &context, const char *code)
217*35238bceSAndroid Build Coastguard Worker {
218*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
219*35238bceSAndroid Build Coastguard Worker     std::map<std::string, std::string> specializationMap;
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker     specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(code).specialize(specializationMap);
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker namespace ResourceDefinition
227*35238bceSAndroid Build Coastguard Worker {
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker class Node
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker public:
232*35238bceSAndroid Build Coastguard Worker     enum NodeType
233*35238bceSAndroid Build Coastguard Worker     {
234*35238bceSAndroid Build Coastguard Worker         TYPE_PROGRAM = 0,
235*35238bceSAndroid Build Coastguard Worker         TYPE_SHADER,
236*35238bceSAndroid Build Coastguard Worker         TYPE_DEFAULT_BLOCK,
237*35238bceSAndroid Build Coastguard Worker         TYPE_VARIABLE,
238*35238bceSAndroid Build Coastguard Worker         TYPE_INTERFACE_BLOCK,
239*35238bceSAndroid Build Coastguard Worker         TYPE_ARRAY_ELEMENT,
240*35238bceSAndroid Build Coastguard Worker         TYPE_STRUCT_MEMBER,
241*35238bceSAndroid Build Coastguard Worker         TYPE_STORAGE_QUALIFIER,
242*35238bceSAndroid Build Coastguard Worker         TYPE_LAYOUT_QUALIFIER,
243*35238bceSAndroid Build Coastguard Worker         TYPE_SHADER_SET,
244*35238bceSAndroid Build Coastguard Worker         TYPE_INTERPOLATION_QUALIFIER,
245*35238bceSAndroid Build Coastguard Worker         TYPE_TRANSFORM_FEEDBACK_TARGET,
246*35238bceSAndroid Build Coastguard Worker 
247*35238bceSAndroid Build Coastguard Worker         TYPE_LAST
248*35238bceSAndroid Build Coastguard Worker     };
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker     typedef de::SharedPtr<const Node> SharedPtr;
251*35238bceSAndroid Build Coastguard Worker 
Node(NodeType type,const SharedPtr & enclosingNode)252*35238bceSAndroid Build Coastguard Worker     Node(NodeType type, const SharedPtr &enclosingNode) : m_type(type), m_enclosingNode(enclosingNode)
253*35238bceSAndroid Build Coastguard Worker     {
254*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(type < TYPE_LAST);
255*35238bceSAndroid Build Coastguard Worker     }
~Node(void)256*35238bceSAndroid Build Coastguard Worker     virtual ~Node(void)
257*35238bceSAndroid Build Coastguard Worker     {
258*35238bceSAndroid Build Coastguard Worker     }
259*35238bceSAndroid Build Coastguard Worker 
getEnclosingNode(void) const260*35238bceSAndroid Build Coastguard Worker     inline const Node *getEnclosingNode(void) const
261*35238bceSAndroid Build Coastguard Worker     {
262*35238bceSAndroid Build Coastguard Worker         return m_enclosingNode.get();
263*35238bceSAndroid Build Coastguard Worker     }
getType(void) const264*35238bceSAndroid Build Coastguard Worker     inline NodeType getType(void) const
265*35238bceSAndroid Build Coastguard Worker     {
266*35238bceSAndroid Build Coastguard Worker         return m_type;
267*35238bceSAndroid Build Coastguard Worker     }
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker private:
270*35238bceSAndroid Build Coastguard Worker     const NodeType m_type;
271*35238bceSAndroid Build Coastguard Worker     const SharedPtr m_enclosingNode;
272*35238bceSAndroid Build Coastguard Worker };
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker class Program : public Node
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker public:
Program(bool separable=false)277*35238bceSAndroid Build Coastguard Worker     Program(bool separable = false) : Node(TYPE_PROGRAM, SharedPtr()), m_separable(separable)
278*35238bceSAndroid Build Coastguard Worker     {
279*35238bceSAndroid Build Coastguard Worker     }
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker     const bool m_separable;
282*35238bceSAndroid Build Coastguard Worker };
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker class Shader : public Node
285*35238bceSAndroid Build Coastguard Worker {
286*35238bceSAndroid Build Coastguard Worker public:
Shader(const SharedPtr & enclosingNode,glu::ShaderType type,glu::GLSLVersion version)287*35238bceSAndroid Build Coastguard Worker     Shader(const SharedPtr &enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
288*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_SHADER, enclosingNode)
289*35238bceSAndroid Build Coastguard Worker         , m_type(type)
290*35238bceSAndroid Build Coastguard Worker         , m_version(version)
291*35238bceSAndroid Build Coastguard Worker     {
292*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
293*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(type < glu::SHADERTYPE_LAST);
294*35238bceSAndroid Build Coastguard Worker     }
295*35238bceSAndroid Build Coastguard Worker 
296*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType m_type;
297*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion m_version;
298*35238bceSAndroid Build Coastguard Worker };
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker class DefaultBlock : public Node
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker public:
DefaultBlock(const SharedPtr & enclosing)303*35238bceSAndroid Build Coastguard Worker     DefaultBlock(const SharedPtr &enclosing) : Node(TYPE_DEFAULT_BLOCK, enclosing)
304*35238bceSAndroid Build Coastguard Worker     {
305*35238bceSAndroid Build Coastguard Worker         // enclosed by the shader
306*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_SHADER || enclosing->getType() == TYPE_SHADER_SET);
307*35238bceSAndroid Build Coastguard Worker     }
308*35238bceSAndroid Build Coastguard Worker };
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker class StorageQualifier : public Node
311*35238bceSAndroid Build Coastguard Worker {
312*35238bceSAndroid Build Coastguard Worker public:
StorageQualifier(const SharedPtr & enclosing,glu::Storage storage)313*35238bceSAndroid Build Coastguard Worker     StorageQualifier(const SharedPtr &enclosing, glu::Storage storage)
314*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_STORAGE_QUALIFIER, enclosing)
315*35238bceSAndroid Build Coastguard Worker         , m_storage(storage)
316*35238bceSAndroid Build Coastguard Worker     {
317*35238bceSAndroid Build Coastguard Worker         // not a part of any block
318*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
319*35238bceSAndroid Build Coastguard Worker     }
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker     const glu::Storage m_storage;
322*35238bceSAndroid Build Coastguard Worker };
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker class Variable : public Node
325*35238bceSAndroid Build Coastguard Worker {
326*35238bceSAndroid Build Coastguard Worker public:
Variable(const SharedPtr & enclosing,glu::DataType dataType)327*35238bceSAndroid Build Coastguard Worker     Variable(const SharedPtr &enclosing, glu::DataType dataType) : Node(TYPE_VARIABLE, enclosing), m_dataType(dataType)
328*35238bceSAndroid Build Coastguard Worker     {
329*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER || enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
330*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
331*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERFACE_BLOCK || enclosing->getType() == TYPE_ARRAY_ELEMENT ||
332*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_STRUCT_MEMBER || enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
333*35238bceSAndroid Build Coastguard Worker     }
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker     const glu::DataType m_dataType;
336*35238bceSAndroid Build Coastguard Worker };
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker class InterfaceBlock : public Node
339*35238bceSAndroid Build Coastguard Worker {
340*35238bceSAndroid Build Coastguard Worker public:
InterfaceBlock(const SharedPtr & enclosing,bool named)341*35238bceSAndroid Build Coastguard Worker     InterfaceBlock(const SharedPtr &enclosing, bool named) : Node(TYPE_INTERFACE_BLOCK, enclosing), m_named(named)
342*35238bceSAndroid Build Coastguard Worker     {
343*35238bceSAndroid Build Coastguard Worker         // Must be storage qualified
344*35238bceSAndroid Build Coastguard Worker         const Node *storageNode = enclosing.get();
345*35238bceSAndroid Build Coastguard Worker         while (storageNode->getType() == TYPE_ARRAY_ELEMENT || storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
346*35238bceSAndroid Build Coastguard Worker         {
347*35238bceSAndroid Build Coastguard Worker             storageNode = storageNode->getEnclosingNode();
348*35238bceSAndroid Build Coastguard Worker         }
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
351*35238bceSAndroid Build Coastguard Worker         DE_UNREF(storageNode);
352*35238bceSAndroid Build Coastguard Worker     }
353*35238bceSAndroid Build Coastguard Worker 
354*35238bceSAndroid Build Coastguard Worker     const bool m_named;
355*35238bceSAndroid Build Coastguard Worker };
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker class ArrayElement : public Node
358*35238bceSAndroid Build Coastguard Worker {
359*35238bceSAndroid Build Coastguard Worker public:
ArrayElement(const SharedPtr & enclosing,int arraySize=DEFAULT_SIZE)360*35238bceSAndroid Build Coastguard Worker     ArrayElement(const SharedPtr &enclosing, int arraySize = DEFAULT_SIZE)
361*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_ARRAY_ELEMENT, enclosing)
362*35238bceSAndroid Build Coastguard Worker         , m_arraySize(arraySize)
363*35238bceSAndroid Build Coastguard Worker     {
364*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER || enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
365*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
366*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERFACE_BLOCK || enclosing->getType() == TYPE_ARRAY_ELEMENT ||
367*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_STRUCT_MEMBER || enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
368*35238bceSAndroid Build Coastguard Worker     }
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker     const int m_arraySize;
371*35238bceSAndroid Build Coastguard Worker 
372*35238bceSAndroid Build Coastguard Worker     enum
373*35238bceSAndroid Build Coastguard Worker     {
374*35238bceSAndroid Build Coastguard Worker         DEFAULT_SIZE  = -1,
375*35238bceSAndroid Build Coastguard Worker         UNSIZED_ARRAY = -2,
376*35238bceSAndroid Build Coastguard Worker     };
377*35238bceSAndroid Build Coastguard Worker };
378*35238bceSAndroid Build Coastguard Worker 
379*35238bceSAndroid Build Coastguard Worker class StructMember : public Node
380*35238bceSAndroid Build Coastguard Worker {
381*35238bceSAndroid Build Coastguard Worker public:
StructMember(const SharedPtr & enclosing)382*35238bceSAndroid Build Coastguard Worker     StructMember(const SharedPtr &enclosing) : Node(TYPE_STRUCT_MEMBER, enclosing)
383*35238bceSAndroid Build Coastguard Worker     {
384*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER || enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
385*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
386*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERFACE_BLOCK || enclosing->getType() == TYPE_ARRAY_ELEMENT ||
387*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_STRUCT_MEMBER || enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
388*35238bceSAndroid Build Coastguard Worker     }
389*35238bceSAndroid Build Coastguard Worker };
390*35238bceSAndroid Build Coastguard Worker 
391*35238bceSAndroid Build Coastguard Worker class LayoutQualifier : public Node
392*35238bceSAndroid Build Coastguard Worker {
393*35238bceSAndroid Build Coastguard Worker public:
LayoutQualifier(const SharedPtr & enclosing,const glu::Layout & layout)394*35238bceSAndroid Build Coastguard Worker     LayoutQualifier(const SharedPtr &enclosing, const glu::Layout &layout)
395*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_LAYOUT_QUALIFIER, enclosing)
396*35238bceSAndroid Build Coastguard Worker         , m_layout(layout)
397*35238bceSAndroid Build Coastguard Worker     {
398*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER || enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
399*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER || enclosing->getType() == TYPE_DEFAULT_BLOCK ||
400*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERFACE_BLOCK);
401*35238bceSAndroid Build Coastguard Worker     }
402*35238bceSAndroid Build Coastguard Worker 
403*35238bceSAndroid Build Coastguard Worker     const glu::Layout m_layout;
404*35238bceSAndroid Build Coastguard Worker };
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker class InterpolationQualifier : public Node
407*35238bceSAndroid Build Coastguard Worker {
408*35238bceSAndroid Build Coastguard Worker public:
InterpolationQualifier(const SharedPtr & enclosing,const glu::Interpolation & interpolation)409*35238bceSAndroid Build Coastguard Worker     InterpolationQualifier(const SharedPtr &enclosing, const glu::Interpolation &interpolation)
410*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_INTERPOLATION_QUALIFIER, enclosing)
411*35238bceSAndroid Build Coastguard Worker         , m_interpolation(interpolation)
412*35238bceSAndroid Build Coastguard Worker     {
413*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER || enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
414*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER || enclosing->getType() == TYPE_DEFAULT_BLOCK ||
415*35238bceSAndroid Build Coastguard Worker                   enclosing->getType() == TYPE_INTERFACE_BLOCK);
416*35238bceSAndroid Build Coastguard Worker     }
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker     const glu::Interpolation m_interpolation;
419*35238bceSAndroid Build Coastguard Worker };
420*35238bceSAndroid Build Coastguard Worker 
421*35238bceSAndroid Build Coastguard Worker class ShaderSet : public Node
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker public:
424*35238bceSAndroid Build Coastguard Worker     ShaderSet(const SharedPtr &enclosing, glu::GLSLVersion version);
425*35238bceSAndroid Build Coastguard Worker     ShaderSet(const SharedPtr &enclosing, glu::GLSLVersion version, uint32_t stagesPresentBits,
426*35238bceSAndroid Build Coastguard Worker               uint32_t stagesReferencingBits);
427*35238bceSAndroid Build Coastguard Worker 
428*35238bceSAndroid Build Coastguard Worker     void setStage(glu::ShaderType type, bool referencing);
429*35238bceSAndroid Build Coastguard Worker     bool isStagePresent(glu::ShaderType stage) const;
430*35238bceSAndroid Build Coastguard Worker     bool isStageReferencing(glu::ShaderType stage) const;
431*35238bceSAndroid Build Coastguard Worker 
432*35238bceSAndroid Build Coastguard Worker     uint32_t getReferencingMask(void) const;
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion m_version;
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker private:
437*35238bceSAndroid Build Coastguard Worker     bool m_stagePresent[glu::SHADERTYPE_LAST];
438*35238bceSAndroid Build Coastguard Worker     bool m_stageReferencing[glu::SHADERTYPE_LAST];
439*35238bceSAndroid Build Coastguard Worker };
440*35238bceSAndroid Build Coastguard Worker 
ShaderSet(const SharedPtr & enclosing,glu::GLSLVersion version)441*35238bceSAndroid Build Coastguard Worker ShaderSet::ShaderSet(const SharedPtr &enclosing, glu::GLSLVersion version)
442*35238bceSAndroid Build Coastguard Worker     : Node(TYPE_SHADER_SET, enclosing)
443*35238bceSAndroid Build Coastguard Worker     , m_version(version)
444*35238bceSAndroid Build Coastguard Worker {
445*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
446*35238bceSAndroid Build Coastguard Worker 
447*35238bceSAndroid Build Coastguard Worker     deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
448*35238bceSAndroid Build Coastguard Worker     deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
449*35238bceSAndroid Build Coastguard Worker }
450*35238bceSAndroid Build Coastguard Worker 
ShaderSet(const SharedPtr & enclosing,glu::GLSLVersion version,uint32_t stagesPresentBits,uint32_t stagesReferencingBits)451*35238bceSAndroid Build Coastguard Worker ShaderSet::ShaderSet(const SharedPtr &enclosing, glu::GLSLVersion version, uint32_t stagesPresentBits,
452*35238bceSAndroid Build Coastguard Worker                      uint32_t stagesReferencingBits)
453*35238bceSAndroid Build Coastguard Worker     : Node(TYPE_SHADER_SET, enclosing)
454*35238bceSAndroid Build Coastguard Worker     , m_version(version)
455*35238bceSAndroid Build Coastguard Worker {
456*35238bceSAndroid Build Coastguard Worker     for (uint32_t stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
457*35238bceSAndroid Build Coastguard Worker     {
458*35238bceSAndroid Build Coastguard Worker         const uint32_t stageMask    = (1u << stageNdx);
459*35238bceSAndroid Build Coastguard Worker         const bool stagePresent     = (stagesPresentBits & stageMask) != 0;
460*35238bceSAndroid Build Coastguard Worker         const bool stageReferencing = (stagesReferencingBits & stageMask) != 0;
461*35238bceSAndroid Build Coastguard Worker 
462*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(stagePresent || !stageReferencing);
463*35238bceSAndroid Build Coastguard Worker 
464*35238bceSAndroid Build Coastguard Worker         m_stagePresent[stageNdx]     = stagePresent;
465*35238bceSAndroid Build Coastguard Worker         m_stageReferencing[stageNdx] = stageReferencing;
466*35238bceSAndroid Build Coastguard Worker     }
467*35238bceSAndroid Build Coastguard Worker }
468*35238bceSAndroid Build Coastguard Worker 
setStage(glu::ShaderType type,bool referencing)469*35238bceSAndroid Build Coastguard Worker void ShaderSet::setStage(glu::ShaderType type, bool referencing)
470*35238bceSAndroid Build Coastguard Worker {
471*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(type < glu::SHADERTYPE_LAST);
472*35238bceSAndroid Build Coastguard Worker     m_stagePresent[type]     = true;
473*35238bceSAndroid Build Coastguard Worker     m_stageReferencing[type] = referencing;
474*35238bceSAndroid Build Coastguard Worker }
475*35238bceSAndroid Build Coastguard Worker 
isStagePresent(glu::ShaderType stage) const476*35238bceSAndroid Build Coastguard Worker bool ShaderSet::isStagePresent(glu::ShaderType stage) const
477*35238bceSAndroid Build Coastguard Worker {
478*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(stage < glu::SHADERTYPE_LAST);
479*35238bceSAndroid Build Coastguard Worker     return m_stagePresent[stage];
480*35238bceSAndroid Build Coastguard Worker }
481*35238bceSAndroid Build Coastguard Worker 
isStageReferencing(glu::ShaderType stage) const482*35238bceSAndroid Build Coastguard Worker bool ShaderSet::isStageReferencing(glu::ShaderType stage) const
483*35238bceSAndroid Build Coastguard Worker {
484*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(stage < glu::SHADERTYPE_LAST);
485*35238bceSAndroid Build Coastguard Worker     return m_stageReferencing[stage];
486*35238bceSAndroid Build Coastguard Worker }
487*35238bceSAndroid Build Coastguard Worker 
getReferencingMask(void) const488*35238bceSAndroid Build Coastguard Worker uint32_t ShaderSet::getReferencingMask(void) const
489*35238bceSAndroid Build Coastguard Worker {
490*35238bceSAndroid Build Coastguard Worker     uint32_t mask = 0;
491*35238bceSAndroid Build Coastguard Worker     for (uint32_t stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
492*35238bceSAndroid Build Coastguard Worker     {
493*35238bceSAndroid Build Coastguard Worker         if (m_stageReferencing[stage])
494*35238bceSAndroid Build Coastguard Worker             mask |= (1u << stage);
495*35238bceSAndroid Build Coastguard Worker     }
496*35238bceSAndroid Build Coastguard Worker     return mask;
497*35238bceSAndroid Build Coastguard Worker }
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker class TransformFeedbackTarget : public Node
500*35238bceSAndroid Build Coastguard Worker {
501*35238bceSAndroid Build Coastguard Worker public:
TransformFeedbackTarget(const SharedPtr & enclosing,const char * builtinVarName=DE_NULL)502*35238bceSAndroid Build Coastguard Worker     TransformFeedbackTarget(const SharedPtr &enclosing, const char *builtinVarName = DE_NULL)
503*35238bceSAndroid Build Coastguard Worker         : Node(TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
504*35238bceSAndroid Build Coastguard Worker         , m_builtinVarName(builtinVarName)
505*35238bceSAndroid Build Coastguard Worker     {
506*35238bceSAndroid Build Coastguard Worker     }
507*35238bceSAndroid Build Coastguard Worker 
508*35238bceSAndroid Build Coastguard Worker     const char *const m_builtinVarName;
509*35238bceSAndroid Build Coastguard Worker };
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker } // namespace ResourceDefinition
512*35238bceSAndroid Build Coastguard Worker 
getDataTypeDefaultPrecision(const glu::DataType & type)513*35238bceSAndroid Build Coastguard Worker static glu::Precision getDataTypeDefaultPrecision(const glu::DataType &type)
514*35238bceSAndroid Build Coastguard Worker {
515*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeBoolOrBVec(type))
516*35238bceSAndroid Build Coastguard Worker         return glu::PRECISION_LAST;
517*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
518*35238bceSAndroid Build Coastguard Worker         return glu::PRECISION_HIGHP;
519*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeSampler(type))
520*35238bceSAndroid Build Coastguard Worker         return glu::PRECISION_HIGHP;
521*35238bceSAndroid Build Coastguard Worker     else if (glu::isDataTypeImage(type))
522*35238bceSAndroid Build Coastguard Worker         return glu::PRECISION_HIGHP;
523*35238bceSAndroid Build Coastguard Worker     else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
524*35238bceSAndroid Build Coastguard Worker         return glu::PRECISION_HIGHP;
525*35238bceSAndroid Build Coastguard Worker 
526*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
527*35238bceSAndroid Build Coastguard Worker     return glu::PRECISION_LAST;
528*35238bceSAndroid Build Coastguard Worker }
529*35238bceSAndroid Build Coastguard Worker 
generateProgramDefinitionFromResource(const ResourceDefinition::Node * resource)530*35238bceSAndroid Build Coastguard Worker static de::MovePtr<ProgramInterfaceDefinition::Program> generateProgramDefinitionFromResource(
531*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node *resource)
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker     de::MovePtr<ProgramInterfaceDefinition::Program> program(new ProgramInterfaceDefinition::Program());
534*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node *head = resource;
535*35238bceSAndroid Build Coastguard Worker 
536*35238bceSAndroid Build Coastguard Worker     if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
537*35238bceSAndroid Build Coastguard Worker     {
538*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable *>(resource));
539*35238bceSAndroid Build Coastguard Worker 
540*35238bceSAndroid Build Coastguard Worker         enum BindingType
541*35238bceSAndroid Build Coastguard Worker         {
542*35238bceSAndroid Build Coastguard Worker             BINDING_VARIABLE,
543*35238bceSAndroid Build Coastguard Worker             BINDING_INTERFACE_BLOCK,
544*35238bceSAndroid Build Coastguard Worker             BINDING_DEFAULT_BLOCK
545*35238bceSAndroid Build Coastguard Worker         };
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker         int structNdx                 = 0;
548*35238bceSAndroid Build Coastguard Worker         int autoAssignArraySize       = 0;
549*35238bceSAndroid Build Coastguard Worker         const glu::DataType basicType = static_cast<const ResourceDefinition::Variable *>(resource)->m_dataType;
550*35238bceSAndroid Build Coastguard Worker         BindingType boundObject       = BINDING_VARIABLE;
551*35238bceSAndroid Build Coastguard Worker         glu::VariableDeclaration variable(glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
552*35238bceSAndroid Build Coastguard Worker         glu::InterfaceBlock interfaceBlock;
553*35238bceSAndroid Build Coastguard Worker         ProgramInterfaceDefinition::DefaultBlock defaultBlock;
554*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> feedbackTargetVaryingPath;
555*35238bceSAndroid Build Coastguard Worker         bool feedbackTargetSet = false;
556*35238bceSAndroid Build Coastguard Worker 
557*35238bceSAndroid Build Coastguard Worker         // image specific
558*35238bceSAndroid Build Coastguard Worker         if (glu::isDataTypeImage(basicType))
559*35238bceSAndroid Build Coastguard Worker         {
560*35238bceSAndroid Build Coastguard Worker             variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
561*35238bceSAndroid Build Coastguard Worker             variable.layout.binding = 1;
562*35238bceSAndroid Build Coastguard Worker 
563*35238bceSAndroid Build Coastguard Worker             if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
564*35238bceSAndroid Build Coastguard Worker                 variable.layout.format = glu::FORMATLAYOUT_RGBA8;
565*35238bceSAndroid Build Coastguard Worker             else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
566*35238bceSAndroid Build Coastguard Worker                 variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
567*35238bceSAndroid Build Coastguard Worker             else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
568*35238bceSAndroid Build Coastguard Worker                 variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
569*35238bceSAndroid Build Coastguard Worker             else
570*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
571*35238bceSAndroid Build Coastguard Worker         }
572*35238bceSAndroid Build Coastguard Worker 
573*35238bceSAndroid Build Coastguard Worker         // atomic counter specific
574*35238bceSAndroid Build Coastguard Worker         if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
575*35238bceSAndroid Build Coastguard Worker             variable.layout.binding = 1;
576*35238bceSAndroid Build Coastguard Worker 
577*35238bceSAndroid Build Coastguard Worker         for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
578*35238bceSAndroid Build Coastguard Worker         {
579*35238bceSAndroid Build Coastguard Worker             if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
580*35238bceSAndroid Build Coastguard Worker             {
581*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::StorageQualifier *qualifier =
582*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::StorageQualifier *>(head);
583*35238bceSAndroid Build Coastguard Worker 
584*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier *>(head));
585*35238bceSAndroid Build Coastguard Worker 
586*35238bceSAndroid Build Coastguard Worker                 if (boundObject == BINDING_VARIABLE)
587*35238bceSAndroid Build Coastguard Worker                 {
588*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(variable.storage == glu::STORAGE_LAST);
589*35238bceSAndroid Build Coastguard Worker                     variable.storage = qualifier->m_storage;
590*35238bceSAndroid Build Coastguard Worker                 }
591*35238bceSAndroid Build Coastguard Worker                 else if (boundObject == BINDING_INTERFACE_BLOCK)
592*35238bceSAndroid Build Coastguard Worker                 {
593*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
594*35238bceSAndroid Build Coastguard Worker                     interfaceBlock.storage = qualifier->m_storage;
595*35238bceSAndroid Build Coastguard Worker                 }
596*35238bceSAndroid Build Coastguard Worker                 else
597*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
598*35238bceSAndroid Build Coastguard Worker             }
599*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
600*35238bceSAndroid Build Coastguard Worker             {
601*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::LayoutQualifier *qualifier =
602*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::LayoutQualifier *>(head);
603*35238bceSAndroid Build Coastguard Worker                 glu::Layout *targetLayout = DE_NULL;
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier *>(head));
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker                 if (boundObject == BINDING_VARIABLE)
608*35238bceSAndroid Build Coastguard Worker                     targetLayout = &variable.layout;
609*35238bceSAndroid Build Coastguard Worker                 else if (boundObject == BINDING_INTERFACE_BLOCK)
610*35238bceSAndroid Build Coastguard Worker                     targetLayout = &interfaceBlock.layout;
611*35238bceSAndroid Build Coastguard Worker                 else
612*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
613*35238bceSAndroid Build Coastguard Worker 
614*35238bceSAndroid Build Coastguard Worker                 if (qualifier->m_layout.location != -1)
615*35238bceSAndroid Build Coastguard Worker                     targetLayout->location = qualifier->m_layout.location;
616*35238bceSAndroid Build Coastguard Worker 
617*35238bceSAndroid Build Coastguard Worker                 if (qualifier->m_layout.binding != -1)
618*35238bceSAndroid Build Coastguard Worker                     targetLayout->binding = qualifier->m_layout.binding;
619*35238bceSAndroid Build Coastguard Worker 
620*35238bceSAndroid Build Coastguard Worker                 if (qualifier->m_layout.offset != -1)
621*35238bceSAndroid Build Coastguard Worker                     targetLayout->offset = qualifier->m_layout.offset;
622*35238bceSAndroid Build Coastguard Worker 
623*35238bceSAndroid Build Coastguard Worker                 if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
624*35238bceSAndroid Build Coastguard Worker                     targetLayout->format = qualifier->m_layout.format;
625*35238bceSAndroid Build Coastguard Worker 
626*35238bceSAndroid Build Coastguard Worker                 if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
627*35238bceSAndroid Build Coastguard Worker                     targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
628*35238bceSAndroid Build Coastguard Worker             }
629*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
630*35238bceSAndroid Build Coastguard Worker             {
631*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::InterpolationQualifier *qualifier =
632*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::InterpolationQualifier *>(head);
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier *>(head));
635*35238bceSAndroid Build Coastguard Worker 
636*35238bceSAndroid Build Coastguard Worker                 if (boundObject == BINDING_VARIABLE)
637*35238bceSAndroid Build Coastguard Worker                     variable.interpolation = qualifier->m_interpolation;
638*35238bceSAndroid Build Coastguard Worker                 else
639*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
640*35238bceSAndroid Build Coastguard Worker             }
641*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
642*35238bceSAndroid Build Coastguard Worker             {
643*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement *>(head));
644*35238bceSAndroid Build Coastguard Worker 
645*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::ArrayElement *arrayElement =
646*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::ArrayElement *>(head);
647*35238bceSAndroid Build Coastguard Worker                 int arraySize;
648*35238bceSAndroid Build Coastguard Worker 
649*35238bceSAndroid Build Coastguard Worker                 // Vary array size per level
650*35238bceSAndroid Build Coastguard Worker                 if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
651*35238bceSAndroid Build Coastguard Worker                 {
652*35238bceSAndroid Build Coastguard Worker                     if (--autoAssignArraySize <= 1)
653*35238bceSAndroid Build Coastguard Worker                         autoAssignArraySize = 3;
654*35238bceSAndroid Build Coastguard Worker 
655*35238bceSAndroid Build Coastguard Worker                     arraySize = autoAssignArraySize;
656*35238bceSAndroid Build Coastguard Worker                 }
657*35238bceSAndroid Build Coastguard Worker                 else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
658*35238bceSAndroid Build Coastguard Worker                     arraySize = glu::VarType::UNSIZED_ARRAY;
659*35238bceSAndroid Build Coastguard Worker                 else
660*35238bceSAndroid Build Coastguard Worker                     arraySize = arrayElement->m_arraySize;
661*35238bceSAndroid Build Coastguard Worker 
662*35238bceSAndroid Build Coastguard Worker                 if (boundObject == BINDING_VARIABLE)
663*35238bceSAndroid Build Coastguard Worker                     variable.varType = glu::VarType(variable.varType, arraySize);
664*35238bceSAndroid Build Coastguard Worker                 else if (boundObject == BINDING_INTERFACE_BLOCK)
665*35238bceSAndroid Build Coastguard Worker                     interfaceBlock.dimensions.push_back(arraySize);
666*35238bceSAndroid Build Coastguard Worker                 else
667*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
668*35238bceSAndroid Build Coastguard Worker 
669*35238bceSAndroid Build Coastguard Worker                 if (feedbackTargetSet)
670*35238bceSAndroid Build Coastguard Worker                     feedbackTargetVaryingPath.back().append("[0]");
671*35238bceSAndroid Build Coastguard Worker             }
672*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
673*35238bceSAndroid Build Coastguard Worker             {
674*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember *>(head));
675*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(boundObject == BINDING_VARIABLE);
676*35238bceSAndroid Build Coastguard Worker 
677*35238bceSAndroid Build Coastguard Worker                 // Struct members cannot contain any qualifiers except precision
678*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
679*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(variable.layout == glu::Layout());
680*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(variable.memoryAccessQualifierBits == 0);
681*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
682*35238bceSAndroid Build Coastguard Worker 
683*35238bceSAndroid Build Coastguard Worker                 {
684*35238bceSAndroid Build Coastguard Worker                     glu::StructType *structPtr =
685*35238bceSAndroid Build Coastguard Worker                         new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
686*35238bceSAndroid Build Coastguard Worker                     structPtr->addMember(variable.name.c_str(), variable.varType);
687*35238bceSAndroid Build Coastguard Worker 
688*35238bceSAndroid Build Coastguard Worker                     variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
689*35238bceSAndroid Build Coastguard Worker                 }
690*35238bceSAndroid Build Coastguard Worker 
691*35238bceSAndroid Build Coastguard Worker                 if (feedbackTargetSet)
692*35238bceSAndroid Build Coastguard Worker                     feedbackTargetVaryingPath.push_back("target");
693*35238bceSAndroid Build Coastguard Worker             }
694*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
695*35238bceSAndroid Build Coastguard Worker             {
696*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock *>(head));
697*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(boundObject == BINDING_VARIABLE);
698*35238bceSAndroid Build Coastguard Worker 
699*35238bceSAndroid Build Coastguard Worker                 const bool named = static_cast<const ResourceDefinition::InterfaceBlock *>(head)->m_named;
700*35238bceSAndroid Build Coastguard Worker 
701*35238bceSAndroid Build Coastguard Worker                 boundObject = BINDING_INTERFACE_BLOCK;
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker                 interfaceBlock.interfaceName = "TargetInterface";
704*35238bceSAndroid Build Coastguard Worker                 interfaceBlock.instanceName  = (named) ? ("targetInstance") : ("");
705*35238bceSAndroid Build Coastguard Worker                 interfaceBlock.variables.push_back(variable);
706*35238bceSAndroid Build Coastguard Worker 
707*35238bceSAndroid Build Coastguard Worker                 if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
708*35238bceSAndroid Build Coastguard Worker                     feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
709*35238bceSAndroid Build Coastguard Worker             }
710*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
711*35238bceSAndroid Build Coastguard Worker             {
712*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock *>(head));
713*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
714*35238bceSAndroid Build Coastguard Worker 
715*35238bceSAndroid Build Coastguard Worker                 if (boundObject == BINDING_VARIABLE)
716*35238bceSAndroid Build Coastguard Worker                     defaultBlock.variables.push_back(variable);
717*35238bceSAndroid Build Coastguard Worker                 else if (boundObject == BINDING_INTERFACE_BLOCK)
718*35238bceSAndroid Build Coastguard Worker                     defaultBlock.interfaceBlocks.push_back(interfaceBlock);
719*35238bceSAndroid Build Coastguard Worker                 else
720*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
721*35238bceSAndroid Build Coastguard Worker 
722*35238bceSAndroid Build Coastguard Worker                 boundObject = BINDING_DEFAULT_BLOCK;
723*35238bceSAndroid Build Coastguard Worker             }
724*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
725*35238bceSAndroid Build Coastguard Worker             {
726*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader *>(head));
727*35238bceSAndroid Build Coastguard Worker 
728*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Shader *shaderDef = static_cast<const ResourceDefinition::Shader *>(head);
729*35238bceSAndroid Build Coastguard Worker                 ProgramInterfaceDefinition::Shader *shader =
730*35238bceSAndroid Build Coastguard Worker                     program->addShader(shaderDef->m_type, shaderDef->m_version);
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker                 shader->getDefaultBlock() = defaultBlock;
733*35238bceSAndroid Build Coastguard Worker             }
734*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
735*35238bceSAndroid Build Coastguard Worker             {
736*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet *>(head));
737*35238bceSAndroid Build Coastguard Worker 
738*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::ShaderSet *shaderDef =
739*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::ShaderSet *>(head);
740*35238bceSAndroid Build Coastguard Worker 
741*35238bceSAndroid Build Coastguard Worker                 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
742*35238bceSAndroid Build Coastguard Worker                 {
743*35238bceSAndroid Build Coastguard Worker                     if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
744*35238bceSAndroid Build Coastguard Worker                     {
745*35238bceSAndroid Build Coastguard Worker                         ProgramInterfaceDefinition::Shader *shader =
746*35238bceSAndroid Build Coastguard Worker                             program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
747*35238bceSAndroid Build Coastguard Worker 
748*35238bceSAndroid Build Coastguard Worker                         if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
749*35238bceSAndroid Build Coastguard Worker                             shader->getDefaultBlock() = defaultBlock;
750*35238bceSAndroid Build Coastguard Worker                     }
751*35238bceSAndroid Build Coastguard Worker                 }
752*35238bceSAndroid Build Coastguard Worker             }
753*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
754*35238bceSAndroid Build Coastguard Worker             {
755*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program *>(head));
756*35238bceSAndroid Build Coastguard Worker 
757*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Program *programDef = static_cast<const ResourceDefinition::Program *>(head);
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker                 program->setSeparable(programDef->m_separable);
760*35238bceSAndroid Build Coastguard Worker 
761*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
762*35238bceSAndroid Build Coastguard Worker                 if (!feedbackTargetVaryingPath.empty())
763*35238bceSAndroid Build Coastguard Worker                 {
764*35238bceSAndroid Build Coastguard Worker                     std::ostringstream buf;
765*35238bceSAndroid Build Coastguard Worker 
766*35238bceSAndroid Build Coastguard Worker                     for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin();
767*35238bceSAndroid Build Coastguard Worker                          it != feedbackTargetVaryingPath.rend(); ++it)
768*35238bceSAndroid Build Coastguard Worker                     {
769*35238bceSAndroid Build Coastguard Worker                         if (it != feedbackTargetVaryingPath.rbegin())
770*35238bceSAndroid Build Coastguard Worker                             buf << ".";
771*35238bceSAndroid Build Coastguard Worker                         buf << *it;
772*35238bceSAndroid Build Coastguard Worker                     }
773*35238bceSAndroid Build Coastguard Worker 
774*35238bceSAndroid Build Coastguard Worker                     program->addTransformFeedbackVarying(buf.str());
775*35238bceSAndroid Build Coastguard Worker                     program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
776*35238bceSAndroid Build Coastguard Worker                 }
777*35238bceSAndroid Build Coastguard Worker                 break;
778*35238bceSAndroid Build Coastguard Worker             }
779*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
780*35238bceSAndroid Build Coastguard Worker             {
781*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget *>(head));
782*35238bceSAndroid Build Coastguard Worker 
783*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::TransformFeedbackTarget *feedbackTarget =
784*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::TransformFeedbackTarget *>(head);
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
787*35238bceSAndroid Build Coastguard Worker                 DE_UNREF(feedbackTarget);
788*35238bceSAndroid Build Coastguard Worker 
789*35238bceSAndroid Build Coastguard Worker                 feedbackTargetSet = true;
790*35238bceSAndroid Build Coastguard Worker                 feedbackTargetVaryingPath.push_back(variable.name);
791*35238bceSAndroid Build Coastguard Worker             }
792*35238bceSAndroid Build Coastguard Worker             else
793*35238bceSAndroid Build Coastguard Worker             {
794*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
795*35238bceSAndroid Build Coastguard Worker                 break;
796*35238bceSAndroid Build Coastguard Worker             }
797*35238bceSAndroid Build Coastguard Worker         }
798*35238bceSAndroid Build Coastguard Worker     }
799*35238bceSAndroid Build Coastguard Worker     else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
800*35238bceSAndroid Build Coastguard Worker              head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
801*35238bceSAndroid Build Coastguard Worker     {
802*35238bceSAndroid Build Coastguard Worker         const char *feedbackTargetVaryingName = DE_NULL;
803*35238bceSAndroid Build Coastguard Worker 
804*35238bceSAndroid Build Coastguard Worker         // empty default block
805*35238bceSAndroid Build Coastguard Worker 
806*35238bceSAndroid Build Coastguard Worker         for (; head; head = head->getEnclosingNode())
807*35238bceSAndroid Build Coastguard Worker         {
808*35238bceSAndroid Build Coastguard Worker             if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
809*35238bceSAndroid Build Coastguard Worker             {
810*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader *>(head));
811*35238bceSAndroid Build Coastguard Worker 
812*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Shader *shaderDef = static_cast<const ResourceDefinition::Shader *>(head);
813*35238bceSAndroid Build Coastguard Worker 
814*35238bceSAndroid Build Coastguard Worker                 program->addShader(shaderDef->m_type, shaderDef->m_version);
815*35238bceSAndroid Build Coastguard Worker             }
816*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
817*35238bceSAndroid Build Coastguard Worker             {
818*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet *>(head));
819*35238bceSAndroid Build Coastguard Worker 
820*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::ShaderSet *shaderDef =
821*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::ShaderSet *>(head);
822*35238bceSAndroid Build Coastguard Worker 
823*35238bceSAndroid Build Coastguard Worker                 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
824*35238bceSAndroid Build Coastguard Worker                     if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
825*35238bceSAndroid Build Coastguard Worker                         program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
826*35238bceSAndroid Build Coastguard Worker             }
827*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
828*35238bceSAndroid Build Coastguard Worker             {
829*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program *>(head));
830*35238bceSAndroid Build Coastguard Worker 
831*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Program *programDef = static_cast<const ResourceDefinition::Program *>(head);
832*35238bceSAndroid Build Coastguard Worker 
833*35238bceSAndroid Build Coastguard Worker                 program->setSeparable(programDef->m_separable);
834*35238bceSAndroid Build Coastguard Worker                 if (feedbackTargetVaryingName)
835*35238bceSAndroid Build Coastguard Worker                 {
836*35238bceSAndroid Build Coastguard Worker                     program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
837*35238bceSAndroid Build Coastguard Worker                     program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
838*35238bceSAndroid Build Coastguard Worker                 }
839*35238bceSAndroid Build Coastguard Worker                 break;
840*35238bceSAndroid Build Coastguard Worker             }
841*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
842*35238bceSAndroid Build Coastguard Worker             {
843*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget *>(head));
844*35238bceSAndroid Build Coastguard Worker 
845*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::TransformFeedbackTarget *feedbackTarget =
846*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::TransformFeedbackTarget *>(head);
847*35238bceSAndroid Build Coastguard Worker 
848*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
849*35238bceSAndroid Build Coastguard Worker 
850*35238bceSAndroid Build Coastguard Worker                 feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
851*35238bceSAndroid Build Coastguard Worker             }
852*35238bceSAndroid Build Coastguard Worker             else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
853*35238bceSAndroid Build Coastguard Worker             {
854*35238bceSAndroid Build Coastguard Worker             }
855*35238bceSAndroid Build Coastguard Worker             else
856*35238bceSAndroid Build Coastguard Worker             {
857*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
858*35238bceSAndroid Build Coastguard Worker                 break;
859*35238bceSAndroid Build Coastguard Worker             }
860*35238bceSAndroid Build Coastguard Worker         }
861*35238bceSAndroid Build Coastguard Worker     }
862*35238bceSAndroid Build Coastguard Worker 
863*35238bceSAndroid Build Coastguard Worker     if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
864*35238bceSAndroid Build Coastguard Worker         program->setGeometryNumOutputVertices(1);
865*35238bceSAndroid Build Coastguard Worker     if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
866*35238bceSAndroid Build Coastguard Worker         program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
867*35238bceSAndroid Build Coastguard Worker         program->setTessellationNumOutputPatchVertices(1);
868*35238bceSAndroid Build Coastguard Worker 
869*35238bceSAndroid Build Coastguard Worker     return program;
870*35238bceSAndroid Build Coastguard Worker }
871*35238bceSAndroid Build Coastguard Worker 
checkAndLogProgram(const glu::ShaderProgram & program,const ProgramInterfaceDefinition::Program * programDefinition,const glw::Functions & gl,tcu::TestLog & log)872*35238bceSAndroid Build Coastguard Worker static void checkAndLogProgram(const glu::ShaderProgram &program,
873*35238bceSAndroid Build Coastguard Worker                                const ProgramInterfaceDefinition::Program *programDefinition, const glw::Functions &gl,
874*35238bceSAndroid Build Coastguard Worker                                tcu::TestLog &log)
875*35238bceSAndroid Build Coastguard Worker {
876*35238bceSAndroid Build Coastguard Worker     const tcu::ScopedLogSection section(log, "Program", "Program");
877*35238bceSAndroid Build Coastguard Worker 
878*35238bceSAndroid Build Coastguard Worker     log << program;
879*35238bceSAndroid Build Coastguard Worker     if (!program.isOk())
880*35238bceSAndroid Build Coastguard Worker     {
881*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits"
882*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::EndMessage;
883*35238bceSAndroid Build Coastguard Worker         checkProgramResourceUsage(programDefinition, gl, log);
884*35238bceSAndroid Build Coastguard Worker 
885*35238bceSAndroid Build Coastguard Worker         // within limits
886*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("could not build program");
887*35238bceSAndroid Build Coastguard Worker     }
888*35238bceSAndroid Build Coastguard Worker }
889*35238bceSAndroid Build Coastguard Worker 
890*35238bceSAndroid Build Coastguard Worker // Resource list query case
891*35238bceSAndroid Build Coastguard Worker 
892*35238bceSAndroid Build Coastguard Worker class ResourceListTestCase : public TestCase
893*35238bceSAndroid Build Coastguard Worker {
894*35238bceSAndroid Build Coastguard Worker public:
895*35238bceSAndroid Build Coastguard Worker     ResourceListTestCase(Context &context, const ResourceDefinition::Node::SharedPtr &targetResource,
896*35238bceSAndroid Build Coastguard Worker                          ProgramInterface interface, const char *name = DE_NULL);
897*35238bceSAndroid Build Coastguard Worker     ~ResourceListTestCase(void);
898*35238bceSAndroid Build Coastguard Worker 
899*35238bceSAndroid Build Coastguard Worker protected:
900*35238bceSAndroid Build Coastguard Worker     void init(void);
901*35238bceSAndroid Build Coastguard Worker     void deinit(void);
902*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
903*35238bceSAndroid Build Coastguard Worker 
904*35238bceSAndroid Build Coastguard Worker     void queryResourceList(std::vector<std::string> &dst, glw::GLuint program);
905*35238bceSAndroid Build Coastguard Worker     bool verifyResourceList(const std::vector<std::string> &resourceList,
906*35238bceSAndroid Build Coastguard Worker                             const std::vector<std::string> &expectedResources);
907*35238bceSAndroid Build Coastguard Worker     bool verifyResourceIndexQuery(const std::vector<std::string> &resourceList,
908*35238bceSAndroid Build Coastguard Worker                                   const std::vector<std::string> &referenceResources, glw::GLuint program);
909*35238bceSAndroid Build Coastguard Worker     bool verifyMaxNameLength(const std::vector<std::string> &referenceResourceList, glw::GLuint program);
910*35238bceSAndroid Build Coastguard Worker 
911*35238bceSAndroid Build Coastguard Worker     static std::string genTestCaseName(ProgramInterface interface, const ResourceDefinition::Node *);
912*35238bceSAndroid Build Coastguard Worker     static bool isArrayedInterface(ProgramInterface interface, uint32_t stageBits);
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker     const ProgramInterface m_programInterface;
915*35238bceSAndroid Build Coastguard Worker     ResourceDefinition::Node::SharedPtr m_targetResource;
916*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_programDefinition;
917*35238bceSAndroid Build Coastguard Worker };
918*35238bceSAndroid Build Coastguard Worker 
ResourceListTestCase(Context & context,const ResourceDefinition::Node::SharedPtr & targetResource,ProgramInterface interface,const char * name)919*35238bceSAndroid Build Coastguard Worker ResourceListTestCase::ResourceListTestCase(Context &context, const ResourceDefinition::Node::SharedPtr &targetResource,
920*35238bceSAndroid Build Coastguard Worker                                            ProgramInterface interface, const char *name)
921*35238bceSAndroid Build Coastguard Worker     : TestCase(context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
922*35238bceSAndroid Build Coastguard Worker     , m_programInterface(interface)
923*35238bceSAndroid Build Coastguard Worker     , m_targetResource(targetResource)
924*35238bceSAndroid Build Coastguard Worker     , m_programDefinition(DE_NULL)
925*35238bceSAndroid Build Coastguard Worker {
926*35238bceSAndroid Build Coastguard Worker     // GL_ATOMIC_COUNTER_BUFFER: no resource names
927*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
928*35238bceSAndroid Build Coastguard Worker }
929*35238bceSAndroid Build Coastguard Worker 
~ResourceListTestCase(void)930*35238bceSAndroid Build Coastguard Worker ResourceListTestCase::~ResourceListTestCase(void)
931*35238bceSAndroid Build Coastguard Worker {
932*35238bceSAndroid Build Coastguard Worker     deinit();
933*35238bceSAndroid Build Coastguard Worker }
934*35238bceSAndroid Build Coastguard Worker 
init(void)935*35238bceSAndroid Build Coastguard Worker void ResourceListTestCase::init(void)
936*35238bceSAndroid Build Coastguard Worker {
937*35238bceSAndroid Build Coastguard Worker     m_programDefinition           = generateProgramDefinitionFromResource(m_targetResource.get()).release();
938*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 = checkSupport(m_context);
939*35238bceSAndroid Build Coastguard Worker 
940*35238bceSAndroid Build Coastguard Worker     if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
941*35238bceSAndroid Build Coastguard Worker          m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
942*35238bceSAndroid Build Coastguard Worker         !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
943*35238bceSAndroid Build Coastguard Worker     {
944*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
945*35238bceSAndroid Build Coastguard Worker     }
946*35238bceSAndroid Build Coastguard Worker     if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) && !supportsES32orGL45 &&
947*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
948*35238bceSAndroid Build Coastguard Worker     {
949*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
950*35238bceSAndroid Build Coastguard Worker     }
951*35238bceSAndroid Build Coastguard Worker     if (programContainsIOBlocks(m_programDefinition) && !supportsES32orGL45 &&
952*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
953*35238bceSAndroid Build Coastguard Worker     {
954*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
955*35238bceSAndroid Build Coastguard Worker     }
956*35238bceSAndroid Build Coastguard Worker }
957*35238bceSAndroid Build Coastguard Worker 
deinit(void)958*35238bceSAndroid Build Coastguard Worker void ResourceListTestCase::deinit(void)
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker     m_targetResource.clear();
961*35238bceSAndroid Build Coastguard Worker 
962*35238bceSAndroid Build Coastguard Worker     delete m_programDefinition;
963*35238bceSAndroid Build Coastguard Worker     m_programDefinition = DE_NULL;
964*35238bceSAndroid Build Coastguard Worker }
965*35238bceSAndroid Build Coastguard Worker 
iterate(void)966*35238bceSAndroid Build Coastguard Worker ResourceListTestCase::IterateResult ResourceListTestCase::iterate(void)
967*35238bceSAndroid Build Coastguard Worker {
968*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(),
969*35238bceSAndroid Build Coastguard Worker                                      generateProgramInterfaceProgramSources(m_programDefinition));
970*35238bceSAndroid Build Coastguard Worker 
971*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
972*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
973*35238bceSAndroid Build Coastguard Worker 
974*35238bceSAndroid Build Coastguard Worker     // Check resource list
975*35238bceSAndroid Build Coastguard Worker     {
976*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "ResourceList", "Resource list");
977*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> resourceList;
978*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> expectedResources;
979*35238bceSAndroid Build Coastguard Worker 
980*35238bceSAndroid Build Coastguard Worker         queryResourceList(resourceList, program.getProgram());
981*35238bceSAndroid Build Coastguard Worker         expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
982*35238bceSAndroid Build Coastguard Worker 
983*35238bceSAndroid Build Coastguard Worker         // verify the list and the expected list match
984*35238bceSAndroid Build Coastguard Worker 
985*35238bceSAndroid Build Coastguard Worker         if (!verifyResourceList(resourceList, expectedResources))
986*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker         // verify GetProgramResourceIndex() matches the indices of the list
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker         if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
991*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
992*35238bceSAndroid Build Coastguard Worker 
993*35238bceSAndroid Build Coastguard Worker         // Verify MAX_NAME_LENGTH
994*35238bceSAndroid Build Coastguard Worker         if (!verifyMaxNameLength(resourceList, program.getProgram()))
995*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
996*35238bceSAndroid Build Coastguard Worker     }
997*35238bceSAndroid Build Coastguard Worker 
998*35238bceSAndroid Build Coastguard Worker     return STOP;
999*35238bceSAndroid Build Coastguard Worker }
1000*35238bceSAndroid Build Coastguard Worker 
queryResourceList(std::vector<std::string> & dst,glw::GLuint program)1001*35238bceSAndroid Build Coastguard Worker void ResourceListTestCase::queryResourceList(std::vector<std::string> &dst, glw::GLuint program)
1002*35238bceSAndroid Build Coastguard Worker {
1003*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1004*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1005*35238bceSAndroid Build Coastguard Worker     glw::GLint numActiveResources      = 0;
1006*35238bceSAndroid Build Coastguard Worker     glw::GLint maxNameLength           = 0;
1007*35238bceSAndroid Build Coastguard Worker     std::vector<char> buffer;
1008*35238bceSAndroid Build Coastguard Worker 
1009*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface)
1010*35238bceSAndroid Build Coastguard Worker                        << " interface:" << tcu::TestLog::EndMessage;
1011*35238bceSAndroid Build Coastguard Worker 
1012*35238bceSAndroid Build Coastguard Worker     gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
1013*35238bceSAndroid Build Coastguard Worker     gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1014*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1015*35238bceSAndroid Build Coastguard Worker 
1016*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
1017*35238bceSAndroid Build Coastguard Worker                        << "\tGL_MAX_NAME_LENGTH = " << maxNameLength << tcu::TestLog::EndMessage;
1018*35238bceSAndroid Build Coastguard Worker 
1019*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
1020*35238bceSAndroid Build Coastguard Worker 
1021*35238bceSAndroid Build Coastguard Worker     buffer.resize(maxNameLength + 1, '\0');
1022*35238bceSAndroid Build Coastguard Worker 
1023*35238bceSAndroid Build Coastguard Worker     for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
1024*35238bceSAndroid Build Coastguard Worker     {
1025*35238bceSAndroid Build Coastguard Worker         glw::GLint written = 0;
1026*35238bceSAndroid Build Coastguard Worker 
1027*35238bceSAndroid Build Coastguard Worker         gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1028*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1029*35238bceSAndroid Build Coastguard Worker 
1030*35238bceSAndroid Build Coastguard Worker         dst.push_back(std::string(&buffer[0], written));
1031*35238bceSAndroid Build Coastguard Worker     }
1032*35238bceSAndroid Build Coastguard Worker }
1033*35238bceSAndroid Build Coastguard Worker 
verifyResourceList(const std::vector<std::string> & resourceList,const std::vector<std::string> & expectedResources)1034*35238bceSAndroid Build Coastguard Worker bool ResourceListTestCase::verifyResourceList(const std::vector<std::string> &resourceList,
1035*35238bceSAndroid Build Coastguard Worker                                               const std::vector<std::string> &expectedResources)
1036*35238bceSAndroid Build Coastguard Worker {
1037*35238bceSAndroid Build Coastguard Worker     bool error = false;
1038*35238bceSAndroid Build Coastguard Worker 
1039*35238bceSAndroid Build Coastguard Worker     // Log and compare resource lists
1040*35238bceSAndroid Build Coastguard Worker 
1041*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1042*35238bceSAndroid Build Coastguard Worker 
1043*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1044*35238bceSAndroid Build Coastguard Worker     {
1045*35238bceSAndroid Build Coastguard Worker         // unusedZero is a uniform that may be added by
1046*35238bceSAndroid Build Coastguard Worker         // generateProgramInterfaceProgramSources.  Omit it here to avoid
1047*35238bceSAndroid Build Coastguard Worker         // confusion about the output.
1048*35238bceSAndroid Build Coastguard Worker         if (resourceList[ndx] != getUnusedZeroUniformName())
1049*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx]
1050*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1051*35238bceSAndroid Build Coastguard Worker     }
1052*35238bceSAndroid Build Coastguard Worker 
1053*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1056*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx]
1057*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1058*35238bceSAndroid Build Coastguard Worker 
1059*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1060*35238bceSAndroid Build Coastguard Worker 
1061*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1062*35238bceSAndroid Build Coastguard Worker     {
1063*35238bceSAndroid Build Coastguard Worker         if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1064*35238bceSAndroid Build Coastguard Worker         {
1065*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource "
1066*35238bceSAndroid Build Coastguard Worker                                << expectedResources[ndx] << tcu::TestLog::EndMessage;
1067*35238bceSAndroid Build Coastguard Worker             error = true;
1068*35238bceSAndroid Build Coastguard Worker         }
1069*35238bceSAndroid Build Coastguard Worker     }
1070*35238bceSAndroid Build Coastguard Worker 
1071*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1072*35238bceSAndroid Build Coastguard Worker     {
1073*35238bceSAndroid Build Coastguard Worker         if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1074*35238bceSAndroid Build Coastguard Worker         {
1075*35238bceSAndroid Build Coastguard Worker             // Ignore all builtin variables or the variable unusedZero,
1076*35238bceSAndroid Build Coastguard Worker             // mismatch causes errors otherwise.  unusedZero is a uniform that
1077*35238bceSAndroid Build Coastguard Worker             // may be added by generateProgramInterfaceProgramSources.
1078*35238bceSAndroid Build Coastguard Worker             if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == false &&
1079*35238bceSAndroid Build Coastguard Worker                 resourceList[ndx] != getUnusedZeroUniformName())
1080*35238bceSAndroid Build Coastguard Worker             {
1081*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name "
1082*35238bceSAndroid Build Coastguard Worker                                    << resourceList[ndx] << tcu::TestLog::EndMessage;
1083*35238bceSAndroid Build Coastguard Worker                 error = true;
1084*35238bceSAndroid Build Coastguard Worker             }
1085*35238bceSAndroid Build Coastguard Worker             else
1086*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in "
1087*35238bceSAndroid Build Coastguard Worker                                    << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1088*35238bceSAndroid Build Coastguard Worker         }
1089*35238bceSAndroid Build Coastguard Worker     }
1090*35238bceSAndroid Build Coastguard Worker 
1091*35238bceSAndroid Build Coastguard Worker     return !error;
1092*35238bceSAndroid Build Coastguard Worker }
1093*35238bceSAndroid Build Coastguard Worker 
verifyResourceIndexQuery(const std::vector<std::string> & resourceList,const std::vector<std::string> & referenceResources,glw::GLuint program)1094*35238bceSAndroid Build Coastguard Worker bool ResourceListTestCase::verifyResourceIndexQuery(const std::vector<std::string> &resourceList,
1095*35238bceSAndroid Build Coastguard Worker                                                     const std::vector<std::string> &referenceResources,
1096*35238bceSAndroid Build Coastguard Worker                                                     glw::GLuint program)
1097*35238bceSAndroid Build Coastguard Worker {
1098*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1099*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1100*35238bceSAndroid Build Coastguard Worker     bool error                         = false;
1101*35238bceSAndroid Build Coastguard Worker 
1102*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
1103*35238bceSAndroid Build Coastguard Worker                        << "Verifying GetProgramResourceIndex returns correct indices for resource names."
1104*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1105*35238bceSAndroid Build Coastguard Worker 
1106*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1107*35238bceSAndroid Build Coastguard Worker     {
1108*35238bceSAndroid Build Coastguard Worker         const glw::GLuint index =
1109*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1110*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1111*35238bceSAndroid Build Coastguard Worker 
1112*35238bceSAndroid Build Coastguard Worker         if (index == GL_INVALID_INDEX)
1113*35238bceSAndroid Build Coastguard Worker         {
1114*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx]
1115*35238bceSAndroid Build Coastguard Worker                                << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1116*35238bceSAndroid Build Coastguard Worker             error = true;
1117*35238bceSAndroid Build Coastguard Worker         }
1118*35238bceSAndroid Build Coastguard Worker         else if ((int)index >= (int)resourceList.size())
1119*35238bceSAndroid Build Coastguard Worker         {
1120*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx]
1121*35238bceSAndroid Build Coastguard Worker                                << "\" got index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)."
1122*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1123*35238bceSAndroid Build Coastguard Worker             error = true;
1124*35238bceSAndroid Build Coastguard Worker         }
1125*35238bceSAndroid Build Coastguard Worker         else if (resourceList[index] != referenceResources[ndx])
1126*35238bceSAndroid Build Coastguard Worker         {
1127*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx]
1128*35238bceSAndroid Build Coastguard Worker                                << "\" got index (index = " << index << ") of another resource (" << resourceList[index]
1129*35238bceSAndroid Build Coastguard Worker                                << ")." << tcu::TestLog::EndMessage;
1130*35238bceSAndroid Build Coastguard Worker             error = true;
1131*35238bceSAndroid Build Coastguard Worker         }
1132*35238bceSAndroid Build Coastguard Worker     }
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker     // Query for "name" should match "name[0]" except for XFB
1135*35238bceSAndroid Build Coastguard Worker 
1136*35238bceSAndroid Build Coastguard Worker     if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1137*35238bceSAndroid Build Coastguard Worker     {
1138*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1139*35238bceSAndroid Build Coastguard Worker         {
1140*35238bceSAndroid Build Coastguard Worker             if (de::endsWith(referenceResources[ndx], "[0]"))
1141*35238bceSAndroid Build Coastguard Worker             {
1142*35238bceSAndroid Build Coastguard Worker                 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length() - 3);
1143*35238bceSAndroid Build Coastguard Worker                 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1144*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1145*35238bceSAndroid Build Coastguard Worker 
1146*35238bceSAndroid Build Coastguard Worker                 if (index == GL_INVALID_INDEX)
1147*35238bceSAndroid Build Coastguard Worker                 {
1148*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString
1149*35238bceSAndroid Build Coastguard Worker                                        << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1150*35238bceSAndroid Build Coastguard Worker                     error = true;
1151*35238bceSAndroid Build Coastguard Worker                 }
1152*35238bceSAndroid Build Coastguard Worker                 else if ((int)index >= (int)resourceList.size())
1153*35238bceSAndroid Build Coastguard Worker                 {
1154*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString
1155*35238bceSAndroid Build Coastguard Worker                                        << "\" resulted in index " << index
1156*35238bceSAndroid Build Coastguard Worker                                        << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1157*35238bceSAndroid Build Coastguard Worker                     error = true;
1158*35238bceSAndroid Build Coastguard Worker                 }
1159*35238bceSAndroid Build Coastguard Worker                 else if (resourceList[index] != queryString + "[0]")
1160*35238bceSAndroid Build Coastguard Worker                 {
1161*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString
1162*35238bceSAndroid Build Coastguard Worker                                        << "\" got index (index = " << index << ") of another resource (\""
1163*35238bceSAndroid Build Coastguard Worker                                        << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1164*35238bceSAndroid Build Coastguard Worker                     error = true;
1165*35238bceSAndroid Build Coastguard Worker                 }
1166*35238bceSAndroid Build Coastguard Worker             }
1167*35238bceSAndroid Build Coastguard Worker         }
1168*35238bceSAndroid Build Coastguard Worker     }
1169*35238bceSAndroid Build Coastguard Worker 
1170*35238bceSAndroid Build Coastguard Worker     return !error;
1171*35238bceSAndroid Build Coastguard Worker }
1172*35238bceSAndroid Build Coastguard Worker 
verifyMaxNameLength(const std::vector<std::string> & resourceList,glw::GLuint program)1173*35238bceSAndroid Build Coastguard Worker bool ResourceListTestCase::verifyMaxNameLength(const std::vector<std::string> &resourceList, glw::GLuint program)
1174*35238bceSAndroid Build Coastguard Worker {
1175*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1176*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1177*35238bceSAndroid Build Coastguard Worker     glw::GLint maxNameLength           = 0;
1178*35238bceSAndroid Build Coastguard Worker     glw::GLint expectedMaxNameLength   = 0;
1179*35238bceSAndroid Build Coastguard Worker 
1180*35238bceSAndroid Build Coastguard Worker     gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1181*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1184*35238bceSAndroid Build Coastguard Worker         expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1185*35238bceSAndroid Build Coastguard Worker 
1186*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength
1187*35238bceSAndroid Build Coastguard Worker                        << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1188*35238bceSAndroid Build Coastguard Worker 
1189*35238bceSAndroid Build Coastguard Worker     if (expectedMaxNameLength != maxNameLength)
1190*35238bceSAndroid Build Coastguard Worker     {
1191*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1192*35238bceSAndroid Build Coastguard Worker         return false;
1193*35238bceSAndroid Build Coastguard Worker     }
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker     return true;
1196*35238bceSAndroid Build Coastguard Worker }
1197*35238bceSAndroid Build Coastguard Worker 
genTestCaseName(ProgramInterface interface,const ResourceDefinition::Node * root)1198*35238bceSAndroid Build Coastguard Worker std::string ResourceListTestCase::genTestCaseName(ProgramInterface interface, const ResourceDefinition::Node *root)
1199*35238bceSAndroid Build Coastguard Worker {
1200*35238bceSAndroid Build Coastguard Worker     bool isImplicitlySizedArray = false;
1201*35238bceSAndroid Build Coastguard Worker     bool hasVariable            = false;
1202*35238bceSAndroid Build Coastguard Worker     bool accumulateName         = true;
1203*35238bceSAndroid Build Coastguard Worker     std::string buf             = "var";
1204*35238bceSAndroid Build Coastguard Worker     std::string prefix;
1205*35238bceSAndroid Build Coastguard Worker 
1206*35238bceSAndroid Build Coastguard Worker     for (const ResourceDefinition::Node *node = root; node; node = node->getEnclosingNode())
1207*35238bceSAndroid Build Coastguard Worker     {
1208*35238bceSAndroid Build Coastguard Worker         switch (node->getType())
1209*35238bceSAndroid Build Coastguard Worker         {
1210*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_VARIABLE:
1211*35238bceSAndroid Build Coastguard Worker         {
1212*35238bceSAndroid Build Coastguard Worker             hasVariable = true;
1213*35238bceSAndroid Build Coastguard Worker             break;
1214*35238bceSAndroid Build Coastguard Worker         }
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1217*35238bceSAndroid Build Coastguard Worker         {
1218*35238bceSAndroid Build Coastguard Worker             if (accumulateName)
1219*35238bceSAndroid Build Coastguard Worker                 buf += "_struct";
1220*35238bceSAndroid Build Coastguard Worker             break;
1221*35238bceSAndroid Build Coastguard Worker         }
1222*35238bceSAndroid Build Coastguard Worker 
1223*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1224*35238bceSAndroid Build Coastguard Worker         {
1225*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement *>(node));
1226*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::ArrayElement *arrayElement =
1227*35238bceSAndroid Build Coastguard Worker                 static_cast<const ResourceDefinition::ArrayElement *>(node);
1228*35238bceSAndroid Build Coastguard Worker 
1229*35238bceSAndroid Build Coastguard Worker             isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1230*35238bceSAndroid Build Coastguard Worker 
1231*35238bceSAndroid Build Coastguard Worker             if (accumulateName)
1232*35238bceSAndroid Build Coastguard Worker                 buf += "_array";
1233*35238bceSAndroid Build Coastguard Worker             break;
1234*35238bceSAndroid Build Coastguard Worker         }
1235*35238bceSAndroid Build Coastguard Worker 
1236*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1237*35238bceSAndroid Build Coastguard Worker         {
1238*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier *>(node));
1239*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::StorageQualifier *storageDef =
1240*35238bceSAndroid Build Coastguard Worker                 static_cast<const ResourceDefinition::StorageQualifier *>(node);
1241*35238bceSAndroid Build Coastguard Worker 
1242*35238bceSAndroid Build Coastguard Worker             if (storageDef->m_storage == glu::STORAGE_PATCH_IN || storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1243*35238bceSAndroid Build Coastguard Worker             {
1244*35238bceSAndroid Build Coastguard Worker                 if (accumulateName)
1245*35238bceSAndroid Build Coastguard Worker                     prefix += "patch_";
1246*35238bceSAndroid Build Coastguard Worker             }
1247*35238bceSAndroid Build Coastguard Worker             break;
1248*35238bceSAndroid Build Coastguard Worker         }
1249*35238bceSAndroid Build Coastguard Worker 
1250*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_SHADER:
1251*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_SHADER_SET:
1252*35238bceSAndroid Build Coastguard Worker         {
1253*35238bceSAndroid Build Coastguard Worker             bool arrayedInterface;
1254*35238bceSAndroid Build Coastguard Worker 
1255*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1256*35238bceSAndroid Build Coastguard Worker             {
1257*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader *>(node));
1258*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Shader *shaderDef = static_cast<const ResourceDefinition::Shader *>(node);
1259*35238bceSAndroid Build Coastguard Worker 
1260*35238bceSAndroid Build Coastguard Worker                 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1261*35238bceSAndroid Build Coastguard Worker             }
1262*35238bceSAndroid Build Coastguard Worker             else
1263*35238bceSAndroid Build Coastguard Worker             {
1264*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1265*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet *>(node));
1266*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::ShaderSet *shaderDef =
1267*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::ShaderSet *>(node);
1268*35238bceSAndroid Build Coastguard Worker 
1269*35238bceSAndroid Build Coastguard Worker                 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1270*35238bceSAndroid Build Coastguard Worker             }
1271*35238bceSAndroid Build Coastguard Worker 
1272*35238bceSAndroid Build Coastguard Worker             if (arrayedInterface && isImplicitlySizedArray)
1273*35238bceSAndroid Build Coastguard Worker             {
1274*35238bceSAndroid Build Coastguard Worker                 // omit implicit arrayness from name, i.e. remove trailing "_array"
1275*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(de::endsWith(buf, "_array"));
1276*35238bceSAndroid Build Coastguard Worker                 buf = buf.substr(0, buf.length() - 6);
1277*35238bceSAndroid Build Coastguard Worker             }
1278*35238bceSAndroid Build Coastguard Worker 
1279*35238bceSAndroid Build Coastguard Worker             break;
1280*35238bceSAndroid Build Coastguard Worker         }
1281*35238bceSAndroid Build Coastguard Worker 
1282*35238bceSAndroid Build Coastguard Worker         case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1283*35238bceSAndroid Build Coastguard Worker         {
1284*35238bceSAndroid Build Coastguard Worker             accumulateName = false;
1285*35238bceSAndroid Build Coastguard Worker             break;
1286*35238bceSAndroid Build Coastguard Worker         }
1287*35238bceSAndroid Build Coastguard Worker 
1288*35238bceSAndroid Build Coastguard Worker         default:
1289*35238bceSAndroid Build Coastguard Worker             break;
1290*35238bceSAndroid Build Coastguard Worker         }
1291*35238bceSAndroid Build Coastguard Worker     }
1292*35238bceSAndroid Build Coastguard Worker 
1293*35238bceSAndroid Build Coastguard Worker     if (!hasVariable)
1294*35238bceSAndroid Build Coastguard Worker         return prefix + "empty";
1295*35238bceSAndroid Build Coastguard Worker     else
1296*35238bceSAndroid Build Coastguard Worker         return prefix + buf;
1297*35238bceSAndroid Build Coastguard Worker }
1298*35238bceSAndroid Build Coastguard Worker 
isArrayedInterface(ProgramInterface interface,uint32_t stageBits)1299*35238bceSAndroid Build Coastguard Worker bool ResourceListTestCase::isArrayedInterface(ProgramInterface interface, uint32_t stageBits)
1300*35238bceSAndroid Build Coastguard Worker {
1301*35238bceSAndroid Build Coastguard Worker     if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1302*35238bceSAndroid Build Coastguard Worker     {
1303*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1304*35238bceSAndroid Build Coastguard Worker         return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1305*35238bceSAndroid Build Coastguard Worker                firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION || firstStage == glu::SHADERTYPE_GEOMETRY;
1306*35238bceSAndroid Build Coastguard Worker     }
1307*35238bceSAndroid Build Coastguard Worker     else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1308*35238bceSAndroid Build Coastguard Worker     {
1309*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1310*35238bceSAndroid Build Coastguard Worker         return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1311*35238bceSAndroid Build Coastguard Worker     }
1312*35238bceSAndroid Build Coastguard Worker     return false;
1313*35238bceSAndroid Build Coastguard Worker }
1314*35238bceSAndroid Build Coastguard Worker 
1315*35238bceSAndroid Build Coastguard Worker // Resouce property query case
1316*35238bceSAndroid Build Coastguard Worker 
1317*35238bceSAndroid Build Coastguard Worker class ResourceTestCase : public ProgramInterfaceQueryTestCase
1318*35238bceSAndroid Build Coastguard Worker {
1319*35238bceSAndroid Build Coastguard Worker public:
1320*35238bceSAndroid Build Coastguard Worker     ResourceTestCase(Context &context, const ResourceDefinition::Node::SharedPtr &targetResource,
1321*35238bceSAndroid Build Coastguard Worker                      const ProgramResourceQueryTestTarget &queryTarget, const char *name = DE_NULL);
1322*35238bceSAndroid Build Coastguard Worker     ~ResourceTestCase(void);
1323*35238bceSAndroid Build Coastguard Worker 
1324*35238bceSAndroid Build Coastguard Worker private:
1325*35238bceSAndroid Build Coastguard Worker     void init(void);
1326*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1327*35238bceSAndroid Build Coastguard Worker     const ProgramInterfaceDefinition::Program *getProgramDefinition(void) const;
1328*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> getQueryTargetResources(void) const;
1329*35238bceSAndroid Build Coastguard Worker 
1330*35238bceSAndroid Build Coastguard Worker     static std::string genTestCaseName(const ResourceDefinition::Node *);
1331*35238bceSAndroid Build Coastguard Worker     static std::string genMultilineDescription(const ResourceDefinition::Node *);
1332*35238bceSAndroid Build Coastguard Worker 
1333*35238bceSAndroid Build Coastguard Worker     ResourceDefinition::Node::SharedPtr m_targetResource;
1334*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_program;
1335*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> m_targetResources;
1336*35238bceSAndroid Build Coastguard Worker };
1337*35238bceSAndroid Build Coastguard Worker 
ResourceTestCase(Context & context,const ResourceDefinition::Node::SharedPtr & targetResource,const ProgramResourceQueryTestTarget & queryTarget,const char * name)1338*35238bceSAndroid Build Coastguard Worker ResourceTestCase::ResourceTestCase(Context &context, const ResourceDefinition::Node::SharedPtr &targetResource,
1339*35238bceSAndroid Build Coastguard Worker                                    const ProgramResourceQueryTestTarget &queryTarget, const char *name)
1340*35238bceSAndroid Build Coastguard Worker     : ProgramInterfaceQueryTestCase(
1341*35238bceSAndroid Build Coastguard Worker           context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1342*35238bceSAndroid Build Coastguard Worker     , m_targetResource(targetResource)
1343*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
1344*35238bceSAndroid Build Coastguard Worker {
1345*35238bceSAndroid Build Coastguard Worker }
1346*35238bceSAndroid Build Coastguard Worker 
~ResourceTestCase(void)1347*35238bceSAndroid Build Coastguard Worker ResourceTestCase::~ResourceTestCase(void)
1348*35238bceSAndroid Build Coastguard Worker {
1349*35238bceSAndroid Build Coastguard Worker     deinit();
1350*35238bceSAndroid Build Coastguard Worker }
1351*35238bceSAndroid Build Coastguard Worker 
init(void)1352*35238bceSAndroid Build Coastguard Worker void ResourceTestCase::init(void)
1353*35238bceSAndroid Build Coastguard Worker {
1354*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << genMultilineDescription(m_targetResource.get())
1355*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1356*35238bceSAndroid Build Coastguard Worker 
1357*35238bceSAndroid Build Coastguard Worker     // Program
1358*35238bceSAndroid Build Coastguard Worker     {
1359*35238bceSAndroid Build Coastguard Worker         // Generate interface with target resource
1360*35238bceSAndroid Build Coastguard Worker         m_program         = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1361*35238bceSAndroid Build Coastguard Worker         m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1362*35238bceSAndroid Build Coastguard Worker     }
1363*35238bceSAndroid Build Coastguard Worker }
1364*35238bceSAndroid Build Coastguard Worker 
deinit(void)1365*35238bceSAndroid Build Coastguard Worker void ResourceTestCase::deinit(void)
1366*35238bceSAndroid Build Coastguard Worker {
1367*35238bceSAndroid Build Coastguard Worker     m_targetResource.clear();
1368*35238bceSAndroid Build Coastguard Worker 
1369*35238bceSAndroid Build Coastguard Worker     delete m_program;
1370*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
1371*35238bceSAndroid Build Coastguard Worker 
1372*35238bceSAndroid Build Coastguard Worker     m_targetResources = std::vector<std::string>();
1373*35238bceSAndroid Build Coastguard Worker }
1374*35238bceSAndroid Build Coastguard Worker 
getProgramDefinition(void) const1375*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *ResourceTestCase::getProgramDefinition(void) const
1376*35238bceSAndroid Build Coastguard Worker {
1377*35238bceSAndroid Build Coastguard Worker     return m_program;
1378*35238bceSAndroid Build Coastguard Worker }
1379*35238bceSAndroid Build Coastguard Worker 
getQueryTargetResources(void) const1380*35238bceSAndroid Build Coastguard Worker std::vector<std::string> ResourceTestCase::getQueryTargetResources(void) const
1381*35238bceSAndroid Build Coastguard Worker {
1382*35238bceSAndroid Build Coastguard Worker     return m_targetResources;
1383*35238bceSAndroid Build Coastguard Worker }
1384*35238bceSAndroid Build Coastguard Worker 
genTestCaseName(const ResourceDefinition::Node * resource)1385*35238bceSAndroid Build Coastguard Worker std::string ResourceTestCase::genTestCaseName(const ResourceDefinition::Node *resource)
1386*35238bceSAndroid Build Coastguard Worker {
1387*35238bceSAndroid Build Coastguard Worker     if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1388*35238bceSAndroid Build Coastguard Worker     {
1389*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable *>(resource));
1390*35238bceSAndroid Build Coastguard Worker 
1391*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Variable *variable = static_cast<const ResourceDefinition::Variable *>(resource);
1392*35238bceSAndroid Build Coastguard Worker 
1393*35238bceSAndroid Build Coastguard Worker         return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1394*35238bceSAndroid Build Coastguard Worker     }
1395*35238bceSAndroid Build Coastguard Worker 
1396*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
1397*35238bceSAndroid Build Coastguard Worker     return "";
1398*35238bceSAndroid Build Coastguard Worker }
1399*35238bceSAndroid Build Coastguard Worker 
genMultilineDescription(const ResourceDefinition::Node * resource)1400*35238bceSAndroid Build Coastguard Worker std::string ResourceTestCase::genMultilineDescription(const ResourceDefinition::Node *resource)
1401*35238bceSAndroid Build Coastguard Worker {
1402*35238bceSAndroid Build Coastguard Worker     if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1403*35238bceSAndroid Build Coastguard Worker     {
1404*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable *>(resource));
1405*35238bceSAndroid Build Coastguard Worker 
1406*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Variable *varDef = static_cast<const ResourceDefinition::Variable *>(resource);
1407*35238bceSAndroid Build Coastguard Worker         std::ostringstream buf;
1408*35238bceSAndroid Build Coastguard Worker         std::ostringstream structureDescriptor;
1409*35238bceSAndroid Build Coastguard Worker         std::string uniformType;
1410*35238bceSAndroid Build Coastguard Worker 
1411*35238bceSAndroid Build Coastguard Worker         for (const ResourceDefinition::Node *node = resource; node; node = node->getEnclosingNode())
1412*35238bceSAndroid Build Coastguard Worker         {
1413*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1414*35238bceSAndroid Build Coastguard Worker             {
1415*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier *>(node));
1416*35238bceSAndroid Build Coastguard Worker 
1417*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::StorageQualifier *storageDef =
1418*35238bceSAndroid Build Coastguard Worker                     static_cast<const ResourceDefinition::StorageQualifier *>(node);
1419*35238bceSAndroid Build Coastguard Worker 
1420*35238bceSAndroid Build Coastguard Worker                 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1421*35238bceSAndroid Build Coastguard Worker                 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1422*35238bceSAndroid Build Coastguard Worker             }
1423*35238bceSAndroid Build Coastguard Worker 
1424*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1425*35238bceSAndroid Build Coastguard Worker                 structureDescriptor << "\n\tarray";
1426*35238bceSAndroid Build Coastguard Worker 
1427*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1428*35238bceSAndroid Build Coastguard Worker                 structureDescriptor << "\n\tin a struct";
1429*35238bceSAndroid Build Coastguard Worker 
1430*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1431*35238bceSAndroid Build Coastguard Worker                 structureDescriptor << "\n\tin the default block";
1432*35238bceSAndroid Build Coastguard Worker 
1433*35238bceSAndroid Build Coastguard Worker             if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1434*35238bceSAndroid Build Coastguard Worker                 structureDescriptor << "\n\tin an interface block";
1435*35238bceSAndroid Build Coastguard Worker         }
1436*35238bceSAndroid Build Coastguard Worker 
1437*35238bceSAndroid Build Coastguard Worker         buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1438*35238bceSAndroid Build Coastguard Worker             << "Variable is:\n"
1439*35238bceSAndroid Build Coastguard Worker             << "\t" << glu::getDataTypeName(varDef->m_dataType) << structureDescriptor.str();
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker         return buf.str();
1442*35238bceSAndroid Build Coastguard Worker     }
1443*35238bceSAndroid Build Coastguard Worker     else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1444*35238bceSAndroid Build Coastguard Worker     {
1445*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget *>(resource));
1446*35238bceSAndroid Build Coastguard Worker 
1447*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::TransformFeedbackTarget *xfbDef =
1448*35238bceSAndroid Build Coastguard Worker             static_cast<const ResourceDefinition::TransformFeedbackTarget *>(resource);
1449*35238bceSAndroid Build Coastguard Worker 
1450*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(xfbDef->m_builtinVarName);
1451*35238bceSAndroid Build Coastguard Worker 
1452*35238bceSAndroid Build Coastguard Worker         return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1453*35238bceSAndroid Build Coastguard Worker     }
1454*35238bceSAndroid Build Coastguard Worker 
1455*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
1456*35238bceSAndroid Build Coastguard Worker     return "";
1457*35238bceSAndroid Build Coastguard Worker }
1458*35238bceSAndroid Build Coastguard Worker 
1459*35238bceSAndroid Build Coastguard Worker class ResourceNameBufferLimitCase : public TestCase
1460*35238bceSAndroid Build Coastguard Worker {
1461*35238bceSAndroid Build Coastguard Worker public:
1462*35238bceSAndroid Build Coastguard Worker     ResourceNameBufferLimitCase(Context &context, const char *name, const char *description);
1463*35238bceSAndroid Build Coastguard Worker     ~ResourceNameBufferLimitCase(void);
1464*35238bceSAndroid Build Coastguard Worker 
1465*35238bceSAndroid Build Coastguard Worker private:
1466*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1467*35238bceSAndroid Build Coastguard Worker };
1468*35238bceSAndroid Build Coastguard Worker 
ResourceNameBufferLimitCase(Context & context,const char * name,const char * description)1469*35238bceSAndroid Build Coastguard Worker ResourceNameBufferLimitCase::ResourceNameBufferLimitCase(Context &context, const char *name, const char *description)
1470*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1471*35238bceSAndroid Build Coastguard Worker {
1472*35238bceSAndroid Build Coastguard Worker }
1473*35238bceSAndroid Build Coastguard Worker 
~ResourceNameBufferLimitCase(void)1474*35238bceSAndroid Build Coastguard Worker ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase(void)
1475*35238bceSAndroid Build Coastguard Worker {
1476*35238bceSAndroid Build Coastguard Worker }
1477*35238bceSAndroid Build Coastguard Worker 
iterate(void)1478*35238bceSAndroid Build Coastguard Worker ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate(void)
1479*35238bceSAndroid Build Coastguard Worker {
1480*35238bceSAndroid Build Coastguard Worker     static const char *const computeSource = "${GLSL_VERSION_DECL}\n"
1481*35238bceSAndroid Build Coastguard Worker                                              "layout(local_size_x = 1) in;\n"
1482*35238bceSAndroid Build Coastguard Worker                                              "uniform highp int u_uniformWithALongName;\n"
1483*35238bceSAndroid Build Coastguard Worker                                              "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1484*35238bceSAndroid Build Coastguard Worker                                              "void main ()\n"
1485*35238bceSAndroid Build Coastguard Worker                                              "{\n"
1486*35238bceSAndroid Build Coastguard Worker                                              "    b_output_int = u_uniformWithALongName;\n"
1487*35238bceSAndroid Build Coastguard Worker                                              "}\n";
1488*35238bceSAndroid Build Coastguard Worker 
1489*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1490*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
1491*35238bceSAndroid Build Coastguard Worker                                                                        specializeShader(m_context, computeSource)));
1492*35238bceSAndroid Build Coastguard Worker     glw::GLuint uniformIndex;
1493*35238bceSAndroid Build Coastguard Worker 
1494*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1495*35238bceSAndroid Build Coastguard Worker 
1496*35238bceSAndroid Build Coastguard Worker     // Log program
1497*35238bceSAndroid Build Coastguard Worker     {
1498*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1499*35238bceSAndroid Build Coastguard Worker 
1500*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1501*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1502*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("could not build program");
1503*35238bceSAndroid Build Coastguard Worker     }
1504*35238bceSAndroid Build Coastguard Worker 
1505*35238bceSAndroid Build Coastguard Worker     uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1506*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1507*35238bceSAndroid Build Coastguard Worker 
1508*35238bceSAndroid Build Coastguard Worker     if (uniformIndex == GL_INVALID_INDEX)
1509*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1510*35238bceSAndroid Build Coastguard Worker 
1511*35238bceSAndroid Build Coastguard Worker     // Query with different sized buffers, len("u_uniformWithALongName") == 22
1512*35238bceSAndroid Build Coastguard Worker 
1513*35238bceSAndroid Build Coastguard Worker     {
1514*35238bceSAndroid Build Coastguard Worker         static const struct
1515*35238bceSAndroid Build Coastguard Worker         {
1516*35238bceSAndroid Build Coastguard Worker             const char *description;
1517*35238bceSAndroid Build Coastguard Worker             int querySize;
1518*35238bceSAndroid Build Coastguard Worker             bool returnLength;
1519*35238bceSAndroid Build Coastguard Worker         } querySizes[] = {
1520*35238bceSAndroid Build Coastguard Worker             {"Query to larger buffer", 24, true},
1521*35238bceSAndroid Build Coastguard Worker             {"Query to buffer the same size", 23, true},
1522*35238bceSAndroid Build Coastguard Worker             {"Query to one byte too small buffer", 22, true},
1523*35238bceSAndroid Build Coastguard Worker             {"Query to one byte buffer", 1, true},
1524*35238bceSAndroid Build Coastguard Worker             {"Query to zero sized buffer", 0, true},
1525*35238bceSAndroid Build Coastguard Worker             {"Query to one byte too small buffer, null length argument", 22, false},
1526*35238bceSAndroid Build Coastguard Worker             {"Query to one byte buffer, null length argument", 1, false},
1527*35238bceSAndroid Build Coastguard Worker             {"Query to zero sized buffer, null length argument", 0, false},
1528*35238bceSAndroid Build Coastguard Worker         };
1529*35238bceSAndroid Build Coastguard Worker 
1530*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1531*35238bceSAndroid Build Coastguard Worker         {
1532*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "Query", querySizes[ndx].description);
1533*35238bceSAndroid Build Coastguard Worker             const int uniformNameLen = 22;
1534*35238bceSAndroid Build Coastguard Worker             const int expectedWriteLen =
1535*35238bceSAndroid Build Coastguard Worker                 (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1536*35238bceSAndroid Build Coastguard Worker             char buffer[26];
1537*35238bceSAndroid Build Coastguard Worker             glw::GLsizei written = -1;
1538*35238bceSAndroid Build Coastguard Worker 
1539*35238bceSAndroid Build Coastguard Worker             // One byte for guard
1540*35238bceSAndroid Build Coastguard Worker             DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1541*35238bceSAndroid Build Coastguard Worker 
1542*35238bceSAndroid Build Coastguard Worker             deMemset(buffer, 'x', sizeof(buffer));
1543*35238bceSAndroid Build Coastguard Worker 
1544*35238bceSAndroid Build Coastguard Worker             if (querySizes[ndx].querySize)
1545*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Querying uniform name to a buffer of size "
1546*35238bceSAndroid Build Coastguard Worker                                    << querySizes[ndx].querySize << ", expecting query to write " << expectedWriteLen
1547*35238bceSAndroid Build Coastguard Worker                                    << " bytes followed by a null terminator" << tcu::TestLog::EndMessage;
1548*35238bceSAndroid Build Coastguard Worker             else
1549*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Querying uniform name to a buffer of size "
1550*35238bceSAndroid Build Coastguard Worker                                    << querySizes[ndx].querySize << ", expecting query to write 0 bytes"
1551*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1552*35238bceSAndroid Build Coastguard Worker 
1553*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize,
1554*35238bceSAndroid Build Coastguard Worker                                       (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1555*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1556*35238bceSAndroid Build Coastguard Worker 
1557*35238bceSAndroid Build Coastguard Worker             if (querySizes[ndx].returnLength && written != expectedWriteLen)
1558*35238bceSAndroid Build Coastguard Worker             {
1559*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen
1560*35238bceSAndroid Build Coastguard Worker                                    << ", got " << written << tcu::TestLog::EndMessage;
1561*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1562*35238bceSAndroid Build Coastguard Worker             }
1563*35238bceSAndroid Build Coastguard Worker             else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1564*35238bceSAndroid Build Coastguard Worker             {
1565*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen
1566*35238bceSAndroid Build Coastguard Worker                                    << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1567*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1568*35238bceSAndroid Build Coastguard Worker             }
1569*35238bceSAndroid Build Coastguard Worker             else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen + 1] != 'x')
1570*35238bceSAndroid Build Coastguard Worker             {
1571*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen + 1)
1572*35238bceSAndroid Build Coastguard Worker                                    << " was modified, got dec=" << (int)buffer[expectedWriteLen + 1]
1573*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1574*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1575*35238bceSAndroid Build Coastguard Worker             }
1576*35238bceSAndroid Build Coastguard Worker             else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1577*35238bceSAndroid Build Coastguard Worker             {
1578*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1579*35238bceSAndroid Build Coastguard Worker                                    << "Error, buffer size was 0 but buffer contents were modified. At index 0 got dec="
1580*35238bceSAndroid Build Coastguard Worker                                    << (int)buffer[0] << tcu::TestLog::EndMessage;
1581*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1582*35238bceSAndroid Build Coastguard Worker             }
1583*35238bceSAndroid Build Coastguard Worker         }
1584*35238bceSAndroid Build Coastguard Worker     }
1585*35238bceSAndroid Build Coastguard Worker 
1586*35238bceSAndroid Build Coastguard Worker     return STOP;
1587*35238bceSAndroid Build Coastguard Worker }
1588*35238bceSAndroid Build Coastguard Worker 
1589*35238bceSAndroid Build Coastguard Worker class ResourceQueryBufferLimitCase : public TestCase
1590*35238bceSAndroid Build Coastguard Worker {
1591*35238bceSAndroid Build Coastguard Worker public:
1592*35238bceSAndroid Build Coastguard Worker     ResourceQueryBufferLimitCase(Context &context, const char *name, const char *description);
1593*35238bceSAndroid Build Coastguard Worker     ~ResourceQueryBufferLimitCase(void);
1594*35238bceSAndroid Build Coastguard Worker 
1595*35238bceSAndroid Build Coastguard Worker private:
1596*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1597*35238bceSAndroid Build Coastguard Worker };
1598*35238bceSAndroid Build Coastguard Worker 
ResourceQueryBufferLimitCase(Context & context,const char * name,const char * description)1599*35238bceSAndroid Build Coastguard Worker ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase(Context &context, const char *name, const char *description)
1600*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1601*35238bceSAndroid Build Coastguard Worker {
1602*35238bceSAndroid Build Coastguard Worker }
1603*35238bceSAndroid Build Coastguard Worker 
~ResourceQueryBufferLimitCase(void)1604*35238bceSAndroid Build Coastguard Worker ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase(void)
1605*35238bceSAndroid Build Coastguard Worker {
1606*35238bceSAndroid Build Coastguard Worker }
1607*35238bceSAndroid Build Coastguard Worker 
iterate(void)1608*35238bceSAndroid Build Coastguard Worker ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate(void)
1609*35238bceSAndroid Build Coastguard Worker {
1610*35238bceSAndroid Build Coastguard Worker     static const char *const computeSource = "${GLSL_VERSION_DECL}\n"
1611*35238bceSAndroid Build Coastguard Worker                                              "layout(local_size_x = 1) in;\n"
1612*35238bceSAndroid Build Coastguard Worker                                              "uniform highp int u_uniform;\n"
1613*35238bceSAndroid Build Coastguard Worker                                              "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1614*35238bceSAndroid Build Coastguard Worker                                              "void main ()\n"
1615*35238bceSAndroid Build Coastguard Worker                                              "{\n"
1616*35238bceSAndroid Build Coastguard Worker                                              "    b_output_int = u_uniform;\n"
1617*35238bceSAndroid Build Coastguard Worker                                              "}\n";
1618*35238bceSAndroid Build Coastguard Worker 
1619*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1620*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
1621*35238bceSAndroid Build Coastguard Worker                                                                        specializeShader(m_context, computeSource)));
1622*35238bceSAndroid Build Coastguard Worker     glw::GLuint uniformIndex;
1623*35238bceSAndroid Build Coastguard Worker 
1624*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1625*35238bceSAndroid Build Coastguard Worker 
1626*35238bceSAndroid Build Coastguard Worker     // Log program
1627*35238bceSAndroid Build Coastguard Worker     {
1628*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1629*35238bceSAndroid Build Coastguard Worker 
1630*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1631*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1632*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("could not build program");
1633*35238bceSAndroid Build Coastguard Worker     }
1634*35238bceSAndroid Build Coastguard Worker 
1635*35238bceSAndroid Build Coastguard Worker     uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1636*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1637*35238bceSAndroid Build Coastguard Worker 
1638*35238bceSAndroid Build Coastguard Worker     if (uniformIndex == GL_INVALID_INDEX)
1639*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1640*35238bceSAndroid Build Coastguard Worker 
1641*35238bceSAndroid Build Coastguard Worker     // Query uniform properties
1642*35238bceSAndroid Build Coastguard Worker 
1643*35238bceSAndroid Build Coastguard Worker     {
1644*35238bceSAndroid Build Coastguard Worker         static const struct
1645*35238bceSAndroid Build Coastguard Worker         {
1646*35238bceSAndroid Build Coastguard Worker             const char *description;
1647*35238bceSAndroid Build Coastguard Worker             int numProps;
1648*35238bceSAndroid Build Coastguard Worker             int bufferSize;
1649*35238bceSAndroid Build Coastguard Worker             bool returnLength;
1650*35238bceSAndroid Build Coastguard Worker         } querySizes[] = {
1651*35238bceSAndroid Build Coastguard Worker             {"Query to a larger buffer", 2, 3, true},
1652*35238bceSAndroid Build Coastguard Worker             {"Query to too small a buffer", 3, 2, true},
1653*35238bceSAndroid Build Coastguard Worker             {"Query to zero sized buffer", 3, 0, true},
1654*35238bceSAndroid Build Coastguard Worker             {"Query to a larger buffer, null length argument", 2, 3, false},
1655*35238bceSAndroid Build Coastguard Worker             {"Query to too small a buffer, null length argument", 3, 2, false},
1656*35238bceSAndroid Build Coastguard Worker             {"Query to zero sized buffer, null length argument", 3, 0, false},
1657*35238bceSAndroid Build Coastguard Worker         };
1658*35238bceSAndroid Build Coastguard Worker 
1659*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1660*35238bceSAndroid Build Coastguard Worker         {
1661*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1662*35238bceSAndroid Build Coastguard Worker             const glw::GLenum props[]  = {GL_LOCATION, GL_LOCATION, GL_LOCATION};
1663*35238bceSAndroid Build Coastguard Worker             const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1664*35238bceSAndroid Build Coastguard Worker             int params[]               = {255, 255, 255, 255};
1665*35238bceSAndroid Build Coastguard Worker             glw::GLsizei written       = -1;
1666*35238bceSAndroid Build Coastguard Worker 
1667*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1668*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(querySizes[ndx].bufferSize <
1669*35238bceSAndroid Build Coastguard Worker                       DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1670*35238bceSAndroid Build Coastguard Worker 
1671*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << querySizes[ndx].numProps
1672*35238bceSAndroid Build Coastguard Worker                                << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize
1673*35238bceSAndroid Build Coastguard Worker                                << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1674*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1675*35238bceSAndroid Build Coastguard Worker 
1676*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props,
1677*35238bceSAndroid Build Coastguard Worker                                     querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL),
1678*35238bceSAndroid Build Coastguard Worker                                     params);
1679*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1680*35238bceSAndroid Build Coastguard Worker 
1681*35238bceSAndroid Build Coastguard Worker             if (querySizes[ndx].returnLength && written != expectedWriteLen)
1682*35238bceSAndroid Build Coastguard Worker             {
1683*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen
1684*35238bceSAndroid Build Coastguard Worker                                    << ", got " << written << tcu::TestLog::EndMessage;
1685*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1686*35238bceSAndroid Build Coastguard Worker             }
1687*35238bceSAndroid Build Coastguard Worker             else if (params[expectedWriteLen] != 255)
1688*35238bceSAndroid Build Coastguard Worker             {
1689*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen)
1690*35238bceSAndroid Build Coastguard Worker                                    << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen]
1691*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1692*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1693*35238bceSAndroid Build Coastguard Worker             }
1694*35238bceSAndroid Build Coastguard Worker         }
1695*35238bceSAndroid Build Coastguard Worker     }
1696*35238bceSAndroid Build Coastguard Worker 
1697*35238bceSAndroid Build Coastguard Worker     return STOP;
1698*35238bceSAndroid Build Coastguard Worker }
1699*35238bceSAndroid Build Coastguard Worker 
1700*35238bceSAndroid Build Coastguard Worker class InterfaceBlockBaseCase : public TestCase
1701*35238bceSAndroid Build Coastguard Worker {
1702*35238bceSAndroid Build Coastguard Worker public:
1703*35238bceSAndroid Build Coastguard Worker     enum CaseType
1704*35238bceSAndroid Build Coastguard Worker     {
1705*35238bceSAndroid Build Coastguard Worker         CASE_NAMED_BLOCK = 0,
1706*35238bceSAndroid Build Coastguard Worker         CASE_UNNAMED_BLOCK,
1707*35238bceSAndroid Build Coastguard Worker         CASE_BLOCK_ARRAY,
1708*35238bceSAndroid Build Coastguard Worker 
1709*35238bceSAndroid Build Coastguard Worker         CASE_LAST
1710*35238bceSAndroid Build Coastguard Worker     };
1711*35238bceSAndroid Build Coastguard Worker 
1712*35238bceSAndroid Build Coastguard Worker     InterfaceBlockBaseCase(Context &context, const char *name, const char *description, glu::Storage storage,
1713*35238bceSAndroid Build Coastguard Worker                            CaseType caseType);
1714*35238bceSAndroid Build Coastguard Worker     ~InterfaceBlockBaseCase(void);
1715*35238bceSAndroid Build Coastguard Worker 
1716*35238bceSAndroid Build Coastguard Worker private:
1717*35238bceSAndroid Build Coastguard Worker     void init(void);
1718*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1719*35238bceSAndroid Build Coastguard Worker 
1720*35238bceSAndroid Build Coastguard Worker protected:
1721*35238bceSAndroid Build Coastguard Worker     const glu::Storage m_storage;
1722*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
1723*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_program;
1724*35238bceSAndroid Build Coastguard Worker };
1725*35238bceSAndroid Build Coastguard Worker 
InterfaceBlockBaseCase(Context & context,const char * name,const char * description,glu::Storage storage,CaseType caseType)1726*35238bceSAndroid Build Coastguard Worker InterfaceBlockBaseCase::InterfaceBlockBaseCase(Context &context, const char *name, const char *description,
1727*35238bceSAndroid Build Coastguard Worker                                                glu::Storage storage, CaseType caseType)
1728*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1729*35238bceSAndroid Build Coastguard Worker     , m_storage(storage)
1730*35238bceSAndroid Build Coastguard Worker     , m_caseType(caseType)
1731*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
1732*35238bceSAndroid Build Coastguard Worker {
1733*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1734*35238bceSAndroid Build Coastguard Worker }
1735*35238bceSAndroid Build Coastguard Worker 
~InterfaceBlockBaseCase(void)1736*35238bceSAndroid Build Coastguard Worker InterfaceBlockBaseCase::~InterfaceBlockBaseCase(void)
1737*35238bceSAndroid Build Coastguard Worker {
1738*35238bceSAndroid Build Coastguard Worker     deinit();
1739*35238bceSAndroid Build Coastguard Worker }
1740*35238bceSAndroid Build Coastguard Worker 
init(void)1741*35238bceSAndroid Build Coastguard Worker void InterfaceBlockBaseCase::init(void)
1742*35238bceSAndroid Build Coastguard Worker {
1743*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1744*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Shader *shader;
1745*35238bceSAndroid Build Coastguard Worker 
1746*35238bceSAndroid Build Coastguard Worker     m_program = new ProgramInterfaceDefinition::Program();
1747*35238bceSAndroid Build Coastguard Worker     shader    = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
1748*35238bceSAndroid Build Coastguard Worker 
1749*35238bceSAndroid Build Coastguard Worker     // PrecedingInterface
1750*35238bceSAndroid Build Coastguard Worker     {
1751*35238bceSAndroid Build Coastguard Worker         glu::InterfaceBlock precedingInterfaceBlock;
1752*35238bceSAndroid Build Coastguard Worker 
1753*35238bceSAndroid Build Coastguard Worker         precedingInterfaceBlock.interfaceName  = "PrecedingInterface";
1754*35238bceSAndroid Build Coastguard Worker         precedingInterfaceBlock.layout.binding = 0;
1755*35238bceSAndroid Build Coastguard Worker         precedingInterfaceBlock.storage        = m_storage;
1756*35238bceSAndroid Build Coastguard Worker         precedingInterfaceBlock.instanceName   = "precedingInstance";
1757*35238bceSAndroid Build Coastguard Worker 
1758*35238bceSAndroid Build Coastguard Worker         precedingInterfaceBlock.variables.push_back(
1759*35238bceSAndroid Build Coastguard Worker             glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1760*35238bceSAndroid Build Coastguard Worker 
1761*35238bceSAndroid Build Coastguard Worker         // Unsized array type
1762*35238bceSAndroid Build Coastguard Worker         if (m_storage == glu::STORAGE_BUFFER)
1763*35238bceSAndroid Build Coastguard Worker             precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(
1764*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
1765*35238bceSAndroid Build Coastguard Worker                 "precedingMemberUnsizedArray"));
1766*35238bceSAndroid Build Coastguard Worker         else
1767*35238bceSAndroid Build Coastguard Worker             precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(
1768*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1769*35238bceSAndroid Build Coastguard Worker 
1770*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1771*35238bceSAndroid Build Coastguard Worker     }
1772*35238bceSAndroid Build Coastguard Worker 
1773*35238bceSAndroid Build Coastguard Worker     // TargetInterface
1774*35238bceSAndroid Build Coastguard Worker     {
1775*35238bceSAndroid Build Coastguard Worker         glu::InterfaceBlock targetInterfaceBlock;
1776*35238bceSAndroid Build Coastguard Worker 
1777*35238bceSAndroid Build Coastguard Worker         targetInterfaceBlock.interfaceName  = "TargetInterface";
1778*35238bceSAndroid Build Coastguard Worker         targetInterfaceBlock.layout.binding = 1;
1779*35238bceSAndroid Build Coastguard Worker         targetInterfaceBlock.storage        = m_storage;
1780*35238bceSAndroid Build Coastguard Worker 
1781*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_UNNAMED_BLOCK)
1782*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.instanceName = "";
1783*35238bceSAndroid Build Coastguard Worker         else
1784*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.instanceName = "targetInstance";
1785*35238bceSAndroid Build Coastguard Worker 
1786*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_BLOCK_ARRAY)
1787*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.dimensions.push_back(2);
1788*35238bceSAndroid Build Coastguard Worker 
1789*35238bceSAndroid Build Coastguard Worker         // Basic type
1790*35238bceSAndroid Build Coastguard Worker         {
1791*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.variables.push_back(
1792*35238bceSAndroid Build Coastguard Worker                 glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1793*35238bceSAndroid Build Coastguard Worker         }
1794*35238bceSAndroid Build Coastguard Worker 
1795*35238bceSAndroid Build Coastguard Worker         // Array type
1796*35238bceSAndroid Build Coastguard Worker         {
1797*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(
1798*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1799*35238bceSAndroid Build Coastguard Worker         }
1800*35238bceSAndroid Build Coastguard Worker 
1801*35238bceSAndroid Build Coastguard Worker         // Struct type
1802*35238bceSAndroid Build Coastguard Worker         {
1803*35238bceSAndroid Build Coastguard Worker             glu::StructType *structPtr = new glu::StructType("StructType");
1804*35238bceSAndroid Build Coastguard Worker             structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1805*35238bceSAndroid Build Coastguard Worker             structPtr->addMember("structMemberArray",
1806*35238bceSAndroid Build Coastguard Worker                                  glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1807*35238bceSAndroid Build Coastguard Worker 
1808*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.variables.push_back(
1809*35238bceSAndroid Build Coastguard Worker                 glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1810*35238bceSAndroid Build Coastguard Worker         }
1811*35238bceSAndroid Build Coastguard Worker 
1812*35238bceSAndroid Build Coastguard Worker         // Unsized array type
1813*35238bceSAndroid Build Coastguard Worker         if (m_storage == glu::STORAGE_BUFFER)
1814*35238bceSAndroid Build Coastguard Worker             targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(
1815*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
1816*35238bceSAndroid Build Coastguard Worker                 "blockMemberUnsizedArray"));
1817*35238bceSAndroid Build Coastguard Worker 
1818*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1819*35238bceSAndroid Build Coastguard Worker     }
1820*35238bceSAndroid Build Coastguard Worker 
1821*35238bceSAndroid Build Coastguard Worker     // TrailingInterface
1822*35238bceSAndroid Build Coastguard Worker     {
1823*35238bceSAndroid Build Coastguard Worker         glu::InterfaceBlock trailingInterfaceBlock;
1824*35238bceSAndroid Build Coastguard Worker 
1825*35238bceSAndroid Build Coastguard Worker         trailingInterfaceBlock.interfaceName  = "TrailingInterface";
1826*35238bceSAndroid Build Coastguard Worker         trailingInterfaceBlock.layout.binding = 3;
1827*35238bceSAndroid Build Coastguard Worker         trailingInterfaceBlock.storage        = m_storage;
1828*35238bceSAndroid Build Coastguard Worker         trailingInterfaceBlock.instanceName   = "trailingInstance";
1829*35238bceSAndroid Build Coastguard Worker         trailingInterfaceBlock.variables.push_back(
1830*35238bceSAndroid Build Coastguard Worker             glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1831*35238bceSAndroid Build Coastguard Worker 
1832*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1833*35238bceSAndroid Build Coastguard Worker     }
1834*35238bceSAndroid Build Coastguard Worker 
1835*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_program->isValid());
1836*35238bceSAndroid Build Coastguard Worker }
1837*35238bceSAndroid Build Coastguard Worker 
deinit(void)1838*35238bceSAndroid Build Coastguard Worker void InterfaceBlockBaseCase::deinit(void)
1839*35238bceSAndroid Build Coastguard Worker {
1840*35238bceSAndroid Build Coastguard Worker     delete m_program;
1841*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
1842*35238bceSAndroid Build Coastguard Worker }
1843*35238bceSAndroid Build Coastguard Worker 
1844*35238bceSAndroid Build Coastguard Worker class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1845*35238bceSAndroid Build Coastguard Worker {
1846*35238bceSAndroid Build Coastguard Worker public:
1847*35238bceSAndroid Build Coastguard Worker     InterfaceBlockActiveVariablesTestCase(Context &context, const char *name, const char *description,
1848*35238bceSAndroid Build Coastguard Worker                                           glu::Storage storage, CaseType caseType);
1849*35238bceSAndroid Build Coastguard Worker 
1850*35238bceSAndroid Build Coastguard Worker private:
1851*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1852*35238bceSAndroid Build Coastguard Worker };
1853*35238bceSAndroid Build Coastguard Worker 
InterfaceBlockActiveVariablesTestCase(Context & context,const char * name,const char * description,glu::Storage storage,CaseType caseType)1854*35238bceSAndroid Build Coastguard Worker InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase(Context &context, const char *name,
1855*35238bceSAndroid Build Coastguard Worker                                                                              const char *description,
1856*35238bceSAndroid Build Coastguard Worker                                                                              glu::Storage storage, CaseType caseType)
1857*35238bceSAndroid Build Coastguard Worker     : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1858*35238bceSAndroid Build Coastguard Worker {
1859*35238bceSAndroid Build Coastguard Worker }
1860*35238bceSAndroid Build Coastguard Worker 
iterate(void)1861*35238bceSAndroid Build Coastguard Worker InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate(void)
1862*35238bceSAndroid Build Coastguard Worker {
1863*35238bceSAndroid Build Coastguard Worker     const ProgramInterface programInterface =
1864*35238bceSAndroid Build Coastguard Worker         (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1865*35238bceSAndroid Build Coastguard Worker         (m_storage == glu::STORAGE_BUFFER)  ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1866*35238bceSAndroid Build Coastguard Worker                                               (PROGRAMINTERFACE_LAST);
1867*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programGLInterfaceValue     = getProgramInterfaceGLEnum(programInterface);
1868*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1869*35238bceSAndroid Build Coastguard Worker                                                     (m_storage == glu::STORAGE_BUFFER)  ? (GL_BUFFER_VARIABLE) :
1870*35238bceSAndroid Build Coastguard Worker                                                                                           (0);
1871*35238bceSAndroid Build Coastguard Worker     const std::vector<std::string> blockNames     = getProgramInterfaceResourceList(m_program, programInterface);
1872*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1873*35238bceSAndroid Build Coastguard Worker     int expectedMaxNumActiveVariables = 0;
1874*35238bceSAndroid Build Coastguard Worker 
1875*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1876*35238bceSAndroid Build Coastguard Worker 
1877*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1878*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1879*35238bceSAndroid Build Coastguard Worker 
1880*35238bceSAndroid Build Coastguard Worker     // Verify all blocks
1881*35238bceSAndroid Build Coastguard Worker 
1882*35238bceSAndroid Build Coastguard Worker     for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1883*35238bceSAndroid Build Coastguard Worker     {
1884*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1885*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1886*35238bceSAndroid Build Coastguard Worker         const glw::GLuint resourceNdx =
1887*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1888*35238bceSAndroid Build Coastguard Worker         glw::GLint numActiveResources;
1889*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> activeResourceNames;
1890*35238bceSAndroid Build Coastguard Worker 
1891*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1892*35238bceSAndroid Build Coastguard Worker 
1893*35238bceSAndroid Build Coastguard Worker         if (resourceNdx == GL_INVALID_INDEX)
1894*35238bceSAndroid Build Coastguard Worker         {
1895*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
1896*35238bceSAndroid Build Coastguard Worker                                << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \""
1897*35238bceSAndroid Build Coastguard Worker                                << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1898*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1899*35238bceSAndroid Build Coastguard Worker             continue;
1900*35238bceSAndroid Build Coastguard Worker         }
1901*35238bceSAndroid Build Coastguard Worker 
1902*35238bceSAndroid Build Coastguard Worker         // query block information
1903*35238bceSAndroid Build Coastguard Worker 
1904*35238bceSAndroid Build Coastguard Worker         {
1905*35238bceSAndroid Build Coastguard Worker             const glw::GLenum props[] = {GL_NUM_ACTIVE_VARIABLES};
1906*35238bceSAndroid Build Coastguard Worker             glw::GLint retBuffer[2]   = {-1, -1};
1907*35238bceSAndroid Build Coastguard Worker             glw::GLint written        = -1;
1908*35238bceSAndroid Build Coastguard Worker 
1909*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx,
1910*35238bceSAndroid Build Coastguard Worker                                     DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1911*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1912*35238bceSAndroid Build Coastguard Worker 
1913*35238bceSAndroid Build Coastguard Worker             numActiveResources            = retBuffer[0];
1914*35238bceSAndroid Build Coastguard Worker             expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1915*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources
1916*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1917*35238bceSAndroid Build Coastguard Worker 
1918*35238bceSAndroid Build Coastguard Worker             if (written == -1 || retBuffer[0] == -1)
1919*35238bceSAndroid Build Coastguard Worker             {
1920*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1921*35238bceSAndroid Build Coastguard Worker                                    << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value"
1922*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1923*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1924*35238bceSAndroid Build Coastguard Worker                 continue;
1925*35238bceSAndroid Build Coastguard Worker             }
1926*35238bceSAndroid Build Coastguard Worker             else if (retBuffer[1] != -1)
1927*35238bceSAndroid Build Coastguard Worker             {
1928*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1929*35238bceSAndroid Build Coastguard Worker                                    << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values"
1930*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1931*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1932*35238bceSAndroid Build Coastguard Worker                 continue;
1933*35238bceSAndroid Build Coastguard Worker             }
1934*35238bceSAndroid Build Coastguard Worker             else if (retBuffer[0] < 0)
1935*35238bceSAndroid Build Coastguard Worker             {
1936*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0"
1937*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1938*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1939*35238bceSAndroid Build Coastguard Worker                 continue;
1940*35238bceSAndroid Build Coastguard Worker             }
1941*35238bceSAndroid Build Coastguard Worker         }
1942*35238bceSAndroid Build Coastguard Worker 
1943*35238bceSAndroid Build Coastguard Worker         // query block variable information
1944*35238bceSAndroid Build Coastguard Worker 
1945*35238bceSAndroid Build Coastguard Worker         {
1946*35238bceSAndroid Build Coastguard Worker             const glw::GLenum props[] = {GL_ACTIVE_VARIABLES};
1947*35238bceSAndroid Build Coastguard Worker             std::vector<glw::GLint> activeVariableIndices(
1948*35238bceSAndroid Build Coastguard Worker                 numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1949*35238bceSAndroid Build Coastguard Worker             glw::GLint written = -1;
1950*35238bceSAndroid Build Coastguard Worker 
1951*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx,
1952*35238bceSAndroid Build Coastguard Worker                                     DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(),
1953*35238bceSAndroid Build Coastguard Worker                                     &written, &activeVariableIndices[0]);
1954*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1955*35238bceSAndroid Build Coastguard Worker 
1956*35238bceSAndroid Build Coastguard Worker             if (written == -1)
1957*35238bceSAndroid Build Coastguard Worker             {
1958*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1959*35238bceSAndroid Build Coastguard Worker                                    << "Error, Query for GL_ACTIVE_VARIABLES did not return any values"
1960*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1961*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1962*35238bceSAndroid Build Coastguard Worker                 continue;
1963*35238bceSAndroid Build Coastguard Worker             }
1964*35238bceSAndroid Build Coastguard Worker             else if (written != numActiveResources)
1965*35238bceSAndroid Build Coastguard Worker             {
1966*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1967*35238bceSAndroid Build Coastguard Worker                                    << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values"
1968*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1969*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
1970*35238bceSAndroid Build Coastguard Worker                                         "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1971*35238bceSAndroid Build Coastguard Worker                 continue;
1972*35238bceSAndroid Build Coastguard Worker             }
1973*35238bceSAndroid Build Coastguard Worker             else if (activeVariableIndices.back() != -1)
1974*35238bceSAndroid Build Coastguard Worker             {
1975*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
1976*35238bceSAndroid Build Coastguard Worker                                    << "Error, GL_ACTIVE_VARIABLES query return buffer trailing guard value was "
1977*35238bceSAndroid Build Coastguard Worker                                       "modified, getProgramResourceiv returned more than NUM_ACTIVE_VARIABLES values"
1978*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
1979*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1980*35238bceSAndroid Build Coastguard Worker                 continue;
1981*35238bceSAndroid Build Coastguard Worker             }
1982*35238bceSAndroid Build Coastguard Worker 
1983*35238bceSAndroid Build Coastguard Worker             // log indices
1984*35238bceSAndroid Build Coastguard Worker             {
1985*35238bceSAndroid Build Coastguard Worker                 tcu::MessageBuilder builder(&m_testCtx.getLog());
1986*35238bceSAndroid Build Coastguard Worker 
1987*35238bceSAndroid Build Coastguard Worker                 builder << "Active variable indices: {";
1988*35238bceSAndroid Build Coastguard Worker                 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1989*35238bceSAndroid Build Coastguard Worker                 {
1990*35238bceSAndroid Build Coastguard Worker                     if (varNdx)
1991*35238bceSAndroid Build Coastguard Worker                         builder << ", ";
1992*35238bceSAndroid Build Coastguard Worker                     builder << activeVariableIndices[varNdx];
1993*35238bceSAndroid Build Coastguard Worker                 }
1994*35238bceSAndroid Build Coastguard Worker                 builder << "}" << tcu::TestLog::EndMessage;
1995*35238bceSAndroid Build Coastguard Worker             }
1996*35238bceSAndroid Build Coastguard Worker 
1997*35238bceSAndroid Build Coastguard Worker             // collect names
1998*35238bceSAndroid Build Coastguard Worker 
1999*35238bceSAndroid Build Coastguard Worker             activeResourceNames.resize(numActiveResources);
2000*35238bceSAndroid Build Coastguard Worker 
2001*35238bceSAndroid Build Coastguard Worker             for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
2002*35238bceSAndroid Build Coastguard Worker             {
2003*35238bceSAndroid Build Coastguard Worker                 const glw::GLenum nameProp = GL_NAME_LENGTH;
2004*35238bceSAndroid Build Coastguard Worker                 glw::GLint nameLength      = -1;
2005*35238bceSAndroid Build Coastguard Worker                 std::vector<char> nameBuffer;
2006*35238bceSAndroid Build Coastguard Worker 
2007*35238bceSAndroid Build Coastguard Worker                 written = -1;
2008*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue,
2009*35238bceSAndroid Build Coastguard Worker                                         activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
2010*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
2011*35238bceSAndroid Build Coastguard Worker 
2012*35238bceSAndroid Build Coastguard Worker                 if (nameLength <= 0 || written <= 0)
2013*35238bceSAndroid Build Coastguard Worker                 {
2014*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed"
2015*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2016*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2017*35238bceSAndroid Build Coastguard Worker                     continue;
2018*35238bceSAndroid Build Coastguard Worker                 }
2019*35238bceSAndroid Build Coastguard Worker 
2020*35238bceSAndroid Build Coastguard Worker                 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
2021*35238bceSAndroid Build Coastguard Worker                 written = -1;
2022*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue,
2023*35238bceSAndroid Build Coastguard Worker                                           activeVariableIndices[varNdx], nameLength + 1, &written, &nameBuffer[0]);
2024*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
2025*35238bceSAndroid Build Coastguard Worker 
2026*35238bceSAndroid Build Coastguard Worker                 if (written <= 0)
2027*35238bceSAndroid Build Coastguard Worker                 {
2028*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written"
2029*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2030*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
2031*35238bceSAndroid Build Coastguard Worker                     continue;
2032*35238bceSAndroid Build Coastguard Worker                 }
2033*35238bceSAndroid Build Coastguard Worker                 else if (written > nameLength)
2034*35238bceSAndroid Build Coastguard Worker                 {
2035*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message
2036*35238bceSAndroid Build Coastguard Worker                                        << "Error, name query failed, query returned too much data"
2037*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2038*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
2039*35238bceSAndroid Build Coastguard Worker                     continue;
2040*35238bceSAndroid Build Coastguard Worker                 }
2041*35238bceSAndroid Build Coastguard Worker 
2042*35238bceSAndroid Build Coastguard Worker                 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
2043*35238bceSAndroid Build Coastguard Worker             }
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker             // log collected names
2046*35238bceSAndroid Build Coastguard Worker             {
2047*35238bceSAndroid Build Coastguard Worker                 tcu::MessageBuilder builder(&m_testCtx.getLog());
2048*35238bceSAndroid Build Coastguard Worker 
2049*35238bceSAndroid Build Coastguard Worker                 builder << "Active variables:\n";
2050*35238bceSAndroid Build Coastguard Worker                 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
2051*35238bceSAndroid Build Coastguard Worker                     builder << "\t" << activeResourceNames[varNdx] << "\n";
2052*35238bceSAndroid Build Coastguard Worker                 builder << tcu::TestLog::EndMessage;
2053*35238bceSAndroid Build Coastguard Worker             }
2054*35238bceSAndroid Build Coastguard Worker         }
2055*35238bceSAndroid Build Coastguard Worker 
2056*35238bceSAndroid Build Coastguard Worker         // verify names
2057*35238bceSAndroid Build Coastguard Worker         {
2058*35238bceSAndroid Build Coastguard Worker             glu::InterfaceBlock *block  = DE_NULL;
2059*35238bceSAndroid Build Coastguard Worker             const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
2060*35238bceSAndroid Build Coastguard Worker             std::vector<std::string> referenceList;
2061*35238bceSAndroid Build Coastguard Worker 
2062*35238bceSAndroid Build Coastguard Worker             for (int interfaceNdx = 0;
2063*35238bceSAndroid Build Coastguard Worker                  interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size();
2064*35238bceSAndroid Build Coastguard Worker                  ++interfaceNdx)
2065*35238bceSAndroid Build Coastguard Worker             {
2066*35238bceSAndroid Build Coastguard Worker                 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName ==
2067*35238bceSAndroid Build Coastguard Worker                     blockName)
2068*35238bceSAndroid Build Coastguard Worker                 {
2069*35238bceSAndroid Build Coastguard Worker                     block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
2070*35238bceSAndroid Build Coastguard Worker                     break;
2071*35238bceSAndroid Build Coastguard Worker                 }
2072*35238bceSAndroid Build Coastguard Worker             }
2073*35238bceSAndroid Build Coastguard Worker 
2074*35238bceSAndroid Build Coastguard Worker             if (!block)
2075*35238bceSAndroid Build Coastguard Worker                 throw tcu::InternalError("could not find block referenced in the reference resource list");
2076*35238bceSAndroid Build Coastguard Worker 
2077*35238bceSAndroid Build Coastguard Worker             // generate reference list
2078*35238bceSAndroid Build Coastguard Worker 
2079*35238bceSAndroid Build Coastguard Worker             referenceList = getProgramInterfaceBlockMemberResourceList(*block);
2080*35238bceSAndroid Build Coastguard Worker             {
2081*35238bceSAndroid Build Coastguard Worker                 tcu::MessageBuilder builder(&m_testCtx.getLog());
2082*35238bceSAndroid Build Coastguard Worker 
2083*35238bceSAndroid Build Coastguard Worker                 builder << "Expected variable names:\n";
2084*35238bceSAndroid Build Coastguard Worker                 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
2085*35238bceSAndroid Build Coastguard Worker                     builder << "\t" << referenceList[varNdx] << "\n";
2086*35238bceSAndroid Build Coastguard Worker                 builder << tcu::TestLog::EndMessage;
2087*35238bceSAndroid Build Coastguard Worker             }
2088*35238bceSAndroid Build Coastguard Worker 
2089*35238bceSAndroid Build Coastguard Worker             // compare lists
2090*35238bceSAndroid Build Coastguard Worker             {
2091*35238bceSAndroid Build Coastguard Worker                 bool listsIdentical = true;
2092*35238bceSAndroid Build Coastguard Worker 
2093*35238bceSAndroid Build Coastguard Worker                 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
2094*35238bceSAndroid Build Coastguard Worker                 {
2095*35238bceSAndroid Build Coastguard Worker                     if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
2096*35238bceSAndroid Build Coastguard Worker                     {
2097*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
2098*35238bceSAndroid Build Coastguard Worker                             << tcu::TestLog::Message << "Error, variable name list did not contain active variable "
2099*35238bceSAndroid Build Coastguard Worker                             << referenceList[ndx] << tcu::TestLog::EndMessage;
2100*35238bceSAndroid Build Coastguard Worker                         listsIdentical = false;
2101*35238bceSAndroid Build Coastguard Worker                     }
2102*35238bceSAndroid Build Coastguard Worker                 }
2103*35238bceSAndroid Build Coastguard Worker 
2104*35238bceSAndroid Build Coastguard Worker                 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
2105*35238bceSAndroid Build Coastguard Worker                 {
2106*35238bceSAndroid Build Coastguard Worker                     if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2107*35238bceSAndroid Build Coastguard Worker                     {
2108*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
2109*35238bceSAndroid Build Coastguard Worker                             << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \""
2110*35238bceSAndroid Build Coastguard Worker                             << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2111*35238bceSAndroid Build Coastguard Worker                         listsIdentical = false;
2112*35238bceSAndroid Build Coastguard Worker                     }
2113*35238bceSAndroid Build Coastguard Worker                 }
2114*35238bceSAndroid Build Coastguard Worker 
2115*35238bceSAndroid Build Coastguard Worker                 if (listsIdentical)
2116*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2117*35238bceSAndroid Build Coastguard Worker                 else
2118*35238bceSAndroid Build Coastguard Worker                 {
2119*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list"
2120*35238bceSAndroid Build Coastguard Worker                                        << tcu::TestLog::EndMessage;
2121*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2122*35238bceSAndroid Build Coastguard Worker                     continue;
2123*35238bceSAndroid Build Coastguard Worker                 }
2124*35238bceSAndroid Build Coastguard Worker             }
2125*35238bceSAndroid Build Coastguard Worker         }
2126*35238bceSAndroid Build Coastguard Worker     }
2127*35238bceSAndroid Build Coastguard Worker 
2128*35238bceSAndroid Build Coastguard Worker     // Max num active variables
2129*35238bceSAndroid Build Coastguard Worker     {
2130*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2131*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl         = m_context.getRenderContext().getFunctions();
2132*35238bceSAndroid Build Coastguard Worker         glw::GLint maxNumActiveVariables = -1;
2133*35238bceSAndroid Build Coastguard Worker 
2134*35238bceSAndroid Build Coastguard Worker         gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES,
2135*35238bceSAndroid Build Coastguard Worker                                  &maxNumActiveVariables);
2136*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2137*35238bceSAndroid Build Coastguard Worker 
2138*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables
2139*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2140*35238bceSAndroid Build Coastguard Worker 
2141*35238bceSAndroid Build Coastguard Worker         if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2142*35238bceSAndroid Build Coastguard Worker         {
2143*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES"
2144*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2145*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2146*35238bceSAndroid Build Coastguard Worker         }
2147*35238bceSAndroid Build Coastguard Worker         else
2148*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2149*35238bceSAndroid Build Coastguard Worker     }
2150*35238bceSAndroid Build Coastguard Worker 
2151*35238bceSAndroid Build Coastguard Worker     return STOP;
2152*35238bceSAndroid Build Coastguard Worker }
2153*35238bceSAndroid Build Coastguard Worker 
2154*35238bceSAndroid Build Coastguard Worker class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2155*35238bceSAndroid Build Coastguard Worker {
2156*35238bceSAndroid Build Coastguard Worker public:
2157*35238bceSAndroid Build Coastguard Worker     InterfaceBlockDataSizeTestCase(Context &context, const char *name, const char *description, glu::Storage storage,
2158*35238bceSAndroid Build Coastguard Worker                                    CaseType caseType);
2159*35238bceSAndroid Build Coastguard Worker 
2160*35238bceSAndroid Build Coastguard Worker private:
2161*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2162*35238bceSAndroid Build Coastguard Worker     int getBlockMinDataSize(const std::string &blockName) const;
2163*35238bceSAndroid Build Coastguard Worker     int getBlockMinDataSize(const glu::InterfaceBlock &block) const;
2164*35238bceSAndroid Build Coastguard Worker };
2165*35238bceSAndroid Build Coastguard Worker 
InterfaceBlockDataSizeTestCase(Context & context,const char * name,const char * description,glu::Storage storage,CaseType caseType)2166*35238bceSAndroid Build Coastguard Worker InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase(Context &context, const char *name,
2167*35238bceSAndroid Build Coastguard Worker                                                                const char *description, glu::Storage storage,
2168*35238bceSAndroid Build Coastguard Worker                                                                CaseType caseType)
2169*35238bceSAndroid Build Coastguard Worker     : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2170*35238bceSAndroid Build Coastguard Worker {
2171*35238bceSAndroid Build Coastguard Worker }
2172*35238bceSAndroid Build Coastguard Worker 
iterate(void)2173*35238bceSAndroid Build Coastguard Worker InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate(void)
2174*35238bceSAndroid Build Coastguard Worker {
2175*35238bceSAndroid Build Coastguard Worker     const ProgramInterface programInterface =
2176*35238bceSAndroid Build Coastguard Worker         (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2177*35238bceSAndroid Build Coastguard Worker         (m_storage == glu::STORAGE_BUFFER)  ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2178*35238bceSAndroid Build Coastguard Worker                                               (PROGRAMINTERFACE_LAST);
2179*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2180*35238bceSAndroid Build Coastguard Worker     const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2181*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2182*35238bceSAndroid Build Coastguard Worker 
2183*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2184*35238bceSAndroid Build Coastguard Worker 
2185*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2186*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2187*35238bceSAndroid Build Coastguard Worker 
2188*35238bceSAndroid Build Coastguard Worker     // Verify all blocks
2189*35238bceSAndroid Build Coastguard Worker     for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2190*35238bceSAndroid Build Coastguard Worker     {
2191*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2192*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2193*35238bceSAndroid Build Coastguard Worker         const glw::GLuint resourceNdx =
2194*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2195*35238bceSAndroid Build Coastguard Worker         const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2196*35238bceSAndroid Build Coastguard Worker         glw::GLint queryDataSize      = -1;
2197*35238bceSAndroid Build Coastguard Worker 
2198*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2199*35238bceSAndroid Build Coastguard Worker 
2200*35238bceSAndroid Build Coastguard Worker         if (resourceNdx == GL_INVALID_INDEX)
2201*35238bceSAndroid Build Coastguard Worker         {
2202*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
2203*35238bceSAndroid Build Coastguard Worker                                << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \""
2204*35238bceSAndroid Build Coastguard Worker                                << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2205*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2206*35238bceSAndroid Build Coastguard Worker             continue;
2207*35238bceSAndroid Build Coastguard Worker         }
2208*35238bceSAndroid Build Coastguard Worker 
2209*35238bceSAndroid Build Coastguard Worker         // query
2210*35238bceSAndroid Build Coastguard Worker         {
2211*35238bceSAndroid Build Coastguard Worker             const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2212*35238bceSAndroid Build Coastguard Worker 
2213*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL,
2214*35238bceSAndroid Build Coastguard Worker                                     &queryDataSize);
2215*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2216*35238bceSAndroid Build Coastguard Worker         }
2217*35238bceSAndroid Build Coastguard Worker 
2218*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2219*35238bceSAndroid Build Coastguard Worker                            << "Buffer data size with tight packing: " << expectedMinDataSize
2220*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2221*35238bceSAndroid Build Coastguard Worker 
2222*35238bceSAndroid Build Coastguard Worker         if (queryDataSize < expectedMinDataSize)
2223*35238bceSAndroid Build Coastguard Worker         {
2224*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size"
2225*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2226*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2227*35238bceSAndroid Build Coastguard Worker             continue;
2228*35238bceSAndroid Build Coastguard Worker         }
2229*35238bceSAndroid Build Coastguard Worker         else
2230*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2231*35238bceSAndroid Build Coastguard Worker     }
2232*35238bceSAndroid Build Coastguard Worker 
2233*35238bceSAndroid Build Coastguard Worker     return STOP;
2234*35238bceSAndroid Build Coastguard Worker }
2235*35238bceSAndroid Build Coastguard Worker 
getBlockMinDataSize(const std::string & blockFullName) const2236*35238bceSAndroid Build Coastguard Worker int InterfaceBlockDataSizeTestCase::getBlockMinDataSize(const std::string &blockFullName) const
2237*35238bceSAndroid Build Coastguard Worker {
2238*35238bceSAndroid Build Coastguard Worker     const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2239*35238bceSAndroid Build Coastguard Worker 
2240*35238bceSAndroid Build Coastguard Worker     for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size();
2241*35238bceSAndroid Build Coastguard Worker          ++interfaceNdx)
2242*35238bceSAndroid Build Coastguard Worker     {
2243*35238bceSAndroid Build Coastguard Worker         if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2244*35238bceSAndroid Build Coastguard Worker             m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2245*35238bceSAndroid Build Coastguard Worker             return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2246*35238bceSAndroid Build Coastguard Worker     }
2247*35238bceSAndroid Build Coastguard Worker 
2248*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
2249*35238bceSAndroid Build Coastguard Worker     return -1;
2250*35238bceSAndroid Build Coastguard Worker }
2251*35238bceSAndroid Build Coastguard Worker 
2252*35238bceSAndroid Build Coastguard Worker class AtomicCounterCase : public TestCase
2253*35238bceSAndroid Build Coastguard Worker {
2254*35238bceSAndroid Build Coastguard Worker public:
2255*35238bceSAndroid Build Coastguard Worker     AtomicCounterCase(Context &context, const char *name, const char *description);
2256*35238bceSAndroid Build Coastguard Worker     ~AtomicCounterCase(void);
2257*35238bceSAndroid Build Coastguard Worker 
2258*35238bceSAndroid Build Coastguard Worker private:
2259*35238bceSAndroid Build Coastguard Worker     void init(void);
2260*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2261*35238bceSAndroid Build Coastguard Worker 
2262*35238bceSAndroid Build Coastguard Worker protected:
2263*35238bceSAndroid Build Coastguard Worker     int getNumAtomicCounterBuffers(void) const;
2264*35238bceSAndroid Build Coastguard Worker     int getMaxNumActiveVariables(void) const;
2265*35238bceSAndroid Build Coastguard Worker     int getBufferVariableCount(int binding) const;
2266*35238bceSAndroid Build Coastguard Worker     int getBufferMinimumDataSize(int binding) const;
2267*35238bceSAndroid Build Coastguard Worker 
2268*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_program;
2269*35238bceSAndroid Build Coastguard Worker };
2270*35238bceSAndroid Build Coastguard Worker 
AtomicCounterCase(Context & context,const char * name,const char * description)2271*35238bceSAndroid Build Coastguard Worker AtomicCounterCase::AtomicCounterCase(Context &context, const char *name, const char *description)
2272*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
2273*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2274*35238bceSAndroid Build Coastguard Worker {
2275*35238bceSAndroid Build Coastguard Worker }
2276*35238bceSAndroid Build Coastguard Worker 
~AtomicCounterCase(void)2277*35238bceSAndroid Build Coastguard Worker AtomicCounterCase::~AtomicCounterCase(void)
2278*35238bceSAndroid Build Coastguard Worker {
2279*35238bceSAndroid Build Coastguard Worker     deinit();
2280*35238bceSAndroid Build Coastguard Worker }
2281*35238bceSAndroid Build Coastguard Worker 
init(void)2282*35238bceSAndroid Build Coastguard Worker void AtomicCounterCase::init(void)
2283*35238bceSAndroid Build Coastguard Worker {
2284*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Shader *shader;
2285*35238bceSAndroid Build Coastguard Worker     glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2286*35238bceSAndroid Build Coastguard Worker 
2287*35238bceSAndroid Build Coastguard Worker     m_program = new ProgramInterfaceDefinition::Program();
2288*35238bceSAndroid Build Coastguard Worker     shader    = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
2289*35238bceSAndroid Build Coastguard Worker 
2290*35238bceSAndroid Build Coastguard Worker     {
2291*35238bceSAndroid Build Coastguard Worker         glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST),
2292*35238bceSAndroid Build Coastguard Worker                                       "binding1_counter1", glu::STORAGE_UNIFORM);
2293*35238bceSAndroid Build Coastguard Worker         decl.layout.binding = 1;
2294*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().variables.push_back(decl);
2295*35238bceSAndroid Build Coastguard Worker     }
2296*35238bceSAndroid Build Coastguard Worker     {
2297*35238bceSAndroid Build Coastguard Worker         glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST),
2298*35238bceSAndroid Build Coastguard Worker                                       "binding1_counter2", glu::STORAGE_UNIFORM);
2299*35238bceSAndroid Build Coastguard Worker         decl.layout.binding = 1;
2300*35238bceSAndroid Build Coastguard Worker         decl.layout.offset  = 8;
2301*35238bceSAndroid Build Coastguard Worker 
2302*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().variables.push_back(decl);
2303*35238bceSAndroid Build Coastguard Worker     }
2304*35238bceSAndroid Build Coastguard Worker     {
2305*35238bceSAndroid Build Coastguard Worker         glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST),
2306*35238bceSAndroid Build Coastguard Worker                                       "binding2_counter1", glu::STORAGE_UNIFORM);
2307*35238bceSAndroid Build Coastguard Worker         decl.layout.binding = 2;
2308*35238bceSAndroid Build Coastguard Worker         shader->getDefaultBlock().variables.push_back(decl);
2309*35238bceSAndroid Build Coastguard Worker     }
2310*35238bceSAndroid Build Coastguard Worker 
2311*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_program->isValid());
2312*35238bceSAndroid Build Coastguard Worker }
2313*35238bceSAndroid Build Coastguard Worker 
deinit(void)2314*35238bceSAndroid Build Coastguard Worker void AtomicCounterCase::deinit(void)
2315*35238bceSAndroid Build Coastguard Worker {
2316*35238bceSAndroid Build Coastguard Worker     delete m_program;
2317*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
2318*35238bceSAndroid Build Coastguard Worker }
2319*35238bceSAndroid Build Coastguard Worker 
getNumAtomicCounterBuffers(void) const2320*35238bceSAndroid Build Coastguard Worker int AtomicCounterCase::getNumAtomicCounterBuffers(void) const
2321*35238bceSAndroid Build Coastguard Worker {
2322*35238bceSAndroid Build Coastguard Worker     std::set<int> buffers;
2323*35238bceSAndroid Build Coastguard Worker 
2324*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2325*35238bceSAndroid Build Coastguard Worker     {
2326*35238bceSAndroid Build Coastguard Worker         if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2327*35238bceSAndroid Build Coastguard Worker             glu::isDataTypeAtomicCounter(
2328*35238bceSAndroid Build Coastguard Worker                 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2329*35238bceSAndroid Build Coastguard Worker         {
2330*35238bceSAndroid Build Coastguard Worker             buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2331*35238bceSAndroid Build Coastguard Worker         }
2332*35238bceSAndroid Build Coastguard Worker     }
2333*35238bceSAndroid Build Coastguard Worker 
2334*35238bceSAndroid Build Coastguard Worker     return (int)buffers.size();
2335*35238bceSAndroid Build Coastguard Worker }
2336*35238bceSAndroid Build Coastguard Worker 
getMaxNumActiveVariables(void) const2337*35238bceSAndroid Build Coastguard Worker int AtomicCounterCase::getMaxNumActiveVariables(void) const
2338*35238bceSAndroid Build Coastguard Worker {
2339*35238bceSAndroid Build Coastguard Worker     int maxVars = 0;
2340*35238bceSAndroid Build Coastguard Worker     std::map<int, int> numBufferVars;
2341*35238bceSAndroid Build Coastguard Worker 
2342*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2343*35238bceSAndroid Build Coastguard Worker     {
2344*35238bceSAndroid Build Coastguard Worker         if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2345*35238bceSAndroid Build Coastguard Worker             glu::isDataTypeAtomicCounter(
2346*35238bceSAndroid Build Coastguard Worker                 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2347*35238bceSAndroid Build Coastguard Worker         {
2348*35238bceSAndroid Build Coastguard Worker             const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2349*35238bceSAndroid Build Coastguard Worker 
2350*35238bceSAndroid Build Coastguard Worker             if (numBufferVars.find(binding) == numBufferVars.end())
2351*35238bceSAndroid Build Coastguard Worker                 numBufferVars[binding] = 1;
2352*35238bceSAndroid Build Coastguard Worker             else
2353*35238bceSAndroid Build Coastguard Worker                 ++numBufferVars[binding];
2354*35238bceSAndroid Build Coastguard Worker         }
2355*35238bceSAndroid Build Coastguard Worker     }
2356*35238bceSAndroid Build Coastguard Worker 
2357*35238bceSAndroid Build Coastguard Worker     for (std::map<int, int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2358*35238bceSAndroid Build Coastguard Worker         maxVars = de::max(maxVars, it->second);
2359*35238bceSAndroid Build Coastguard Worker 
2360*35238bceSAndroid Build Coastguard Worker     return maxVars;
2361*35238bceSAndroid Build Coastguard Worker }
2362*35238bceSAndroid Build Coastguard Worker 
getBufferVariableCount(int binding) const2363*35238bceSAndroid Build Coastguard Worker int AtomicCounterCase::getBufferVariableCount(int binding) const
2364*35238bceSAndroid Build Coastguard Worker {
2365*35238bceSAndroid Build Coastguard Worker     int numVars = 0;
2366*35238bceSAndroid Build Coastguard Worker 
2367*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2368*35238bceSAndroid Build Coastguard Worker     {
2369*35238bceSAndroid Build Coastguard Worker         if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2370*35238bceSAndroid Build Coastguard Worker             glu::isDataTypeAtomicCounter(
2371*35238bceSAndroid Build Coastguard Worker                 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2372*35238bceSAndroid Build Coastguard Worker             m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2373*35238bceSAndroid Build Coastguard Worker             ++numVars;
2374*35238bceSAndroid Build Coastguard Worker     }
2375*35238bceSAndroid Build Coastguard Worker 
2376*35238bceSAndroid Build Coastguard Worker     return numVars;
2377*35238bceSAndroid Build Coastguard Worker }
2378*35238bceSAndroid Build Coastguard Worker 
getBufferMinimumDataSize(int binding) const2379*35238bceSAndroid Build Coastguard Worker int AtomicCounterCase::getBufferMinimumDataSize(int binding) const
2380*35238bceSAndroid Build Coastguard Worker {
2381*35238bceSAndroid Build Coastguard Worker     int minSize       = -1;
2382*35238bceSAndroid Build Coastguard Worker     int currentOffset = 0;
2383*35238bceSAndroid Build Coastguard Worker 
2384*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2385*35238bceSAndroid Build Coastguard Worker     {
2386*35238bceSAndroid Build Coastguard Worker         if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2387*35238bceSAndroid Build Coastguard Worker             glu::isDataTypeAtomicCounter(
2388*35238bceSAndroid Build Coastguard Worker                 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2389*35238bceSAndroid Build Coastguard Worker             m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2390*35238bceSAndroid Build Coastguard Worker         {
2391*35238bceSAndroid Build Coastguard Worker             const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ?
2392*35238bceSAndroid Build Coastguard Worker                                        (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) :
2393*35238bceSAndroid Build Coastguard Worker                                        (currentOffset);
2394*35238bceSAndroid Build Coastguard Worker             currentOffset        = thisOffset + 4;
2395*35238bceSAndroid Build Coastguard Worker 
2396*35238bceSAndroid Build Coastguard Worker             minSize = de::max(minSize, thisOffset + 4);
2397*35238bceSAndroid Build Coastguard Worker         }
2398*35238bceSAndroid Build Coastguard Worker     }
2399*35238bceSAndroid Build Coastguard Worker 
2400*35238bceSAndroid Build Coastguard Worker     return minSize;
2401*35238bceSAndroid Build Coastguard Worker }
2402*35238bceSAndroid Build Coastguard Worker 
2403*35238bceSAndroid Build Coastguard Worker class AtomicCounterResourceListCase : public AtomicCounterCase
2404*35238bceSAndroid Build Coastguard Worker {
2405*35238bceSAndroid Build Coastguard Worker public:
2406*35238bceSAndroid Build Coastguard Worker     AtomicCounterResourceListCase(Context &context, const char *name, const char *description);
2407*35238bceSAndroid Build Coastguard Worker 
2408*35238bceSAndroid Build Coastguard Worker private:
2409*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2410*35238bceSAndroid Build Coastguard Worker };
2411*35238bceSAndroid Build Coastguard Worker 
AtomicCounterResourceListCase(Context & context,const char * name,const char * description)2412*35238bceSAndroid Build Coastguard Worker AtomicCounterResourceListCase::AtomicCounterResourceListCase(Context &context, const char *name,
2413*35238bceSAndroid Build Coastguard Worker                                                              const char *description)
2414*35238bceSAndroid Build Coastguard Worker     : AtomicCounterCase(context, name, description)
2415*35238bceSAndroid Build Coastguard Worker {
2416*35238bceSAndroid Build Coastguard Worker }
2417*35238bceSAndroid Build Coastguard Worker 
iterate(void)2418*35238bceSAndroid Build Coastguard Worker AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate(void)
2419*35238bceSAndroid Build Coastguard Worker {
2420*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2421*35238bceSAndroid Build Coastguard Worker 
2422*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2423*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2424*35238bceSAndroid Build Coastguard Worker 
2425*35238bceSAndroid Build Coastguard Worker     {
2426*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2427*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl             = m_context.getRenderContext().getFunctions();
2428*35238bceSAndroid Build Coastguard Worker         glw::GLint numActiveResources        = -1;
2429*35238bceSAndroid Build Coastguard Worker         const int numExpectedActiveResources = 2; // 2 buffer bindings
2430*35238bceSAndroid Build Coastguard Worker 
2431*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting "
2432*35238bceSAndroid Build Coastguard Worker                            << numExpectedActiveResources << tcu::TestLog::EndMessage;
2433*35238bceSAndroid Build Coastguard Worker 
2434*35238bceSAndroid Build Coastguard Worker         gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES,
2435*35238bceSAndroid Build Coastguard Worker                                  &numActiveResources);
2436*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2437*35238bceSAndroid Build Coastguard Worker 
2438*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources
2439*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2440*35238bceSAndroid Build Coastguard Worker 
2441*35238bceSAndroid Build Coastguard Worker         if (numActiveResources != numExpectedActiveResources)
2442*35238bceSAndroid Build Coastguard Worker         {
2443*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES"
2444*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2445*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2446*35238bceSAndroid Build Coastguard Worker         }
2447*35238bceSAndroid Build Coastguard Worker         else
2448*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2449*35238bceSAndroid Build Coastguard Worker     }
2450*35238bceSAndroid Build Coastguard Worker 
2451*35238bceSAndroid Build Coastguard Worker     return STOP;
2452*35238bceSAndroid Build Coastguard Worker }
2453*35238bceSAndroid Build Coastguard Worker 
2454*35238bceSAndroid Build Coastguard Worker class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2455*35238bceSAndroid Build Coastguard Worker {
2456*35238bceSAndroid Build Coastguard Worker public:
2457*35238bceSAndroid Build Coastguard Worker     AtomicCounterActiveVariablesCase(Context &context, const char *name, const char *description);
2458*35238bceSAndroid Build Coastguard Worker 
2459*35238bceSAndroid Build Coastguard Worker private:
2460*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2461*35238bceSAndroid Build Coastguard Worker };
2462*35238bceSAndroid Build Coastguard Worker 
AtomicCounterActiveVariablesCase(Context & context,const char * name,const char * description)2463*35238bceSAndroid Build Coastguard Worker AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase(Context &context, const char *name,
2464*35238bceSAndroid Build Coastguard Worker                                                                    const char *description)
2465*35238bceSAndroid Build Coastguard Worker     : AtomicCounterCase(context, name, description)
2466*35238bceSAndroid Build Coastguard Worker {
2467*35238bceSAndroid Build Coastguard Worker }
2468*35238bceSAndroid Build Coastguard Worker 
iterate(void)2469*35238bceSAndroid Build Coastguard Worker AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate(void)
2470*35238bceSAndroid Build Coastguard Worker {
2471*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2472*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2473*35238bceSAndroid Build Coastguard Worker     const int numAtomicBuffers              = getNumAtomicCounterBuffers();
2474*35238bceSAndroid Build Coastguard Worker     const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2475*35238bceSAndroid Build Coastguard Worker 
2476*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2477*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2478*35238bceSAndroid Build Coastguard Worker 
2479*35238bceSAndroid Build Coastguard Worker     // check active variables
2480*35238bceSAndroid Build Coastguard Worker     {
2481*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2482*35238bceSAndroid Build Coastguard Worker         glw::GLint queryActiveResources       = -1;
2483*35238bceSAndroid Build Coastguard Worker         glw::GLint queryMaxNumActiveVariables = -1;
2484*35238bceSAndroid Build Coastguard Worker 
2485*35238bceSAndroid Build Coastguard Worker         gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES,
2486*35238bceSAndroid Build Coastguard Worker                                  &queryActiveResources);
2487*35238bceSAndroid Build Coastguard Worker         gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES,
2488*35238bceSAndroid Build Coastguard Worker                                  &queryMaxNumActiveVariables);
2489*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2490*35238bceSAndroid Build Coastguard Worker 
2491*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2492*35238bceSAndroid Build Coastguard Worker                            << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2493*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2494*35238bceSAndroid Build Coastguard Worker 
2495*35238bceSAndroid Build Coastguard Worker         if (queryActiveResources != numAtomicBuffers)
2496*35238bceSAndroid Build Coastguard Worker         {
2497*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected "
2498*35238bceSAndroid Build Coastguard Worker                                << numAtomicBuffers << tcu::TestLog::EndMessage;
2499*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2500*35238bceSAndroid Build Coastguard Worker         }
2501*35238bceSAndroid Build Coastguard Worker 
2502*35238bceSAndroid Build Coastguard Worker         if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2503*35238bceSAndroid Build Coastguard Worker         {
2504*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
2505*35238bceSAndroid Build Coastguard Worker                                << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected "
2506*35238bceSAndroid Build Coastguard Worker                                << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2507*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2508*35238bceSAndroid Build Coastguard Worker         }
2509*35238bceSAndroid Build Coastguard Worker     }
2510*35238bceSAndroid Build Coastguard Worker 
2511*35238bceSAndroid Build Coastguard Worker     // Check each buffer
2512*35238bceSAndroid Build Coastguard Worker     for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2513*35238bceSAndroid Build Coastguard Worker     {
2514*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Resource",
2515*35238bceSAndroid Build Coastguard Worker                                             "Resource index " + de::toString(bufferNdx));
2516*35238bceSAndroid Build Coastguard Worker         std::vector<glw::GLint> activeVariables;
2517*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> memberNames;
2518*35238bceSAndroid Build Coastguard Worker 
2519*35238bceSAndroid Build Coastguard Worker         // Find active variables
2520*35238bceSAndroid Build Coastguard Worker         {
2521*35238bceSAndroid Build Coastguard Worker             const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2522*35238bceSAndroid Build Coastguard Worker             const glw::GLenum activeVariablesProp    = GL_ACTIVE_VARIABLES;
2523*35238bceSAndroid Build Coastguard Worker             glw::GLint numActiveVariables            = -2;
2524*35238bceSAndroid Build Coastguard Worker             glw::GLint written                       = -1;
2525*35238bceSAndroid Build Coastguard Worker 
2526*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1,
2527*35238bceSAndroid Build Coastguard Worker                                     &numActiveVariablesProp, 1, &written, &numActiveVariables);
2528*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2529*35238bceSAndroid Build Coastguard Worker 
2530*35238bceSAndroid Build Coastguard Worker             if (numActiveVariables <= 0)
2531*35238bceSAndroid Build Coastguard Worker             {
2532*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
2533*35238bceSAndroid Build Coastguard Worker                                    << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables
2534*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2535*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2536*35238bceSAndroid Build Coastguard Worker                 continue;
2537*35238bceSAndroid Build Coastguard Worker             }
2538*35238bceSAndroid Build Coastguard Worker 
2539*35238bceSAndroid Build Coastguard Worker             if (written <= 0)
2540*35238bceSAndroid Build Coastguard Worker             {
2541*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
2542*35238bceSAndroid Build Coastguard Worker                                    << "Error, query for NUM_ACTIVE_VARIABLES returned no values"
2543*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2544*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2545*35238bceSAndroid Build Coastguard Worker                 continue;
2546*35238bceSAndroid Build Coastguard Worker             }
2547*35238bceSAndroid Build Coastguard Worker 
2548*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables
2549*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2550*35238bceSAndroid Build Coastguard Worker 
2551*35238bceSAndroid Build Coastguard Worker             written = -1;
2552*35238bceSAndroid Build Coastguard Worker             activeVariables.resize(numActiveVariables + 1, -2);
2553*35238bceSAndroid Build Coastguard Worker 
2554*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp,
2555*35238bceSAndroid Build Coastguard Worker                                     numActiveVariables, &written, &activeVariables[0]);
2556*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2557*35238bceSAndroid Build Coastguard Worker 
2558*35238bceSAndroid Build Coastguard Worker             if (written != numActiveVariables)
2559*35238bceSAndroid Build Coastguard Worker             {
2560*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
2561*35238bceSAndroid Build Coastguard Worker                                    << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = "
2562*35238bceSAndroid Build Coastguard Worker                                    << numActiveVariables << ", query returned " << written << " values"
2563*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2564*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2565*35238bceSAndroid Build Coastguard Worker                 continue;
2566*35238bceSAndroid Build Coastguard Worker             }
2567*35238bceSAndroid Build Coastguard Worker 
2568*35238bceSAndroid Build Coastguard Worker             if (activeVariables.back() != -2)
2569*35238bceSAndroid Build Coastguard Worker             {
2570*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
2571*35238bceSAndroid Build Coastguard Worker                                    << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds"
2572*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2573*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2574*35238bceSAndroid Build Coastguard Worker                 continue;
2575*35238bceSAndroid Build Coastguard Worker             }
2576*35238bceSAndroid Build Coastguard Worker 
2577*35238bceSAndroid Build Coastguard Worker             activeVariables.pop_back();
2578*35238bceSAndroid Build Coastguard Worker         }
2579*35238bceSAndroid Build Coastguard Worker 
2580*35238bceSAndroid Build Coastguard Worker         // log indices
2581*35238bceSAndroid Build Coastguard Worker         {
2582*35238bceSAndroid Build Coastguard Worker             tcu::MessageBuilder builder(&m_testCtx.getLog());
2583*35238bceSAndroid Build Coastguard Worker 
2584*35238bceSAndroid Build Coastguard Worker             builder << "Active variable indices: {";
2585*35238bceSAndroid Build Coastguard Worker             for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2586*35238bceSAndroid Build Coastguard Worker             {
2587*35238bceSAndroid Build Coastguard Worker                 if (varNdx)
2588*35238bceSAndroid Build Coastguard Worker                     builder << ", ";
2589*35238bceSAndroid Build Coastguard Worker                 builder << activeVariables[varNdx];
2590*35238bceSAndroid Build Coastguard Worker             }
2591*35238bceSAndroid Build Coastguard Worker             builder << "}" << tcu::TestLog::EndMessage;
2592*35238bceSAndroid Build Coastguard Worker         }
2593*35238bceSAndroid Build Coastguard Worker 
2594*35238bceSAndroid Build Coastguard Worker         // collect member names
2595*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2596*35238bceSAndroid Build Coastguard Worker         {
2597*35238bceSAndroid Build Coastguard Worker             const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2598*35238bceSAndroid Build Coastguard Worker             glw::GLint nameLength            = -1;
2599*35238bceSAndroid Build Coastguard Worker             glw::GLint written               = -1;
2600*35238bceSAndroid Build Coastguard Worker             std::vector<char> nameBuf;
2601*35238bceSAndroid Build Coastguard Worker 
2602*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1,
2603*35238bceSAndroid Build Coastguard Worker                                     &written, &nameLength);
2604*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2605*35238bceSAndroid Build Coastguard Worker 
2606*35238bceSAndroid Build Coastguard Worker             if (written <= 0 || nameLength == -1)
2607*35238bceSAndroid Build Coastguard Worker             {
2608*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values"
2609*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2610*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2611*35238bceSAndroid Build Coastguard Worker                 continue;
2612*35238bceSAndroid Build Coastguard Worker             }
2613*35238bceSAndroid Build Coastguard Worker 
2614*35238bceSAndroid Build Coastguard Worker             nameBuf.resize(
2615*35238bceSAndroid Build Coastguard Worker                 nameLength + 2,
2616*35238bceSAndroid Build Coastguard Worker                 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2617*35238bceSAndroid Build Coastguard Worker             written = -1;
2618*35238bceSAndroid Build Coastguard Worker 
2619*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(),
2620*35238bceSAndroid Build Coastguard Worker                                       &written, &nameBuf[0]);
2621*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2622*35238bceSAndroid Build Coastguard Worker 
2623*35238bceSAndroid Build Coastguard Worker             if (written <= 0)
2624*35238bceSAndroid Build Coastguard Worker             {
2625*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name"
2626*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2627*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2628*35238bceSAndroid Build Coastguard Worker                 continue;
2629*35238bceSAndroid Build Coastguard Worker             }
2630*35238bceSAndroid Build Coastguard Worker 
2631*35238bceSAndroid Build Coastguard Worker             memberNames.push_back(std::string(&nameBuf[0], written));
2632*35238bceSAndroid Build Coastguard Worker         }
2633*35238bceSAndroid Build Coastguard Worker 
2634*35238bceSAndroid Build Coastguard Worker         // log names
2635*35238bceSAndroid Build Coastguard Worker         {
2636*35238bceSAndroid Build Coastguard Worker             tcu::MessageBuilder builder(&m_testCtx.getLog());
2637*35238bceSAndroid Build Coastguard Worker 
2638*35238bceSAndroid Build Coastguard Worker             builder << "Active variables:\n";
2639*35238bceSAndroid Build Coastguard Worker             for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2640*35238bceSAndroid Build Coastguard Worker             {
2641*35238bceSAndroid Build Coastguard Worker                 builder << "\t" << memberNames[varNdx] << "\n";
2642*35238bceSAndroid Build Coastguard Worker             }
2643*35238bceSAndroid Build Coastguard Worker             builder << tcu::TestLog::EndMessage;
2644*35238bceSAndroid Build Coastguard Worker         }
2645*35238bceSAndroid Build Coastguard Worker 
2646*35238bceSAndroid Build Coastguard Worker         // check names are all in the same buffer
2647*35238bceSAndroid Build Coastguard Worker         {
2648*35238bceSAndroid Build Coastguard Worker             bool bindingsValid = true;
2649*35238bceSAndroid Build Coastguard Worker 
2650*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2651*35238bceSAndroid Build Coastguard Worker 
2652*35238bceSAndroid Build Coastguard Worker             for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2653*35238bceSAndroid Build Coastguard Worker             {
2654*35238bceSAndroid Build Coastguard Worker                 int prevBinding = -1;
2655*35238bceSAndroid Build Coastguard Worker 
2656*35238bceSAndroid Build Coastguard Worker                 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size();
2657*35238bceSAndroid Build Coastguard Worker                      ++varNdx)
2658*35238bceSAndroid Build Coastguard Worker                 {
2659*35238bceSAndroid Build Coastguard Worker                     if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2660*35238bceSAndroid Build Coastguard Worker                     {
2661*35238bceSAndroid Build Coastguard Worker                         const int varBinding =
2662*35238bceSAndroid Build Coastguard Worker                             m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2663*35238bceSAndroid Build Coastguard Worker 
2664*35238bceSAndroid Build Coastguard Worker                         if (prevBinding == -1 || prevBinding == varBinding)
2665*35238bceSAndroid Build Coastguard Worker                             prevBinding = varBinding;
2666*35238bceSAndroid Build Coastguard Worker                         else
2667*35238bceSAndroid Build Coastguard Worker                             bindingsValid = false;
2668*35238bceSAndroid Build Coastguard Worker                     }
2669*35238bceSAndroid Build Coastguard Worker                 }
2670*35238bceSAndroid Build Coastguard Worker 
2671*35238bceSAndroid Build Coastguard Worker                 if (prevBinding == -1)
2672*35238bceSAndroid Build Coastguard Worker                 {
2673*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \""
2674*35238bceSAndroid Build Coastguard Worker                                        << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2675*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2676*35238bceSAndroid Build Coastguard Worker                 }
2677*35238bceSAndroid Build Coastguard Worker                 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2678*35238bceSAndroid Build Coastguard Worker                 {
2679*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected variable count for binding "
2680*35238bceSAndroid Build Coastguard Worker                                        << prevBinding << ". Expected " << getBufferVariableCount(prevBinding)
2681*35238bceSAndroid Build Coastguard Worker                                        << ", got " << (int)memberNames.size() << tcu::TestLog::EndMessage;
2682*35238bceSAndroid Build Coastguard Worker                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2683*35238bceSAndroid Build Coastguard Worker                 }
2684*35238bceSAndroid Build Coastguard Worker             }
2685*35238bceSAndroid Build Coastguard Worker 
2686*35238bceSAndroid Build Coastguard Worker             if (!bindingsValid)
2687*35238bceSAndroid Build Coastguard Worker             {
2688*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer"
2689*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2690*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2691*35238bceSAndroid Build Coastguard Worker                 continue;
2692*35238bceSAndroid Build Coastguard Worker             }
2693*35238bceSAndroid Build Coastguard Worker         }
2694*35238bceSAndroid Build Coastguard Worker     }
2695*35238bceSAndroid Build Coastguard Worker 
2696*35238bceSAndroid Build Coastguard Worker     return STOP;
2697*35238bceSAndroid Build Coastguard Worker }
2698*35238bceSAndroid Build Coastguard Worker 
2699*35238bceSAndroid Build Coastguard Worker class AtomicCounterBufferBindingCase : public AtomicCounterCase
2700*35238bceSAndroid Build Coastguard Worker {
2701*35238bceSAndroid Build Coastguard Worker public:
2702*35238bceSAndroid Build Coastguard Worker     AtomicCounterBufferBindingCase(Context &context, const char *name, const char *description);
2703*35238bceSAndroid Build Coastguard Worker 
2704*35238bceSAndroid Build Coastguard Worker private:
2705*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2706*35238bceSAndroid Build Coastguard Worker };
2707*35238bceSAndroid Build Coastguard Worker 
AtomicCounterBufferBindingCase(Context & context,const char * name,const char * description)2708*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase(Context &context, const char *name,
2709*35238bceSAndroid Build Coastguard Worker                                                                const char *description)
2710*35238bceSAndroid Build Coastguard Worker     : AtomicCounterCase(context, name, description)
2711*35238bceSAndroid Build Coastguard Worker {
2712*35238bceSAndroid Build Coastguard Worker }
2713*35238bceSAndroid Build Coastguard Worker 
iterate(void)2714*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate(void)
2715*35238bceSAndroid Build Coastguard Worker {
2716*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2717*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2718*35238bceSAndroid Build Coastguard Worker     const int numAtomicBuffers = getNumAtomicCounterBuffers();
2719*35238bceSAndroid Build Coastguard Worker 
2720*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2721*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2722*35238bceSAndroid Build Coastguard Worker 
2723*35238bceSAndroid Build Coastguard Worker     // check every buffer
2724*35238bceSAndroid Build Coastguard Worker     for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2725*35238bceSAndroid Build Coastguard Worker     {
2726*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Resource",
2727*35238bceSAndroid Build Coastguard Worker                                             "Resource index " + de::toString(bufferNdx));
2728*35238bceSAndroid Build Coastguard Worker         const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2729*35238bceSAndroid Build Coastguard Worker         glw::GLint bufferBinding            = -1;
2730*35238bceSAndroid Build Coastguard Worker         glw::GLint written                  = -1;
2731*35238bceSAndroid Build Coastguard Worker 
2732*35238bceSAndroid Build Coastguard Worker         gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1,
2733*35238bceSAndroid Build Coastguard Worker                                 &written, &bufferBinding);
2734*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2735*35238bceSAndroid Build Coastguard Worker 
2736*35238bceSAndroid Build Coastguard Worker         if (written <= 0)
2737*35238bceSAndroid Build Coastguard Worker         {
2738*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values."
2739*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2740*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2741*35238bceSAndroid Build Coastguard Worker         }
2742*35238bceSAndroid Build Coastguard Worker 
2743*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding
2744*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
2745*35238bceSAndroid Build Coastguard Worker 
2746*35238bceSAndroid Build Coastguard Worker         // no such buffer binding?
2747*35238bceSAndroid Build Coastguard Worker         if (getBufferVariableCount(bufferBinding) == 0)
2748*35238bceSAndroid Build Coastguard Worker         {
2749*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding
2750*35238bceSAndroid Build Coastguard Worker                                << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2751*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2752*35238bceSAndroid Build Coastguard Worker         }
2753*35238bceSAndroid Build Coastguard Worker     }
2754*35238bceSAndroid Build Coastguard Worker 
2755*35238bceSAndroid Build Coastguard Worker     return STOP;
2756*35238bceSAndroid Build Coastguard Worker }
2757*35238bceSAndroid Build Coastguard Worker 
2758*35238bceSAndroid Build Coastguard Worker class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2759*35238bceSAndroid Build Coastguard Worker {
2760*35238bceSAndroid Build Coastguard Worker public:
2761*35238bceSAndroid Build Coastguard Worker     AtomicCounterBufferDataSizeCase(Context &context, const char *name, const char *description);
2762*35238bceSAndroid Build Coastguard Worker 
2763*35238bceSAndroid Build Coastguard Worker private:
2764*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2765*35238bceSAndroid Build Coastguard Worker };
2766*35238bceSAndroid Build Coastguard Worker 
AtomicCounterBufferDataSizeCase(Context & context,const char * name,const char * description)2767*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase(Context &context, const char *name,
2768*35238bceSAndroid Build Coastguard Worker                                                                  const char *description)
2769*35238bceSAndroid Build Coastguard Worker     : AtomicCounterCase(context, name, description)
2770*35238bceSAndroid Build Coastguard Worker {
2771*35238bceSAndroid Build Coastguard Worker }
2772*35238bceSAndroid Build Coastguard Worker 
iterate(void)2773*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate(void)
2774*35238bceSAndroid Build Coastguard Worker {
2775*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2776*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2777*35238bceSAndroid Build Coastguard Worker     const int numAtomicBuffers = getNumAtomicCounterBuffers();
2778*35238bceSAndroid Build Coastguard Worker 
2779*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2780*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2781*35238bceSAndroid Build Coastguard Worker 
2782*35238bceSAndroid Build Coastguard Worker     // check every buffer
2783*35238bceSAndroid Build Coastguard Worker     for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2784*35238bceSAndroid Build Coastguard Worker     {
2785*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Resource",
2786*35238bceSAndroid Build Coastguard Worker                                             "Resource index " + de::toString(bufferNdx));
2787*35238bceSAndroid Build Coastguard Worker         const glw::GLenum props[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE};
2788*35238bceSAndroid Build Coastguard Worker         glw::GLint values[]       = {-1, -1};
2789*35238bceSAndroid Build Coastguard Worker         glw::GLint written        = -1;
2790*35238bceSAndroid Build Coastguard Worker         int bufferMinDataSize;
2791*35238bceSAndroid Build Coastguard Worker 
2792*35238bceSAndroid Build Coastguard Worker         gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props),
2793*35238bceSAndroid Build Coastguard Worker                                 props, DE_LENGTH_OF_ARRAY(values), &written, values);
2794*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2795*35238bceSAndroid Build Coastguard Worker 
2796*35238bceSAndroid Build Coastguard Worker         if (written != 2)
2797*35238bceSAndroid Build Coastguard Worker         {
2798*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
2799*35238bceSAndroid Build Coastguard Worker                                << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written
2800*35238bceSAndroid Build Coastguard Worker                                << " value(s)." << tcu::TestLog::EndMessage;
2801*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2802*35238bceSAndroid Build Coastguard Worker             continue;
2803*35238bceSAndroid Build Coastguard Worker         }
2804*35238bceSAndroid Build Coastguard Worker 
2805*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << values[0] << "\n"
2806*35238bceSAndroid Build Coastguard Worker                            << "GL_BUFFER_DATA_SIZE = " << values[1] << tcu::TestLog::EndMessage;
2807*35238bceSAndroid Build Coastguard Worker 
2808*35238bceSAndroid Build Coastguard Worker         bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2809*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to "
2810*35238bceSAndroid Build Coastguard Worker                            << bufferMinDataSize << tcu::TestLog::EndMessage;
2811*35238bceSAndroid Build Coastguard Worker 
2812*35238bceSAndroid Build Coastguard Worker         // no such buffer binding?
2813*35238bceSAndroid Build Coastguard Worker         if (bufferMinDataSize == -1)
2814*35238bceSAndroid Build Coastguard Worker         {
2815*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0]
2816*35238bceSAndroid Build Coastguard Worker                                << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2817*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2818*35238bceSAndroid Build Coastguard Worker         }
2819*35238bceSAndroid Build Coastguard Worker         else if (values[1] < bufferMinDataSize)
2820*35238bceSAndroid Build Coastguard Worker         {
2821*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_DATA_SIZE = " << values[1]
2822*35238bceSAndroid Build Coastguard Worker                                << ", expected greater than or equal to " << bufferMinDataSize
2823*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
2824*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2825*35238bceSAndroid Build Coastguard Worker         }
2826*35238bceSAndroid Build Coastguard Worker         else
2827*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2828*35238bceSAndroid Build Coastguard Worker     }
2829*35238bceSAndroid Build Coastguard Worker 
2830*35238bceSAndroid Build Coastguard Worker     return STOP;
2831*35238bceSAndroid Build Coastguard Worker }
2832*35238bceSAndroid Build Coastguard Worker 
2833*35238bceSAndroid Build Coastguard Worker class AtomicCounterReferencedByCase : public TestCase
2834*35238bceSAndroid Build Coastguard Worker {
2835*35238bceSAndroid Build Coastguard Worker public:
2836*35238bceSAndroid Build Coastguard Worker     AtomicCounterReferencedByCase(Context &context, const char *name, const char *description, bool separable,
2837*35238bceSAndroid Build Coastguard Worker                                   uint32_t presentStagesMask, uint32_t activeStagesMask);
2838*35238bceSAndroid Build Coastguard Worker     ~AtomicCounterReferencedByCase(void);
2839*35238bceSAndroid Build Coastguard Worker 
2840*35238bceSAndroid Build Coastguard Worker private:
2841*35238bceSAndroid Build Coastguard Worker     void init(void);
2842*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2843*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2844*35238bceSAndroid Build Coastguard Worker 
2845*35238bceSAndroid Build Coastguard Worker     const bool m_separable;
2846*35238bceSAndroid Build Coastguard Worker     const uint32_t m_presentStagesMask;
2847*35238bceSAndroid Build Coastguard Worker     const uint32_t m_activeStagesMask;
2848*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_program;
2849*35238bceSAndroid Build Coastguard Worker };
2850*35238bceSAndroid Build Coastguard Worker 
AtomicCounterReferencedByCase(Context & context,const char * name,const char * description,bool separable,uint32_t presentStagesMask,uint32_t activeStagesMask)2851*35238bceSAndroid Build Coastguard Worker AtomicCounterReferencedByCase::AtomicCounterReferencedByCase(Context &context, const char *name,
2852*35238bceSAndroid Build Coastguard Worker                                                              const char *description, bool separable,
2853*35238bceSAndroid Build Coastguard Worker                                                              uint32_t presentStagesMask, uint32_t activeStagesMask)
2854*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
2855*35238bceSAndroid Build Coastguard Worker     , m_separable(separable)
2856*35238bceSAndroid Build Coastguard Worker     , m_presentStagesMask(presentStagesMask)
2857*35238bceSAndroid Build Coastguard Worker     , m_activeStagesMask(activeStagesMask)
2858*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2859*35238bceSAndroid Build Coastguard Worker {
2860*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2861*35238bceSAndroid Build Coastguard Worker }
2862*35238bceSAndroid Build Coastguard Worker 
~AtomicCounterReferencedByCase(void)2863*35238bceSAndroid Build Coastguard Worker AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase(void)
2864*35238bceSAndroid Build Coastguard Worker {
2865*35238bceSAndroid Build Coastguard Worker     deinit();
2866*35238bceSAndroid Build Coastguard Worker }
2867*35238bceSAndroid Build Coastguard Worker 
init(void)2868*35238bceSAndroid Build Coastguard Worker void AtomicCounterReferencedByCase::init(void)
2869*35238bceSAndroid Build Coastguard Worker {
2870*35238bceSAndroid Build Coastguard Worker     const uint32_t geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2871*35238bceSAndroid Build Coastguard Worker     const uint32_t tessellationMask =
2872*35238bceSAndroid Build Coastguard Worker         (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2873*35238bceSAndroid Build Coastguard Worker     glu::VariableDeclaration atomicVar(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST),
2874*35238bceSAndroid Build Coastguard Worker                                        "targetCounter", glu::STORAGE_UNIFORM);
2875*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2876*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45      = checkSupport(m_context);
2877*35238bceSAndroid Build Coastguard Worker 
2878*35238bceSAndroid Build Coastguard Worker     if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32orGL45 &&
2879*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2880*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2881*35238bceSAndroid Build Coastguard Worker     if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32orGL45 &&
2882*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2883*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2884*35238bceSAndroid Build Coastguard Worker 
2885*35238bceSAndroid Build Coastguard Worker     atomicVar.layout.binding = 1;
2886*35238bceSAndroid Build Coastguard Worker 
2887*35238bceSAndroid Build Coastguard Worker     m_program = new ProgramInterfaceDefinition::Program();
2888*35238bceSAndroid Build Coastguard Worker     m_program->setSeparable(m_separable);
2889*35238bceSAndroid Build Coastguard Worker 
2890*35238bceSAndroid Build Coastguard Worker     for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2891*35238bceSAndroid Build Coastguard Worker     {
2892*35238bceSAndroid Build Coastguard Worker         if (m_activeStagesMask & (1 << shaderType))
2893*35238bceSAndroid Build Coastguard Worker             m_program->addShader((glu::ShaderType)shaderType, glslVersion)
2894*35238bceSAndroid Build Coastguard Worker                 ->getDefaultBlock()
2895*35238bceSAndroid Build Coastguard Worker                 .variables.push_back(atomicVar);
2896*35238bceSAndroid Build Coastguard Worker         else if (m_presentStagesMask & (1 << shaderType))
2897*35238bceSAndroid Build Coastguard Worker             m_program->addShader((glu::ShaderType)shaderType, glslVersion);
2898*35238bceSAndroid Build Coastguard Worker     }
2899*35238bceSAndroid Build Coastguard Worker 
2900*35238bceSAndroid Build Coastguard Worker     if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2901*35238bceSAndroid Build Coastguard Worker         m_program->setGeometryNumOutputVertices(1);
2902*35238bceSAndroid Build Coastguard Worker     if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2903*35238bceSAndroid Build Coastguard Worker         m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2904*35238bceSAndroid Build Coastguard Worker         m_program->setTessellationNumOutputPatchVertices(1);
2905*35238bceSAndroid Build Coastguard Worker 
2906*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_program->isValid());
2907*35238bceSAndroid Build Coastguard Worker }
2908*35238bceSAndroid Build Coastguard Worker 
deinit(void)2909*35238bceSAndroid Build Coastguard Worker void AtomicCounterReferencedByCase::deinit(void)
2910*35238bceSAndroid Build Coastguard Worker {
2911*35238bceSAndroid Build Coastguard Worker     delete m_program;
2912*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
2913*35238bceSAndroid Build Coastguard Worker }
2914*35238bceSAndroid Build Coastguard Worker 
iterate(void)2915*35238bceSAndroid Build Coastguard Worker AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate(void)
2916*35238bceSAndroid Build Coastguard Worker {
2917*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &rc = m_context.getRenderContext();
2918*35238bceSAndroid Build Coastguard Worker     const bool isES32orGL45      = glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) ||
2919*35238bceSAndroid Build Coastguard Worker                               glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5));
2920*35238bceSAndroid Build Coastguard Worker 
2921*35238bceSAndroid Build Coastguard Worker     const struct
2922*35238bceSAndroid Build Coastguard Worker     {
2923*35238bceSAndroid Build Coastguard Worker         glw::GLenum propName;
2924*35238bceSAndroid Build Coastguard Worker         glu::ShaderType shaderType;
2925*35238bceSAndroid Build Coastguard Worker         const char *extension;
2926*35238bceSAndroid Build Coastguard Worker     } targetProps[] = {
2927*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL},
2928*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL},
2929*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL},
2930*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL,
2931*35238bceSAndroid Build Coastguard Worker          (isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")},
2932*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION,
2933*35238bceSAndroid Build Coastguard Worker          (isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")},
2934*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY,
2935*35238bceSAndroid Build Coastguard Worker          (isES32orGL45 ? DE_NULL : "GL_EXT_geometry_shader")},
2936*35238bceSAndroid Build Coastguard Worker     };
2937*35238bceSAndroid Build Coastguard Worker 
2938*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = rc.getFunctions();
2939*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(rc, generateProgramInterfaceProgramSources(m_program));
2940*35238bceSAndroid Build Coastguard Worker 
2941*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2942*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, rc.getFunctions(), m_testCtx.getLog());
2943*35238bceSAndroid Build Coastguard Worker 
2944*35238bceSAndroid Build Coastguard Worker     // check props
2945*35238bceSAndroid Build Coastguard Worker     for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2946*35238bceSAndroid Build Coastguard Worker     {
2947*35238bceSAndroid Build Coastguard Worker         if (targetProps[propNdx].extension == DE_NULL ||
2948*35238bceSAndroid Build Coastguard Worker             m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2949*35238bceSAndroid Build Coastguard Worker         {
2950*35238bceSAndroid Build Coastguard Worker             const glw::GLenum prop = targetProps[propNdx].propName;
2951*35238bceSAndroid Build Coastguard Worker             const glw::GLint expected =
2952*35238bceSAndroid Build Coastguard Worker                 ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2953*35238bceSAndroid Build Coastguard Worker             glw::GLint value   = -1;
2954*35238bceSAndroid Build Coastguard Worker             glw::GLint written = -1;
2955*35238bceSAndroid Build Coastguard Worker 
2956*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop)
2957*35238bceSAndroid Build Coastguard Worker                                << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2958*35238bceSAndroid Build Coastguard Worker 
2959*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2960*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2961*35238bceSAndroid Build Coastguard Worker 
2962*35238bceSAndroid Build Coastguard Worker             if (written != 1)
2963*35238bceSAndroid Build Coastguard Worker             {
2964*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
2965*35238bceSAndroid Build Coastguard Worker                                    << "Error, query for referenced_by_* returned invalid number of values."
2966*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2967*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2968*35238bceSAndroid Build Coastguard Worker                 continue;
2969*35238bceSAndroid Build Coastguard Worker             }
2970*35238bceSAndroid Build Coastguard Worker 
2971*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = "
2972*35238bceSAndroid Build Coastguard Worker                                << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2973*35238bceSAndroid Build Coastguard Worker 
2974*35238bceSAndroid Build Coastguard Worker             if (value != expected)
2975*35238bceSAndroid Build Coastguard Worker             {
2976*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value"
2977*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2978*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2979*35238bceSAndroid Build Coastguard Worker                 continue;
2980*35238bceSAndroid Build Coastguard Worker             }
2981*35238bceSAndroid Build Coastguard Worker         }
2982*35238bceSAndroid Build Coastguard Worker     }
2983*35238bceSAndroid Build Coastguard Worker 
2984*35238bceSAndroid Build Coastguard Worker     return STOP;
2985*35238bceSAndroid Build Coastguard Worker }
2986*35238bceSAndroid Build Coastguard Worker 
2987*35238bceSAndroid Build Coastguard Worker class ProgramInputOutputReferencedByCase : public TestCase
2988*35238bceSAndroid Build Coastguard Worker {
2989*35238bceSAndroid Build Coastguard Worker public:
2990*35238bceSAndroid Build Coastguard Worker     enum CaseType
2991*35238bceSAndroid Build Coastguard Worker     {
2992*35238bceSAndroid Build Coastguard Worker         CASE_VERTEX_FRAGMENT = 0,
2993*35238bceSAndroid Build Coastguard Worker         CASE_VERTEX_GEO_FRAGMENT,
2994*35238bceSAndroid Build Coastguard Worker         CASE_VERTEX_TESS_FRAGMENT,
2995*35238bceSAndroid Build Coastguard Worker         CASE_VERTEX_TESS_GEO_FRAGMENT,
2996*35238bceSAndroid Build Coastguard Worker 
2997*35238bceSAndroid Build Coastguard Worker         CASE_SEPARABLE_VERTEX,
2998*35238bceSAndroid Build Coastguard Worker         CASE_SEPARABLE_FRAGMENT,
2999*35238bceSAndroid Build Coastguard Worker         CASE_SEPARABLE_GEOMETRY,
3000*35238bceSAndroid Build Coastguard Worker         CASE_SEPARABLE_TESS_CTRL,
3001*35238bceSAndroid Build Coastguard Worker         CASE_SEPARABLE_TESS_EVAL,
3002*35238bceSAndroid Build Coastguard Worker 
3003*35238bceSAndroid Build Coastguard Worker         CASE_LAST
3004*35238bceSAndroid Build Coastguard Worker     };
3005*35238bceSAndroid Build Coastguard Worker     ProgramInputOutputReferencedByCase(Context &context, const char *name, const char *description,
3006*35238bceSAndroid Build Coastguard Worker                                        glu::Storage targetStorage, CaseType caseType);
3007*35238bceSAndroid Build Coastguard Worker     ~ProgramInputOutputReferencedByCase(void);
3008*35238bceSAndroid Build Coastguard Worker 
3009*35238bceSAndroid Build Coastguard Worker private:
3010*35238bceSAndroid Build Coastguard Worker     void init(void);
3011*35238bceSAndroid Build Coastguard Worker     void deinit(void);
3012*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
3013*35238bceSAndroid Build Coastguard Worker 
3014*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
3015*35238bceSAndroid Build Coastguard Worker     const glu::Storage m_targetStorage;
3016*35238bceSAndroid Build Coastguard Worker     ProgramInterfaceDefinition::Program *m_program;
3017*35238bceSAndroid Build Coastguard Worker };
3018*35238bceSAndroid Build Coastguard Worker 
ProgramInputOutputReferencedByCase(Context & context,const char * name,const char * description,glu::Storage targetStorage,CaseType caseType)3019*35238bceSAndroid Build Coastguard Worker ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase(Context &context, const char *name,
3020*35238bceSAndroid Build Coastguard Worker                                                                        const char *description,
3021*35238bceSAndroid Build Coastguard Worker                                                                        glu::Storage targetStorage, CaseType caseType)
3022*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
3023*35238bceSAndroid Build Coastguard Worker     , m_caseType(caseType)
3024*35238bceSAndroid Build Coastguard Worker     , m_targetStorage(targetStorage)
3025*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
3026*35238bceSAndroid Build Coastguard Worker {
3027*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(caseType < CASE_LAST);
3028*35238bceSAndroid Build Coastguard Worker }
3029*35238bceSAndroid Build Coastguard Worker 
~ProgramInputOutputReferencedByCase(void)3030*35238bceSAndroid Build Coastguard Worker ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase(void)
3031*35238bceSAndroid Build Coastguard Worker {
3032*35238bceSAndroid Build Coastguard Worker     deinit();
3033*35238bceSAndroid Build Coastguard Worker }
3034*35238bceSAndroid Build Coastguard Worker 
init(void)3035*35238bceSAndroid Build Coastguard Worker void ProgramInputOutputReferencedByCase::init(void)
3036*35238bceSAndroid Build Coastguard Worker {
3037*35238bceSAndroid Build Coastguard Worker     const bool hasTessellationShader =
3038*35238bceSAndroid Build Coastguard Worker         (m_caseType == CASE_VERTEX_TESS_FRAGMENT) || (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
3039*35238bceSAndroid Build Coastguard Worker         (m_caseType == CASE_SEPARABLE_TESS_CTRL) || (m_caseType == CASE_SEPARABLE_TESS_EVAL);
3040*35238bceSAndroid Build Coastguard Worker     const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
3041*35238bceSAndroid Build Coastguard Worker                                    (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
3042*35238bceSAndroid Build Coastguard Worker                                    (m_caseType == CASE_SEPARABLE_GEOMETRY);
3043*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 = checkSupport(m_context);
3044*35238bceSAndroid Build Coastguard Worker 
3045*35238bceSAndroid Build Coastguard Worker     if (hasTessellationShader && !supportsES32orGL45 &&
3046*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
3047*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
3048*35238bceSAndroid Build Coastguard Worker     if (hasGeometryShader && !supportsES32orGL45 &&
3049*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
3050*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
3051*35238bceSAndroid Build Coastguard Worker 
3052*35238bceSAndroid Build Coastguard Worker     glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
3053*35238bceSAndroid Build Coastguard Worker     m_program                    = new ProgramInterfaceDefinition::Program();
3054*35238bceSAndroid Build Coastguard Worker 
3055*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASE_SEPARABLE_VERTEX || m_caseType == CASE_SEPARABLE_FRAGMENT ||
3056*35238bceSAndroid Build Coastguard Worker         m_caseType == CASE_SEPARABLE_GEOMETRY || m_caseType == CASE_SEPARABLE_TESS_CTRL ||
3057*35238bceSAndroid Build Coastguard Worker         m_caseType == CASE_SEPARABLE_TESS_EVAL)
3058*35238bceSAndroid Build Coastguard Worker     {
3059*35238bceSAndroid Build Coastguard Worker         const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3060*35238bceSAndroid Build Coastguard Worker         const bool perPatchStorage =
3061*35238bceSAndroid Build Coastguard Worker             (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
3062*35238bceSAndroid Build Coastguard Worker         const char *varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3063*35238bceSAndroid Build Coastguard Worker         const glu::VariableDeclaration targetDecl(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName,
3064*35238bceSAndroid Build Coastguard Worker                                                   m_targetStorage);
3065*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType shaderType =
3066*35238bceSAndroid Build Coastguard Worker             (m_caseType == CASE_SEPARABLE_VERTEX)    ? (glu::SHADERTYPE_VERTEX) :
3067*35238bceSAndroid Build Coastguard Worker             (m_caseType == CASE_SEPARABLE_FRAGMENT)  ? (glu::SHADERTYPE_FRAGMENT) :
3068*35238bceSAndroid Build Coastguard Worker             (m_caseType == CASE_SEPARABLE_GEOMETRY)  ? (glu::SHADERTYPE_GEOMETRY) :
3069*35238bceSAndroid Build Coastguard Worker             (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL) :
3070*35238bceSAndroid Build Coastguard Worker             (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION) :
3071*35238bceSAndroid Build Coastguard Worker                                                        (glu::SHADERTYPE_LAST);
3072*35238bceSAndroid Build Coastguard Worker         const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
3073*35238bceSAndroid Build Coastguard Worker                                                        (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
3074*35238bceSAndroid Build Coastguard Worker                                                        (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION)) :
3075*35238bceSAndroid Build Coastguard Worker                                                       (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
3076*35238bceSAndroid Build Coastguard Worker 
3077*35238bceSAndroid Build Coastguard Worker         m_program->setSeparable(true);
3078*35238bceSAndroid Build Coastguard Worker 
3079*35238bceSAndroid Build Coastguard Worker         if (arrayedInterface && !perPatchStorage)
3080*35238bceSAndroid Build Coastguard Worker         {
3081*35238bceSAndroid Build Coastguard Worker             const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY),
3082*35238bceSAndroid Build Coastguard Worker                                                          varName, m_targetStorage);
3083*35238bceSAndroid Build Coastguard Worker             m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDeclArr);
3084*35238bceSAndroid Build Coastguard Worker         }
3085*35238bceSAndroid Build Coastguard Worker         else
3086*35238bceSAndroid Build Coastguard Worker         {
3087*35238bceSAndroid Build Coastguard Worker             m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDecl);
3088*35238bceSAndroid Build Coastguard Worker         }
3089*35238bceSAndroid Build Coastguard Worker     }
3090*35238bceSAndroid Build Coastguard Worker     else if (m_caseType == CASE_VERTEX_FRAGMENT || m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
3091*35238bceSAndroid Build Coastguard Worker              m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
3092*35238bceSAndroid Build Coastguard Worker     {
3093*35238bceSAndroid Build Coastguard Worker         ProgramInterfaceDefinition::Shader *vertex   = m_program->addShader(glu::SHADERTYPE_VERTEX, glslVersion);
3094*35238bceSAndroid Build Coastguard Worker         ProgramInterfaceDefinition::Shader *fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glslVersion);
3095*35238bceSAndroid Build Coastguard Worker 
3096*35238bceSAndroid Build Coastguard Worker         m_program->setSeparable(false);
3097*35238bceSAndroid Build Coastguard Worker 
3098*35238bceSAndroid Build Coastguard Worker         vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(
3099*35238bceSAndroid Build Coastguard Worker             glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderInput", glu::STORAGE_IN));
3100*35238bceSAndroid Build Coastguard Worker         vertex->getDefaultBlock().variables.push_back(
3101*35238bceSAndroid Build Coastguard Worker             glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderOutput",
3102*35238bceSAndroid Build Coastguard Worker                                      glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(1)));
3103*35238bceSAndroid Build Coastguard Worker 
3104*35238bceSAndroid Build Coastguard Worker         fragment->getDefaultBlock().variables.push_back(
3105*35238bceSAndroid Build Coastguard Worker             glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderOutput",
3106*35238bceSAndroid Build Coastguard Worker                                      glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(0)));
3107*35238bceSAndroid Build Coastguard Worker         fragment->getDefaultBlock().variables.push_back(
3108*35238bceSAndroid Build Coastguard Worker             glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderInput",
3109*35238bceSAndroid Build Coastguard Worker                                      glu::STORAGE_IN, glu::INTERPOLATION_LAST, glu::Layout(1)));
3110*35238bceSAndroid Build Coastguard Worker 
3111*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
3112*35238bceSAndroid Build Coastguard Worker         {
3113*35238bceSAndroid Build Coastguard Worker             ProgramInterfaceDefinition::Shader *tessCtrl =
3114*35238bceSAndroid Build Coastguard Worker                 m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glslVersion);
3115*35238bceSAndroid Build Coastguard Worker             ProgramInterfaceDefinition::Shader *tessEval =
3116*35238bceSAndroid Build Coastguard Worker                 m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glslVersion);
3117*35238bceSAndroid Build Coastguard Worker 
3118*35238bceSAndroid Build Coastguard Worker             tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(
3119*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
3120*35238bceSAndroid Build Coastguard Worker                 "shaderInput", glu::STORAGE_IN, glu::INTERPOLATION_LAST, glu::Layout(1)));
3121*35238bceSAndroid Build Coastguard Worker             tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(
3122*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
3123*35238bceSAndroid Build Coastguard Worker                 "shaderOutput", glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(1)));
3124*35238bceSAndroid Build Coastguard Worker 
3125*35238bceSAndroid Build Coastguard Worker             tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(
3126*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
3127*35238bceSAndroid Build Coastguard Worker                 "shaderInput", glu::STORAGE_IN, glu::INTERPOLATION_LAST, glu::Layout(1)));
3128*35238bceSAndroid Build Coastguard Worker             tessEval->getDefaultBlock().variables.push_back(
3129*35238bceSAndroid Build Coastguard Worker                 glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderOutput",
3130*35238bceSAndroid Build Coastguard Worker                                          glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(1)));
3131*35238bceSAndroid Build Coastguard Worker         }
3132*35238bceSAndroid Build Coastguard Worker 
3133*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
3134*35238bceSAndroid Build Coastguard Worker         {
3135*35238bceSAndroid Build Coastguard Worker             ProgramInterfaceDefinition::Shader *geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glslVersion);
3136*35238bceSAndroid Build Coastguard Worker 
3137*35238bceSAndroid Build Coastguard Worker             geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(
3138*35238bceSAndroid Build Coastguard Worker                 glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
3139*35238bceSAndroid Build Coastguard Worker                 "shaderInput", glu::STORAGE_IN, glu::INTERPOLATION_LAST, glu::Layout(1)));
3140*35238bceSAndroid Build Coastguard Worker             geometry->getDefaultBlock().variables.push_back(
3141*35238bceSAndroid Build Coastguard Worker                 glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "shaderOutput",
3142*35238bceSAndroid Build Coastguard Worker                                          glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(1)));
3143*35238bceSAndroid Build Coastguard Worker         }
3144*35238bceSAndroid Build Coastguard Worker     }
3145*35238bceSAndroid Build Coastguard Worker     else
3146*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3147*35238bceSAndroid Build Coastguard Worker 
3148*35238bceSAndroid Build Coastguard Worker     if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
3149*35238bceSAndroid Build Coastguard Worker         m_program->setGeometryNumOutputVertices(1);
3150*35238bceSAndroid Build Coastguard Worker     if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
3151*35238bceSAndroid Build Coastguard Worker         m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
3152*35238bceSAndroid Build Coastguard Worker         m_program->setTessellationNumOutputPatchVertices(1);
3153*35238bceSAndroid Build Coastguard Worker 
3154*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_program->isValid());
3155*35238bceSAndroid Build Coastguard Worker }
3156*35238bceSAndroid Build Coastguard Worker 
deinit(void)3157*35238bceSAndroid Build Coastguard Worker void ProgramInputOutputReferencedByCase::deinit(void)
3158*35238bceSAndroid Build Coastguard Worker {
3159*35238bceSAndroid Build Coastguard Worker     delete m_program;
3160*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
3161*35238bceSAndroid Build Coastguard Worker }
3162*35238bceSAndroid Build Coastguard Worker 
iterate(void)3163*35238bceSAndroid Build Coastguard Worker ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate(void)
3164*35238bceSAndroid Build Coastguard Worker {
3165*35238bceSAndroid Build Coastguard Worker     static const struct
3166*35238bceSAndroid Build Coastguard Worker     {
3167*35238bceSAndroid Build Coastguard Worker         glw::GLenum propName;
3168*35238bceSAndroid Build Coastguard Worker         glu::ShaderType shaderType;
3169*35238bceSAndroid Build Coastguard Worker         const char *extension;
3170*35238bceSAndroid Build Coastguard Worker     } targetProps[] = {
3171*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL},
3172*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL},
3173*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL},
3174*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader"},
3175*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION,
3176*35238bceSAndroid Build Coastguard Worker          "GL_EXT_tessellation_shader"},
3177*35238bceSAndroid Build Coastguard Worker         {GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader"},
3178*35238bceSAndroid Build Coastguard Worker     };
3179*35238bceSAndroid Build Coastguard Worker 
3180*35238bceSAndroid Build Coastguard Worker     const bool isInputCase   = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3181*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3182*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3183*35238bceSAndroid Build Coastguard Worker     const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3184*35238bceSAndroid Build Coastguard Worker     const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3185*35238bceSAndroid Build Coastguard Worker     glw::GLuint resourceIndex;
3186*35238bceSAndroid Build Coastguard Worker 
3187*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3188*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3189*35238bceSAndroid Build Coastguard Worker 
3190*35238bceSAndroid Build Coastguard Worker     // find target resource index
3191*35238bceSAndroid Build Coastguard Worker 
3192*35238bceSAndroid Build Coastguard Worker     resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3193*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3194*35238bceSAndroid Build Coastguard Worker 
3195*35238bceSAndroid Build Coastguard Worker     if (resourceIndex == GL_INVALID_INDEX)
3196*35238bceSAndroid Build Coastguard Worker     {
3197*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName
3198*35238bceSAndroid Build Coastguard Worker                            << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3199*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3200*35238bceSAndroid Build Coastguard Worker         return STOP;
3201*35238bceSAndroid Build Coastguard Worker     }
3202*35238bceSAndroid Build Coastguard Worker 
3203*35238bceSAndroid Build Coastguard Worker     // check props
3204*35238bceSAndroid Build Coastguard Worker     for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3205*35238bceSAndroid Build Coastguard Worker     {
3206*35238bceSAndroid Build Coastguard Worker         if (targetProps[propNdx].extension == DE_NULL ||
3207*35238bceSAndroid Build Coastguard Worker             m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3208*35238bceSAndroid Build Coastguard Worker         {
3209*35238bceSAndroid Build Coastguard Worker             const glw::GLenum prop = targetProps[propNdx].propName;
3210*35238bceSAndroid Build Coastguard Worker             const bool expected    = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) :
3211*35238bceSAndroid Build Coastguard Worker                                                      (targetProps[propNdx].shaderType == m_program->getLastStage());
3212*35238bceSAndroid Build Coastguard Worker             glw::GLint value       = -1;
3213*35238bceSAndroid Build Coastguard Worker             glw::GLint written     = -1;
3214*35238bceSAndroid Build Coastguard Worker 
3215*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop)
3216*35238bceSAndroid Build Coastguard Worker                                << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3217*35238bceSAndroid Build Coastguard Worker 
3218*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written,
3219*35238bceSAndroid Build Coastguard Worker                                     &value);
3220*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3221*35238bceSAndroid Build Coastguard Worker 
3222*35238bceSAndroid Build Coastguard Worker             if (written != 1)
3223*35238bceSAndroid Build Coastguard Worker             {
3224*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message
3225*35238bceSAndroid Build Coastguard Worker                                    << "Error, query for referenced_by_* returned invalid number of values."
3226*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
3227*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3228*35238bceSAndroid Build Coastguard Worker                 continue;
3229*35238bceSAndroid Build Coastguard Worker             }
3230*35238bceSAndroid Build Coastguard Worker 
3231*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = "
3232*35238bceSAndroid Build Coastguard Worker                                << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3233*35238bceSAndroid Build Coastguard Worker 
3234*35238bceSAndroid Build Coastguard Worker             if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3235*35238bceSAndroid Build Coastguard Worker             {
3236*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value"
3237*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
3238*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3239*35238bceSAndroid Build Coastguard Worker                 continue;
3240*35238bceSAndroid Build Coastguard Worker             }
3241*35238bceSAndroid Build Coastguard Worker         }
3242*35238bceSAndroid Build Coastguard Worker     }
3243*35238bceSAndroid Build Coastguard Worker 
3244*35238bceSAndroid Build Coastguard Worker     return STOP;
3245*35238bceSAndroid Build Coastguard Worker }
3246*35238bceSAndroid Build Coastguard Worker 
3247*35238bceSAndroid Build Coastguard Worker class FeedbackResourceListTestCase : public ResourceListTestCase
3248*35238bceSAndroid Build Coastguard Worker {
3249*35238bceSAndroid Build Coastguard Worker public:
3250*35238bceSAndroid Build Coastguard Worker     FeedbackResourceListTestCase(Context &context, const ResourceDefinition::Node::SharedPtr &resource,
3251*35238bceSAndroid Build Coastguard Worker                                  const char *name);
3252*35238bceSAndroid Build Coastguard Worker     ~FeedbackResourceListTestCase(void);
3253*35238bceSAndroid Build Coastguard Worker 
3254*35238bceSAndroid Build Coastguard Worker private:
3255*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
3256*35238bceSAndroid Build Coastguard Worker };
3257*35238bceSAndroid Build Coastguard Worker 
FeedbackResourceListTestCase(Context & context,const ResourceDefinition::Node::SharedPtr & resource,const char * name)3258*35238bceSAndroid Build Coastguard Worker FeedbackResourceListTestCase::FeedbackResourceListTestCase(Context &context,
3259*35238bceSAndroid Build Coastguard Worker                                                            const ResourceDefinition::Node::SharedPtr &resource,
3260*35238bceSAndroid Build Coastguard Worker                                                            const char *name)
3261*35238bceSAndroid Build Coastguard Worker     : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3262*35238bceSAndroid Build Coastguard Worker {
3263*35238bceSAndroid Build Coastguard Worker }
3264*35238bceSAndroid Build Coastguard Worker 
~FeedbackResourceListTestCase(void)3265*35238bceSAndroid Build Coastguard Worker FeedbackResourceListTestCase::~FeedbackResourceListTestCase(void)
3266*35238bceSAndroid Build Coastguard Worker {
3267*35238bceSAndroid Build Coastguard Worker     deinit();
3268*35238bceSAndroid Build Coastguard Worker }
3269*35238bceSAndroid Build Coastguard Worker 
iterate(void)3270*35238bceSAndroid Build Coastguard Worker FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate(void)
3271*35238bceSAndroid Build Coastguard Worker {
3272*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(),
3273*35238bceSAndroid Build Coastguard Worker                                      generateProgramInterfaceProgramSources(m_programDefinition));
3274*35238bceSAndroid Build Coastguard Worker 
3275*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3276*35238bceSAndroid Build Coastguard Worker 
3277*35238bceSAndroid Build Coastguard Worker     // Feedback varyings
3278*35238bceSAndroid Build Coastguard Worker     {
3279*35238bceSAndroid Build Coastguard Worker         tcu::MessageBuilder builder(&m_testCtx.getLog());
3280*35238bceSAndroid Build Coastguard Worker         builder << "Transform feedback varyings: {";
3281*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3282*35238bceSAndroid Build Coastguard Worker         {
3283*35238bceSAndroid Build Coastguard Worker             if (ndx)
3284*35238bceSAndroid Build Coastguard Worker                 builder << ", ";
3285*35238bceSAndroid Build Coastguard Worker             builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3286*35238bceSAndroid Build Coastguard Worker         }
3287*35238bceSAndroid Build Coastguard Worker         builder << "}" << tcu::TestLog::EndMessage;
3288*35238bceSAndroid Build Coastguard Worker     }
3289*35238bceSAndroid Build Coastguard Worker 
3290*35238bceSAndroid Build Coastguard Worker     checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3291*35238bceSAndroid Build Coastguard Worker 
3292*35238bceSAndroid Build Coastguard Worker     // Check resource list
3293*35238bceSAndroid Build Coastguard Worker     {
3294*35238bceSAndroid Build Coastguard Worker         const tcu::ScopedLogSection section(m_testCtx.getLog(), "ResourceList", "Resource list");
3295*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> resourceList;
3296*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> expectedResources;
3297*35238bceSAndroid Build Coastguard Worker 
3298*35238bceSAndroid Build Coastguard Worker         queryResourceList(resourceList, program.getProgram());
3299*35238bceSAndroid Build Coastguard Worker         expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3300*35238bceSAndroid Build Coastguard Worker 
3301*35238bceSAndroid Build Coastguard Worker         // verify the list and the expected list match
3302*35238bceSAndroid Build Coastguard Worker 
3303*35238bceSAndroid Build Coastguard Worker         if (!verifyResourceList(resourceList, expectedResources))
3304*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3305*35238bceSAndroid Build Coastguard Worker 
3306*35238bceSAndroid Build Coastguard Worker         // verify GetProgramResourceIndex() matches the indices of the list
3307*35238bceSAndroid Build Coastguard Worker 
3308*35238bceSAndroid Build Coastguard Worker         if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3309*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3310*35238bceSAndroid Build Coastguard Worker 
3311*35238bceSAndroid Build Coastguard Worker         // Verify MAX_NAME_LENGTH
3312*35238bceSAndroid Build Coastguard Worker         if (!verifyMaxNameLength(resourceList, program.getProgram()))
3313*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3314*35238bceSAndroid Build Coastguard Worker     }
3315*35238bceSAndroid Build Coastguard Worker 
3316*35238bceSAndroid Build Coastguard Worker     return STOP;
3317*35238bceSAndroid Build Coastguard Worker }
3318*35238bceSAndroid Build Coastguard Worker 
getBlockMinDataSize(const glu::InterfaceBlock & block) const3319*35238bceSAndroid Build Coastguard Worker int InterfaceBlockDataSizeTestCase::getBlockMinDataSize(const glu::InterfaceBlock &block) const
3320*35238bceSAndroid Build Coastguard Worker {
3321*35238bceSAndroid Build Coastguard Worker     int dataSize = 0;
3322*35238bceSAndroid Build Coastguard Worker 
3323*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3324*35238bceSAndroid Build Coastguard Worker         dataSize += getVarTypeSize(block.variables[ndx].varType);
3325*35238bceSAndroid Build Coastguard Worker 
3326*35238bceSAndroid Build Coastguard Worker     return dataSize;
3327*35238bceSAndroid Build Coastguard Worker }
3328*35238bceSAndroid Build Coastguard Worker 
isDataTypeLayoutQualified(glu::DataType type)3329*35238bceSAndroid Build Coastguard Worker static bool isDataTypeLayoutQualified(glu::DataType type)
3330*35238bceSAndroid Build Coastguard Worker {
3331*35238bceSAndroid Build Coastguard Worker     return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3332*35238bceSAndroid Build Coastguard Worker }
3333*35238bceSAndroid Build Coastguard Worker 
generateVariableCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel=3,bool createTestGroup=true)3334*35238bceSAndroid Build Coastguard Worker static void generateVariableCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3335*35238bceSAndroid Build Coastguard Worker                                   tcu::TestCaseGroup *const targetGroup,
3336*35238bceSAndroid Build Coastguard Worker                                   const ProgramResourceQueryTestTarget &queryTarget, int expandLevel = 3,
3337*35238bceSAndroid Build Coastguard Worker                                   bool createTestGroup = true)
3338*35238bceSAndroid Build Coastguard Worker {
3339*35238bceSAndroid Build Coastguard Worker     static const struct
3340*35238bceSAndroid Build Coastguard Worker     {
3341*35238bceSAndroid Build Coastguard Worker         int level;
3342*35238bceSAndroid Build Coastguard Worker         glu::DataType dataType;
3343*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
3344*35238bceSAndroid Build Coastguard Worker         {0, glu::TYPE_FLOAT},        {1, glu::TYPE_INT},          {1, glu::TYPE_UINT},
3345*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_BOOL},
3346*35238bceSAndroid Build Coastguard Worker 
3347*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_FLOAT_VEC2},   {1, glu::TYPE_FLOAT_VEC3},   {1, glu::TYPE_FLOAT_VEC4},
3348*35238bceSAndroid Build Coastguard Worker 
3349*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_VEC2},     {2, glu::TYPE_INT_VEC3},     {3, glu::TYPE_INT_VEC4},
3350*35238bceSAndroid Build Coastguard Worker 
3351*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_VEC2},    {2, glu::TYPE_UINT_VEC3},    {3, glu::TYPE_UINT_VEC4},
3352*35238bceSAndroid Build Coastguard Worker 
3353*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_BOOL_VEC2},    {2, glu::TYPE_BOOL_VEC3},    {3, glu::TYPE_BOOL_VEC4},
3354*35238bceSAndroid Build Coastguard Worker 
3355*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT2},   {3, glu::TYPE_FLOAT_MAT2X3}, {3, glu::TYPE_FLOAT_MAT2X4},
3356*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT3X2}, {2, glu::TYPE_FLOAT_MAT3},   {3, glu::TYPE_FLOAT_MAT3X4},
3357*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT4X2}, {3, glu::TYPE_FLOAT_MAT4X3}, {2, glu::TYPE_FLOAT_MAT4},
3358*35238bceSAndroid Build Coastguard Worker     };
3359*35238bceSAndroid Build Coastguard Worker 
3360*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *group;
3361*35238bceSAndroid Build Coastguard Worker 
3362*35238bceSAndroid Build Coastguard Worker     if (createTestGroup)
3363*35238bceSAndroid Build Coastguard Worker     {
3364*35238bceSAndroid Build Coastguard Worker         group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3365*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(group);
3366*35238bceSAndroid Build Coastguard Worker     }
3367*35238bceSAndroid Build Coastguard Worker     else
3368*35238bceSAndroid Build Coastguard Worker         group = targetGroup;
3369*35238bceSAndroid Build Coastguard Worker 
3370*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3371*35238bceSAndroid Build Coastguard Worker     {
3372*35238bceSAndroid Build Coastguard Worker         if (variableTypes[ndx].level <= expandLevel)
3373*35238bceSAndroid Build Coastguard Worker         {
3374*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
3375*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3376*35238bceSAndroid Build Coastguard Worker             group->addChild(new ResourceTestCase(context, variable, queryTarget));
3377*35238bceSAndroid Build Coastguard Worker         }
3378*35238bceSAndroid Build Coastguard Worker     }
3379*35238bceSAndroid Build Coastguard Worker }
3380*35238bceSAndroid Build Coastguard Worker 
generateOpaqueTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel=3,bool createTestGroup=true)3381*35238bceSAndroid Build Coastguard Worker static void generateOpaqueTypeCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3382*35238bceSAndroid Build Coastguard Worker                                     tcu::TestCaseGroup *const targetGroup,
3383*35238bceSAndroid Build Coastguard Worker                                     const ProgramResourceQueryTestTarget &queryTarget, int expandLevel = 3,
3384*35238bceSAndroid Build Coastguard Worker                                     bool createTestGroup = true)
3385*35238bceSAndroid Build Coastguard Worker {
3386*35238bceSAndroid Build Coastguard Worker     static const struct
3387*35238bceSAndroid Build Coastguard Worker     {
3388*35238bceSAndroid Build Coastguard Worker         int level;
3389*35238bceSAndroid Build Coastguard Worker         glu::DataType dataType;
3390*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
3391*35238bceSAndroid Build Coastguard Worker         {0, glu::TYPE_SAMPLER_2D},
3392*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_SAMPLER_CUBE},
3393*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_SAMPLER_2D_ARRAY},
3394*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_SAMPLER_3D},
3395*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_SAMPLER_2D_SHADOW},
3396*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_SAMPLER_CUBE_SHADOW},
3397*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW},
3398*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_INT_SAMPLER_2D},
3399*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_SAMPLER_CUBE},
3400*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_SAMPLER_2D_ARRAY},
3401*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_SAMPLER_3D},
3402*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_UINT_SAMPLER_2D},
3403*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_SAMPLER_CUBE},
3404*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_SAMPLER_2D_ARRAY},
3405*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_SAMPLER_3D},
3406*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_SAMPLER_2D_MULTISAMPLE},
3407*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE},
3408*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE},
3409*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_IMAGE_2D},
3410*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_IMAGE_CUBE},
3411*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_IMAGE_2D_ARRAY},
3412*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_IMAGE_3D},
3413*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_IMAGE_2D},
3414*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_IMAGE_CUBE},
3415*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_INT_IMAGE_2D_ARRAY},
3416*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_IMAGE_3D},
3417*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_UINT_IMAGE_2D},
3418*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_IMAGE_CUBE},
3419*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_IMAGE_2D_ARRAY},
3420*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_IMAGE_3D},
3421*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_UINT_ATOMIC_COUNTER},
3422*35238bceSAndroid Build Coastguard Worker     };
3423*35238bceSAndroid Build Coastguard Worker 
3424*35238bceSAndroid Build Coastguard Worker     bool isStructMember = false;
3425*35238bceSAndroid Build Coastguard Worker 
3426*35238bceSAndroid Build Coastguard Worker     // Requirements
3427*35238bceSAndroid Build Coastguard Worker     for (const ResourceDefinition::Node *node = parentStructure.get(); node; node = node->getEnclosingNode())
3428*35238bceSAndroid Build Coastguard Worker     {
3429*35238bceSAndroid Build Coastguard Worker         // Don't insert inside a interface block
3430*35238bceSAndroid Build Coastguard Worker         if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3431*35238bceSAndroid Build Coastguard Worker             return;
3432*35238bceSAndroid Build Coastguard Worker 
3433*35238bceSAndroid Build Coastguard Worker         isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3434*35238bceSAndroid Build Coastguard Worker     }
3435*35238bceSAndroid Build Coastguard Worker 
3436*35238bceSAndroid Build Coastguard Worker     // Add cases
3437*35238bceSAndroid Build Coastguard Worker     {
3438*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *group;
3439*35238bceSAndroid Build Coastguard Worker 
3440*35238bceSAndroid Build Coastguard Worker         if (createTestGroup)
3441*35238bceSAndroid Build Coastguard Worker         {
3442*35238bceSAndroid Build Coastguard Worker             group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3443*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(group);
3444*35238bceSAndroid Build Coastguard Worker         }
3445*35238bceSAndroid Build Coastguard Worker         else
3446*35238bceSAndroid Build Coastguard Worker             group = targetGroup;
3447*35238bceSAndroid Build Coastguard Worker 
3448*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3449*35238bceSAndroid Build Coastguard Worker         {
3450*35238bceSAndroid Build Coastguard Worker             if (variableTypes[ndx].level > expandLevel)
3451*35238bceSAndroid Build Coastguard Worker                 continue;
3452*35238bceSAndroid Build Coastguard Worker 
3453*35238bceSAndroid Build Coastguard Worker             // Layout qualifiers are not allowed on struct members
3454*35238bceSAndroid Build Coastguard Worker             if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3455*35238bceSAndroid Build Coastguard Worker                 continue;
3456*35238bceSAndroid Build Coastguard Worker 
3457*35238bceSAndroid Build Coastguard Worker             {
3458*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr variable(
3459*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3460*35238bceSAndroid Build Coastguard Worker                 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3461*35238bceSAndroid Build Coastguard Worker             }
3462*35238bceSAndroid Build Coastguard Worker         }
3463*35238bceSAndroid Build Coastguard Worker     }
3464*35238bceSAndroid Build Coastguard Worker }
3465*35238bceSAndroid Build Coastguard Worker 
3466*35238bceSAndroid Build Coastguard Worker static void generateCompoundVariableCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3467*35238bceSAndroid Build Coastguard Worker                                           tcu::TestCaseGroup *const targetGroup,
3468*35238bceSAndroid Build Coastguard Worker                                           const ProgramResourceQueryTestTarget &queryTarget, int expandLevel = 3);
3469*35238bceSAndroid Build Coastguard Worker 
generateVariableArrayCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel=3)3470*35238bceSAndroid Build Coastguard Worker static void generateVariableArrayCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3471*35238bceSAndroid Build Coastguard Worker                                        tcu::TestCaseGroup *const targetGroup,
3472*35238bceSAndroid Build Coastguard Worker                                        const ProgramResourceQueryTestTarget &queryTarget, int expandLevel = 3)
3473*35238bceSAndroid Build Coastguard Worker {
3474*35238bceSAndroid Build Coastguard Worker     if (expandLevel > 0)
3475*35238bceSAndroid Build Coastguard Worker     {
3476*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3477*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3478*35238bceSAndroid Build Coastguard Worker 
3479*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3480*35238bceSAndroid Build Coastguard Worker 
3481*35238bceSAndroid Build Coastguard Worker         // Arrays of basic variables
3482*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3483*35238bceSAndroid Build Coastguard Worker 
3484*35238bceSAndroid Build Coastguard Worker         // Arrays of opaque types
3485*35238bceSAndroid Build Coastguard Worker         generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3486*35238bceSAndroid Build Coastguard Worker 
3487*35238bceSAndroid Build Coastguard Worker         // Arrays of arrays
3488*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel - 1);
3489*35238bceSAndroid Build Coastguard Worker 
3490*35238bceSAndroid Build Coastguard Worker         // Arrays of structs
3491*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel - 1);
3492*35238bceSAndroid Build Coastguard Worker     }
3493*35238bceSAndroid Build Coastguard Worker }
3494*35238bceSAndroid Build Coastguard Worker 
generateCompoundVariableCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel)3495*35238bceSAndroid Build Coastguard Worker static void generateCompoundVariableCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3496*35238bceSAndroid Build Coastguard Worker                                           tcu::TestCaseGroup *const targetGroup,
3497*35238bceSAndroid Build Coastguard Worker                                           const ProgramResourceQueryTestTarget &queryTarget, int expandLevel)
3498*35238bceSAndroid Build Coastguard Worker {
3499*35238bceSAndroid Build Coastguard Worker     if (expandLevel > 0)
3500*35238bceSAndroid Build Coastguard Worker     {
3501*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3502*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3503*35238bceSAndroid Build Coastguard Worker 
3504*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3505*35238bceSAndroid Build Coastguard Worker 
3506*35238bceSAndroid Build Coastguard Worker         // Struct containing basic variable
3507*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3508*35238bceSAndroid Build Coastguard Worker 
3509*35238bceSAndroid Build Coastguard Worker         // Struct containing opaque types
3510*35238bceSAndroid Build Coastguard Worker         generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3511*35238bceSAndroid Build Coastguard Worker 
3512*35238bceSAndroid Build Coastguard Worker         // Struct containing arrays
3513*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel - 1);
3514*35238bceSAndroid Build Coastguard Worker 
3515*35238bceSAndroid Build Coastguard Worker         // Struct containing struct
3516*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel - 1);
3517*35238bceSAndroid Build Coastguard Worker     }
3518*35238bceSAndroid Build Coastguard Worker }
3519*35238bceSAndroid Build Coastguard Worker 
3520*35238bceSAndroid Build Coastguard Worker // Resource list cases
3521*35238bceSAndroid Build Coastguard Worker 
3522*35238bceSAndroid Build Coastguard Worker enum BlockFlags
3523*35238bceSAndroid Build Coastguard Worker {
3524*35238bceSAndroid Build Coastguard Worker     BLOCKFLAG_DEFAULT = 0x01,
3525*35238bceSAndroid Build Coastguard Worker     BLOCKFLAG_NAMED   = 0x02,
3526*35238bceSAndroid Build Coastguard Worker     BLOCKFLAG_UNNAMED = 0x04,
3527*35238bceSAndroid Build Coastguard Worker     BLOCKFLAG_ARRAY   = 0x08,
3528*35238bceSAndroid Build Coastguard Worker 
3529*35238bceSAndroid Build Coastguard Worker     BLOCKFLAG_ALL = 0x0F
3530*35238bceSAndroid Build Coastguard Worker };
3531*35238bceSAndroid Build Coastguard Worker 
generateUniformCaseBlocks(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,uint32_t blockFlags,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup * const))3532*35238bceSAndroid Build Coastguard Worker static void generateUniformCaseBlocks(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
3533*35238bceSAndroid Build Coastguard Worker                                       tcu::TestCaseGroup *const targetGroup, uint32_t blockFlags,
3534*35238bceSAndroid Build Coastguard Worker                                       void (*blockContentGenerator)(Context &,
3535*35238bceSAndroid Build Coastguard Worker                                                                     const ResourceDefinition::Node::SharedPtr &,
3536*35238bceSAndroid Build Coastguard Worker                                                                     tcu::TestCaseGroup *const))
3537*35238bceSAndroid Build Coastguard Worker {
3538*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
3539*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr uniform(
3540*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3541*35238bceSAndroid Build Coastguard Worker 
3542*35238bceSAndroid Build Coastguard Worker     // .default_block
3543*35238bceSAndroid Build Coastguard Worker     if (blockFlags & BLOCKFLAG_DEFAULT)
3544*35238bceSAndroid Build Coastguard Worker     {
3545*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
3546*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3547*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3548*35238bceSAndroid Build Coastguard Worker 
3549*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, uniform, blockGroup);
3550*35238bceSAndroid Build Coastguard Worker     }
3551*35238bceSAndroid Build Coastguard Worker 
3552*35238bceSAndroid Build Coastguard Worker     // .named_block
3553*35238bceSAndroid Build Coastguard Worker     if (blockFlags & BLOCKFLAG_NAMED)
3554*35238bceSAndroid Build Coastguard Worker     {
3555*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3556*35238bceSAndroid Build Coastguard Worker 
3557*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
3558*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3559*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3560*35238bceSAndroid Build Coastguard Worker 
3561*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, block, blockGroup);
3562*35238bceSAndroid Build Coastguard Worker     }
3563*35238bceSAndroid Build Coastguard Worker 
3564*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
3565*35238bceSAndroid Build Coastguard Worker     if (blockFlags & BLOCKFLAG_UNNAMED)
3566*35238bceSAndroid Build Coastguard Worker     {
3567*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3568*35238bceSAndroid Build Coastguard Worker 
3569*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
3570*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3571*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3572*35238bceSAndroid Build Coastguard Worker 
3573*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, block, blockGroup);
3574*35238bceSAndroid Build Coastguard Worker     }
3575*35238bceSAndroid Build Coastguard Worker 
3576*35238bceSAndroid Build Coastguard Worker     // .block_array
3577*35238bceSAndroid Build Coastguard Worker     if (blockFlags & BLOCKFLAG_ARRAY)
3578*35238bceSAndroid Build Coastguard Worker     {
3579*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(uniform));
3580*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
3581*35238bceSAndroid Build Coastguard Worker 
3582*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
3583*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3584*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
3585*35238bceSAndroid Build Coastguard Worker 
3586*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, block, blockGroup);
3587*35238bceSAndroid Build Coastguard Worker     }
3588*35238bceSAndroid Build Coastguard Worker }
3589*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedResourceListBlockContentCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,ProgramInterface interface,int depth)3590*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedResourceListBlockContentCases(
3591*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup,
3592*35238bceSAndroid Build Coastguard Worker     ProgramInterface interface, int depth)
3593*35238bceSAndroid Build Coastguard Worker {
3594*35238bceSAndroid Build Coastguard Worker     // variable
3595*35238bceSAndroid Build Coastguard Worker     {
3596*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
3597*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3598*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3599*35238bceSAndroid Build Coastguard Worker     }
3600*35238bceSAndroid Build Coastguard Worker 
3601*35238bceSAndroid Build Coastguard Worker     // struct
3602*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
3603*35238bceSAndroid Build Coastguard Worker     {
3604*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3605*35238bceSAndroid Build Coastguard Worker         generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3606*35238bceSAndroid Build Coastguard Worker     }
3607*35238bceSAndroid Build Coastguard Worker 
3608*35238bceSAndroid Build Coastguard Worker     // array
3609*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
3610*35238bceSAndroid Build Coastguard Worker     {
3611*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3612*35238bceSAndroid Build Coastguard Worker         generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3613*35238bceSAndroid Build Coastguard Worker     }
3614*35238bceSAndroid Build Coastguard Worker }
3615*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedVariableAggregateTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,ProgramInterface interface,ProgramResourcePropFlags targetProp,glu::DataType dataType,const std::string & nameSuffix,int depth)3616*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedVariableAggregateTypeCases(Context &context,
3617*35238bceSAndroid Build Coastguard Worker                                                            const ResourceDefinition::Node::SharedPtr &parentStructure,
3618*35238bceSAndroid Build Coastguard Worker                                                            tcu::TestCaseGroup *const targetGroup,
3619*35238bceSAndroid Build Coastguard Worker                                                            ProgramInterface interface,
3620*35238bceSAndroid Build Coastguard Worker                                                            ProgramResourcePropFlags targetProp, glu::DataType dataType,
3621*35238bceSAndroid Build Coastguard Worker                                                            const std::string &nameSuffix, int depth)
3622*35238bceSAndroid Build Coastguard Worker {
3623*35238bceSAndroid Build Coastguard Worker     // variable
3624*35238bceSAndroid Build Coastguard Worker     {
3625*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3626*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3627*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3628*35238bceSAndroid Build Coastguard Worker     }
3629*35238bceSAndroid Build Coastguard Worker 
3630*35238bceSAndroid Build Coastguard Worker     // struct
3631*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
3632*35238bceSAndroid Build Coastguard Worker     {
3633*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3634*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp,
3635*35238bceSAndroid Build Coastguard Worker                                                        dataType, "_struct" + nameSuffix, depth - 1);
3636*35238bceSAndroid Build Coastguard Worker     }
3637*35238bceSAndroid Build Coastguard Worker 
3638*35238bceSAndroid Build Coastguard Worker     // array
3639*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
3640*35238bceSAndroid Build Coastguard Worker     {
3641*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3642*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp,
3643*35238bceSAndroid Build Coastguard Worker                                                        dataType, "_array" + nameSuffix, depth - 1);
3644*35238bceSAndroid Build Coastguard Worker     }
3645*35238bceSAndroid Build Coastguard Worker }
3646*35238bceSAndroid Build Coastguard Worker 
generateUniformResourceListBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3647*35238bceSAndroid Build Coastguard Worker static void generateUniformResourceListBlockContents(Context &context,
3648*35238bceSAndroid Build Coastguard Worker                                                      const ResourceDefinition::Node::SharedPtr &parentStructure,
3649*35238bceSAndroid Build Coastguard Worker                                                      tcu::TestCaseGroup *const targetGroup)
3650*35238bceSAndroid Build Coastguard Worker {
3651*35238bceSAndroid Build Coastguard Worker     generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM,
3652*35238bceSAndroid Build Coastguard Worker                                                       4);
3653*35238bceSAndroid Build Coastguard Worker }
3654*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockArraySizeContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3655*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockArraySizeContents(Context &context,
3656*35238bceSAndroid Build Coastguard Worker                                                   const ResourceDefinition::Node::SharedPtr &parentStructure,
3657*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *const targetGroup)
3658*35238bceSAndroid Build Coastguard Worker {
3659*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3660*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3661*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
3662*35238bceSAndroid Build Coastguard Worker         isInterfaceBlock && static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
3663*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3664*35238bceSAndroid Build Coastguard Worker 
3665*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock || namedNonArrayBlock)
3666*35238bceSAndroid Build Coastguard Worker     {
3667*35238bceSAndroid Build Coastguard Worker         // .types
3668*35238bceSAndroid Build Coastguard Worker         {
3669*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3670*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3671*35238bceSAndroid Build Coastguard Worker 
3672*35238bceSAndroid Build Coastguard Worker             generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3673*35238bceSAndroid Build Coastguard Worker             generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3674*35238bceSAndroid Build Coastguard Worker         }
3675*35238bceSAndroid Build Coastguard Worker 
3676*35238bceSAndroid Build Coastguard Worker         // aggregates
3677*35238bceSAndroid Build Coastguard Worker         {
3678*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
3679*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3680*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3681*35238bceSAndroid Build Coastguard Worker 
3682*35238bceSAndroid Build Coastguard Worker             generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface,
3683*35238bceSAndroid Build Coastguard Worker                                                            PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3684*35238bceSAndroid Build Coastguard Worker         }
3685*35238bceSAndroid Build Coastguard Worker     }
3686*35238bceSAndroid Build Coastguard Worker     else
3687*35238bceSAndroid Build Coastguard Worker     {
3688*35238bceSAndroid Build Coastguard Worker         // aggregates
3689*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface,
3690*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3691*35238bceSAndroid Build Coastguard Worker     }
3692*35238bceSAndroid Build Coastguard Worker }
3693*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedArrayStrideTypeAggregateSubCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const std::string & namePrefix,ProgramInterface interface,glu::DataType type,int expandLevel)3694*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedArrayStrideTypeAggregateSubCases(
3695*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup,
3696*35238bceSAndroid Build Coastguard Worker     const std::string &namePrefix, ProgramInterface interface, glu::DataType type, int expandLevel)
3697*35238bceSAndroid Build Coastguard Worker {
3698*35238bceSAndroid Build Coastguard Worker     // case
3699*35238bceSAndroid Build Coastguard Worker     {
3700*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3701*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3702*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE),
3703*35238bceSAndroid Build Coastguard Worker             namePrefix.c_str()));
3704*35238bceSAndroid Build Coastguard Worker     }
3705*35238bceSAndroid Build Coastguard Worker 
3706*35238bceSAndroid Build Coastguard Worker     if (expandLevel > 0)
3707*35238bceSAndroid Build Coastguard Worker     {
3708*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3709*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3710*35238bceSAndroid Build Coastguard Worker 
3711*35238bceSAndroid Build Coastguard Worker         // _struct
3712*35238bceSAndroid Build Coastguard Worker         generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct",
3713*35238bceSAndroid Build Coastguard Worker                                                              interface, type, expandLevel - 1);
3714*35238bceSAndroid Build Coastguard Worker 
3715*35238bceSAndroid Build Coastguard Worker         // _array
3716*35238bceSAndroid Build Coastguard Worker         generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array",
3717*35238bceSAndroid Build Coastguard Worker                                                              interface, type, expandLevel - 1);
3718*35238bceSAndroid Build Coastguard Worker     }
3719*35238bceSAndroid Build Coastguard Worker }
3720*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedArrayStrideTypeAggregateCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,ProgramInterface interface,glu::DataType type,int expandLevel,bool includeBaseCase)3721*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedArrayStrideTypeAggregateCases(
3722*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup,
3723*35238bceSAndroid Build Coastguard Worker     ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3724*35238bceSAndroid Build Coastguard Worker {
3725*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3726*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3727*35238bceSAndroid Build Coastguard Worker     const std::string namePrefix = glu::getDataTypeName(type);
3728*35238bceSAndroid Build Coastguard Worker 
3729*35238bceSAndroid Build Coastguard Worker     if (expandLevel == 0 || includeBaseCase)
3730*35238bceSAndroid Build Coastguard Worker     {
3731*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3732*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3733*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE),
3734*35238bceSAndroid Build Coastguard Worker             namePrefix.c_str()));
3735*35238bceSAndroid Build Coastguard Worker     }
3736*35238bceSAndroid Build Coastguard Worker     if (expandLevel >= 1)
3737*35238bceSAndroid Build Coastguard Worker     {
3738*35238bceSAndroid Build Coastguard Worker         // _struct
3739*35238bceSAndroid Build Coastguard Worker         if (!glu::isDataTypeAtomicCounter(type))
3740*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateSubCases(
3741*35238bceSAndroid Build Coastguard Worker                 context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3742*35238bceSAndroid Build Coastguard Worker 
3743*35238bceSAndroid Build Coastguard Worker         // _array
3744*35238bceSAndroid Build Coastguard Worker         generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array",
3745*35238bceSAndroid Build Coastguard Worker                                                              interface, type, expandLevel - 1);
3746*35238bceSAndroid Build Coastguard Worker     }
3747*35238bceSAndroid Build Coastguard Worker }
3748*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockArrayStrideContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3749*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockArrayStrideContents(Context &context,
3750*35238bceSAndroid Build Coastguard Worker                                                     const ResourceDefinition::Node::SharedPtr &parentStructure,
3751*35238bceSAndroid Build Coastguard Worker                                                     tcu::TestCaseGroup *const targetGroup)
3752*35238bceSAndroid Build Coastguard Worker {
3753*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3754*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3755*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
3756*35238bceSAndroid Build Coastguard Worker         isInterfaceBlock && static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
3757*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3758*35238bceSAndroid Build Coastguard Worker 
3759*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock || namedNonArrayBlock)
3760*35238bceSAndroid Build Coastguard Worker     {
3761*35238bceSAndroid Build Coastguard Worker         // .types
3762*35238bceSAndroid Build Coastguard Worker         {
3763*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3764*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3765*35238bceSAndroid Build Coastguard Worker 
3766*35238bceSAndroid Build Coastguard Worker             generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3767*35238bceSAndroid Build Coastguard Worker             generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3768*35238bceSAndroid Build Coastguard Worker         }
3769*35238bceSAndroid Build Coastguard Worker 
3770*35238bceSAndroid Build Coastguard Worker         // .aggregates
3771*35238bceSAndroid Build Coastguard Worker         {
3772*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
3773*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3774*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3775*35238bceSAndroid Build Coastguard Worker 
3776*35238bceSAndroid Build Coastguard Worker             // .sampler_2d_*
3777*35238bceSAndroid Build Coastguard Worker             if (!isInterfaceBlock)
3778*35238bceSAndroid Build Coastguard Worker                 generateBufferBackedArrayStrideTypeAggregateCases(
3779*35238bceSAndroid Build Coastguard Worker                     context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3780*35238bceSAndroid Build Coastguard Worker 
3781*35238bceSAndroid Build Coastguard Worker             // .atomic_counter_*
3782*35238bceSAndroid Build Coastguard Worker             if (!isInterfaceBlock)
3783*35238bceSAndroid Build Coastguard Worker             {
3784*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr layout(
3785*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3786*35238bceSAndroid Build Coastguard Worker                 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface,
3787*35238bceSAndroid Build Coastguard Worker                                                                   glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3788*35238bceSAndroid Build Coastguard Worker             }
3789*35238bceSAndroid Build Coastguard Worker 
3790*35238bceSAndroid Build Coastguard Worker             // .float_*
3791*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup,
3792*35238bceSAndroid Build Coastguard Worker                                                               queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3793*35238bceSAndroid Build Coastguard Worker 
3794*35238bceSAndroid Build Coastguard Worker             // .bool_*
3795*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup,
3796*35238bceSAndroid Build Coastguard Worker                                                               queryTarget.interface, glu::TYPE_BOOL, 1, false);
3797*35238bceSAndroid Build Coastguard Worker 
3798*35238bceSAndroid Build Coastguard Worker             // .bvec3_*
3799*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup,
3800*35238bceSAndroid Build Coastguard Worker                                                               queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3801*35238bceSAndroid Build Coastguard Worker 
3802*35238bceSAndroid Build Coastguard Worker             // .vec3_*
3803*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup,
3804*35238bceSAndroid Build Coastguard Worker                                                               queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3805*35238bceSAndroid Build Coastguard Worker 
3806*35238bceSAndroid Build Coastguard Worker             // .ivec2_*
3807*35238bceSAndroid Build Coastguard Worker             generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup,
3808*35238bceSAndroid Build Coastguard Worker                                                               queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3809*35238bceSAndroid Build Coastguard Worker         }
3810*35238bceSAndroid Build Coastguard Worker     }
3811*35238bceSAndroid Build Coastguard Worker     else
3812*35238bceSAndroid Build Coastguard Worker     {
3813*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3814*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3815*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3816*35238bceSAndroid Build Coastguard Worker     }
3817*35238bceSAndroid Build Coastguard Worker }
3818*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockLocationContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3819*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockLocationContents(Context &context,
3820*35238bceSAndroid Build Coastguard Worker                                                  const ResourceDefinition::Node::SharedPtr &parentStructure,
3821*35238bceSAndroid Build Coastguard Worker                                                  tcu::TestCaseGroup *const targetGroup)
3822*35238bceSAndroid Build Coastguard Worker {
3823*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3824*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3825*35238bceSAndroid Build Coastguard Worker 
3826*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock)
3827*35238bceSAndroid Build Coastguard Worker     {
3828*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3829*35238bceSAndroid Build Coastguard Worker         generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3830*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3831*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3832*35238bceSAndroid Build Coastguard Worker     }
3833*35238bceSAndroid Build Coastguard Worker     else
3834*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3835*35238bceSAndroid Build Coastguard Worker }
3836*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockBlockIndexContents(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion)3837*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockBlockIndexContents(Context &context, tcu::TestCaseGroup *const targetGroup,
3838*35238bceSAndroid Build Coastguard Worker                                                    glu::GLSLVersion glslVersion)
3839*35238bceSAndroid Build Coastguard Worker {
3840*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
3841*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
3842*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
3843*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
3844*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr uniform(
3845*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3846*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr binding(
3847*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3848*35238bceSAndroid Build Coastguard Worker 
3849*35238bceSAndroid Build Coastguard Worker     // .default_block
3850*35238bceSAndroid Build Coastguard Worker     {
3851*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
3852*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3853*35238bceSAndroid Build Coastguard Worker 
3854*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3855*35238bceSAndroid Build Coastguard Worker             context, variable,
3856*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX),
3857*35238bceSAndroid Build Coastguard Worker             "default_block"));
3858*35238bceSAndroid Build Coastguard Worker     }
3859*35238bceSAndroid Build Coastguard Worker 
3860*35238bceSAndroid Build Coastguard Worker     // .named_block
3861*35238bceSAndroid Build Coastguard Worker     {
3862*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, true));
3863*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
3864*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3865*35238bceSAndroid Build Coastguard Worker 
3866*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3867*35238bceSAndroid Build Coastguard Worker             context, variable,
3868*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3869*35238bceSAndroid Build Coastguard Worker     }
3870*35238bceSAndroid Build Coastguard Worker 
3871*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
3872*35238bceSAndroid Build Coastguard Worker     {
3873*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, false));
3874*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
3875*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3876*35238bceSAndroid Build Coastguard Worker 
3877*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3878*35238bceSAndroid Build Coastguard Worker             context, variable,
3879*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX),
3880*35238bceSAndroid Build Coastguard Worker             "unnamed_block"));
3881*35238bceSAndroid Build Coastguard Worker     }
3882*35238bceSAndroid Build Coastguard Worker 
3883*35238bceSAndroid Build Coastguard Worker     // .block_array
3884*35238bceSAndroid Build Coastguard Worker     {
3885*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding));
3886*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(arrayElement, true));
3887*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
3888*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3889*35238bceSAndroid Build Coastguard Worker 
3890*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
3891*35238bceSAndroid Build Coastguard Worker             context, variable,
3892*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3893*35238bceSAndroid Build Coastguard Worker     }
3894*35238bceSAndroid Build Coastguard Worker }
3895*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockAtomicCounterBufferIndexContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3896*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockAtomicCounterBufferIndexContents(
3897*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup)
3898*35238bceSAndroid Build Coastguard Worker {
3899*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM,
3900*35238bceSAndroid Build Coastguard Worker                                                      PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3901*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3902*35238bceSAndroid Build Coastguard Worker 
3903*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock)
3904*35238bceSAndroid Build Coastguard Worker     {
3905*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3906*35238bceSAndroid Build Coastguard Worker         generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3907*35238bceSAndroid Build Coastguard Worker 
3908*35238bceSAndroid Build Coastguard Worker         // .array
3909*35238bceSAndroid Build Coastguard Worker         {
3910*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(
3911*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(parentStructure));
3912*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayArrayElement(
3913*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(arrayElement));
3914*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
3915*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3916*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr elementvariable(
3917*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3918*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3919*35238bceSAndroid Build Coastguard Worker 
3920*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3921*35238bceSAndroid Build Coastguard Worker 
3922*35238bceSAndroid Build Coastguard Worker             blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3923*35238bceSAndroid Build Coastguard Worker             blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3924*35238bceSAndroid Build Coastguard Worker         }
3925*35238bceSAndroid Build Coastguard Worker     }
3926*35238bceSAndroid Build Coastguard Worker     else
3927*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3928*35238bceSAndroid Build Coastguard Worker }
3929*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockNameLengthContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3930*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockNameLengthContents(Context &context,
3931*35238bceSAndroid Build Coastguard Worker                                                    const ResourceDefinition::Node::SharedPtr &parentStructure,
3932*35238bceSAndroid Build Coastguard Worker                                                    tcu::TestCaseGroup *const targetGroup)
3933*35238bceSAndroid Build Coastguard Worker {
3934*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3935*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
3936*35238bceSAndroid Build Coastguard Worker         isInterfaceBlock && static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
3937*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3938*35238bceSAndroid Build Coastguard Worker 
3939*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock || namedNonArrayBlock)
3940*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM,
3941*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3942*35238bceSAndroid Build Coastguard Worker     else
3943*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM,
3944*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3945*35238bceSAndroid Build Coastguard Worker }
3946*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockTypeContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3947*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockTypeContents(Context &context,
3948*35238bceSAndroid Build Coastguard Worker                                              const ResourceDefinition::Node::SharedPtr &parentStructure,
3949*35238bceSAndroid Build Coastguard Worker                                              tcu::TestCaseGroup *const targetGroup)
3950*35238bceSAndroid Build Coastguard Worker {
3951*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3952*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3953*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
3954*35238bceSAndroid Build Coastguard Worker         isInterfaceBlock && static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
3955*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3956*35238bceSAndroid Build Coastguard Worker 
3957*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock || namedNonArrayBlock)
3958*35238bceSAndroid Build Coastguard Worker     {
3959*35238bceSAndroid Build Coastguard Worker         // .types
3960*35238bceSAndroid Build Coastguard Worker         {
3961*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3962*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3963*35238bceSAndroid Build Coastguard Worker 
3964*35238bceSAndroid Build Coastguard Worker             generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3965*35238bceSAndroid Build Coastguard Worker             generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3966*35238bceSAndroid Build Coastguard Worker         }
3967*35238bceSAndroid Build Coastguard Worker 
3968*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3969*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3970*35238bceSAndroid Build Coastguard Worker     }
3971*35238bceSAndroid Build Coastguard Worker     else
3972*35238bceSAndroid Build Coastguard Worker     {
3973*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3974*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3975*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3976*35238bceSAndroid Build Coastguard Worker     }
3977*35238bceSAndroid Build Coastguard Worker }
3978*35238bceSAndroid Build Coastguard Worker 
generateUniformBlockOffsetContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)3979*35238bceSAndroid Build Coastguard Worker static void generateUniformBlockOffsetContents(Context &context,
3980*35238bceSAndroid Build Coastguard Worker                                                const ResourceDefinition::Node::SharedPtr &parentStructure,
3981*35238bceSAndroid Build Coastguard Worker                                                tcu::TestCaseGroup *const targetGroup)
3982*35238bceSAndroid Build Coastguard Worker {
3983*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3984*35238bceSAndroid Build Coastguard Worker     const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3985*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
3986*35238bceSAndroid Build Coastguard Worker         isInterfaceBlock && static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
3987*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3988*35238bceSAndroid Build Coastguard Worker 
3989*35238bceSAndroid Build Coastguard Worker     if (!isInterfaceBlock)
3990*35238bceSAndroid Build Coastguard Worker     {
3991*35238bceSAndroid Build Coastguard Worker         // .types
3992*35238bceSAndroid Build Coastguard Worker         {
3993*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3994*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
3995*35238bceSAndroid Build Coastguard Worker 
3996*35238bceSAndroid Build Coastguard Worker             generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3997*35238bceSAndroid Build Coastguard Worker             generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3998*35238bceSAndroid Build Coastguard Worker         }
3999*35238bceSAndroid Build Coastguard Worker 
4000*35238bceSAndroid Build Coastguard Worker         // .aggregates
4001*35238bceSAndroid Build Coastguard Worker         {
4002*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
4003*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
4004*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
4005*35238bceSAndroid Build Coastguard Worker 
4006*35238bceSAndroid Build Coastguard Worker             // .atomic_uint_struct
4007*35238bceSAndroid Build Coastguard Worker             // .atomic_uint_array
4008*35238bceSAndroid Build Coastguard Worker             {
4009*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr offset(
4010*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
4011*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(offset));
4012*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr elementVariable(
4013*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4014*35238bceSAndroid Build Coastguard Worker 
4015*35238bceSAndroid Build Coastguard Worker                 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
4016*35238bceSAndroid Build Coastguard Worker             }
4017*35238bceSAndroid Build Coastguard Worker 
4018*35238bceSAndroid Build Coastguard Worker             // .float_array
4019*35238bceSAndroid Build Coastguard Worker             // .float_struct
4020*35238bceSAndroid Build Coastguard Worker             {
4021*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr structMember(
4022*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::StructMember(parentStructure));
4023*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr arrayElement(
4024*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::ArrayElement(parentStructure));
4025*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr memberVariable(
4026*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4027*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr elementVariable(
4028*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4029*35238bceSAndroid Build Coastguard Worker 
4030*35238bceSAndroid Build Coastguard Worker                 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
4031*35238bceSAndroid Build Coastguard Worker                 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
4032*35238bceSAndroid Build Coastguard Worker             }
4033*35238bceSAndroid Build Coastguard Worker         }
4034*35238bceSAndroid Build Coastguard Worker     }
4035*35238bceSAndroid Build Coastguard Worker     else if (namedNonArrayBlock)
4036*35238bceSAndroid Build Coastguard Worker     {
4037*35238bceSAndroid Build Coastguard Worker         // .types
4038*35238bceSAndroid Build Coastguard Worker         {
4039*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
4040*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
4041*35238bceSAndroid Build Coastguard Worker 
4042*35238bceSAndroid Build Coastguard Worker             generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
4043*35238bceSAndroid Build Coastguard Worker             generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
4044*35238bceSAndroid Build Coastguard Worker         }
4045*35238bceSAndroid Build Coastguard Worker 
4046*35238bceSAndroid Build Coastguard Worker         // .aggregates
4047*35238bceSAndroid Build Coastguard Worker         {
4048*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
4049*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
4050*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
4051*35238bceSAndroid Build Coastguard Worker 
4052*35238bceSAndroid Build Coastguard Worker             // .float_array
4053*35238bceSAndroid Build Coastguard Worker             // .float_struct
4054*35238bceSAndroid Build Coastguard Worker             {
4055*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr structMember(
4056*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::StructMember(parentStructure));
4057*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr arrayElement(
4058*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::StructMember(parentStructure));
4059*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr memberVariable(
4060*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4061*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr elementVariable(
4062*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4063*35238bceSAndroid Build Coastguard Worker 
4064*35238bceSAndroid Build Coastguard Worker                 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
4065*35238bceSAndroid Build Coastguard Worker                 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
4066*35238bceSAndroid Build Coastguard Worker             }
4067*35238bceSAndroid Build Coastguard Worker         }
4068*35238bceSAndroid Build Coastguard Worker     }
4069*35238bceSAndroid Build Coastguard Worker     else
4070*35238bceSAndroid Build Coastguard Worker     {
4071*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
4072*35238bceSAndroid Build Coastguard Worker         generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
4073*35238bceSAndroid Build Coastguard Worker         generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
4074*35238bceSAndroid Build Coastguard Worker     }
4075*35238bceSAndroid Build Coastguard Worker }
4076*35238bceSAndroid Build Coastguard Worker 
generateMatrixVariableCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,bool createTestGroup=true,int expandLevel=2)4077*35238bceSAndroid Build Coastguard Worker static void generateMatrixVariableCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
4078*35238bceSAndroid Build Coastguard Worker                                         tcu::TestCaseGroup *const targetGroup,
4079*35238bceSAndroid Build Coastguard Worker                                         const ProgramResourceQueryTestTarget &queryTarget, bool createTestGroup = true,
4080*35238bceSAndroid Build Coastguard Worker                                         int expandLevel = 2)
4081*35238bceSAndroid Build Coastguard Worker {
4082*35238bceSAndroid Build Coastguard Worker     static const struct
4083*35238bceSAndroid Build Coastguard Worker     {
4084*35238bceSAndroid Build Coastguard Worker         int priority;
4085*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
4086*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
4087*35238bceSAndroid Build Coastguard Worker         {0, glu::TYPE_FLOAT_MAT2},   {1, glu::TYPE_FLOAT_MAT2X3}, {2, glu::TYPE_FLOAT_MAT2X4},
4088*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT3X2}, {1, glu::TYPE_FLOAT_MAT3},   {0, glu::TYPE_FLOAT_MAT3X4},
4089*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT4X2}, {1, glu::TYPE_FLOAT_MAT4X3}, {0, glu::TYPE_FLOAT_MAT4},
4090*35238bceSAndroid Build Coastguard Worker     };
4091*35238bceSAndroid Build Coastguard Worker 
4092*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *group;
4093*35238bceSAndroid Build Coastguard Worker 
4094*35238bceSAndroid Build Coastguard Worker     if (createTestGroup)
4095*35238bceSAndroid Build Coastguard Worker     {
4096*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
4097*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
4098*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4099*35238bceSAndroid Build Coastguard Worker         group = blockGroup;
4100*35238bceSAndroid Build Coastguard Worker     }
4101*35238bceSAndroid Build Coastguard Worker     else
4102*35238bceSAndroid Build Coastguard Worker         group = targetGroup;
4103*35238bceSAndroid Build Coastguard Worker 
4104*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
4105*35238bceSAndroid Build Coastguard Worker     {
4106*35238bceSAndroid Build Coastguard Worker         if (variableTypes[ndx].priority < expandLevel)
4107*35238bceSAndroid Build Coastguard Worker         {
4108*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
4109*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
4110*35238bceSAndroid Build Coastguard Worker             group->addChild(new ResourceTestCase(context, variable, queryTarget));
4111*35238bceSAndroid Build Coastguard Worker         }
4112*35238bceSAndroid Build Coastguard Worker     }
4113*35238bceSAndroid Build Coastguard Worker }
4114*35238bceSAndroid Build Coastguard Worker 
4115*35238bceSAndroid Build Coastguard Worker static void generateMatrixStructCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
4116*35238bceSAndroid Build Coastguard Worker                                       tcu::TestCaseGroup *const targetGroup,
4117*35238bceSAndroid Build Coastguard Worker                                       const ProgramResourceQueryTestTarget &queryTarget, int expandLevel);
4118*35238bceSAndroid Build Coastguard Worker 
generateMatrixArrayCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel)4119*35238bceSAndroid Build Coastguard Worker static void generateMatrixArrayCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
4120*35238bceSAndroid Build Coastguard Worker                                      tcu::TestCaseGroup *const targetGroup,
4121*35238bceSAndroid Build Coastguard Worker                                      const ProgramResourceQueryTestTarget &queryTarget, int expandLevel)
4122*35238bceSAndroid Build Coastguard Worker {
4123*35238bceSAndroid Build Coastguard Worker     if (expandLevel > 0)
4124*35238bceSAndroid Build Coastguard Worker     {
4125*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
4126*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
4127*35238bceSAndroid Build Coastguard Worker 
4128*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4129*35238bceSAndroid Build Coastguard Worker 
4130*35238bceSAndroid Build Coastguard Worker         // Arrays of basic variables
4131*35238bceSAndroid Build Coastguard Worker         generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
4132*35238bceSAndroid Build Coastguard Worker 
4133*35238bceSAndroid Build Coastguard Worker         // Arrays of arrays
4134*35238bceSAndroid Build Coastguard Worker         generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel - 1);
4135*35238bceSAndroid Build Coastguard Worker 
4136*35238bceSAndroid Build Coastguard Worker         // Arrays of structs
4137*35238bceSAndroid Build Coastguard Worker         generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel - 1);
4138*35238bceSAndroid Build Coastguard Worker     }
4139*35238bceSAndroid Build Coastguard Worker }
4140*35238bceSAndroid Build Coastguard Worker 
generateMatrixStructCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,int expandLevel)4141*35238bceSAndroid Build Coastguard Worker static void generateMatrixStructCases(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
4142*35238bceSAndroid Build Coastguard Worker                                       tcu::TestCaseGroup *const targetGroup,
4143*35238bceSAndroid Build Coastguard Worker                                       const ProgramResourceQueryTestTarget &queryTarget, int expandLevel)
4144*35238bceSAndroid Build Coastguard Worker {
4145*35238bceSAndroid Build Coastguard Worker     if (expandLevel > 0)
4146*35238bceSAndroid Build Coastguard Worker     {
4147*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
4148*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
4149*35238bceSAndroid Build Coastguard Worker 
4150*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4151*35238bceSAndroid Build Coastguard Worker 
4152*35238bceSAndroid Build Coastguard Worker         // Struct containing basic variable
4153*35238bceSAndroid Build Coastguard Worker         generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
4154*35238bceSAndroid Build Coastguard Worker 
4155*35238bceSAndroid Build Coastguard Worker         // Struct containing arrays
4156*35238bceSAndroid Build Coastguard Worker         generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel - 1);
4157*35238bceSAndroid Build Coastguard Worker 
4158*35238bceSAndroid Build Coastguard Worker         // Struct containing struct
4159*35238bceSAndroid Build Coastguard Worker         generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel - 1);
4160*35238bceSAndroid Build Coastguard Worker     }
4161*35238bceSAndroid Build Coastguard Worker }
4162*35238bceSAndroid Build Coastguard Worker 
generateUniformMatrixOrderCaseBlockContentCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,bool extendedBasicTypeCases,bool opaqueCases)4163*35238bceSAndroid Build Coastguard Worker static void generateUniformMatrixOrderCaseBlockContentCases(Context &context,
4164*35238bceSAndroid Build Coastguard Worker                                                             const ResourceDefinition::Node::SharedPtr &parentStructure,
4165*35238bceSAndroid Build Coastguard Worker                                                             tcu::TestCaseGroup *const targetGroup,
4166*35238bceSAndroid Build Coastguard Worker                                                             bool extendedBasicTypeCases, bool opaqueCases)
4167*35238bceSAndroid Build Coastguard Worker {
4168*35238bceSAndroid Build Coastguard Worker     static const struct
4169*35238bceSAndroid Build Coastguard Worker     {
4170*35238bceSAndroid Build Coastguard Worker         const char *name;
4171*35238bceSAndroid Build Coastguard Worker         glu::MatrixOrder order;
4172*35238bceSAndroid Build Coastguard Worker     } qualifiers[] = {
4173*35238bceSAndroid Build Coastguard Worker         {"no_qualifier", glu::MATRIXORDER_LAST},
4174*35238bceSAndroid Build Coastguard Worker         {"row_major", glu::MATRIXORDER_ROW_MAJOR},
4175*35238bceSAndroid Build Coastguard Worker         {"column_major", glu::MATRIXORDER_COLUMN_MAJOR},
4176*35238bceSAndroid Build Coastguard Worker     };
4177*35238bceSAndroid Build Coastguard Worker 
4178*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
4179*35238bceSAndroid Build Coastguard Worker 
4180*35238bceSAndroid Build Coastguard Worker     for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
4181*35238bceSAndroid Build Coastguard Worker     {
4182*35238bceSAndroid Build Coastguard Worker         // Add layout qualifiers only for block members
4183*35238bceSAndroid Build Coastguard Worker         if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST ||
4184*35238bceSAndroid Build Coastguard Worker             parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
4185*35238bceSAndroid Build Coastguard Worker         {
4186*35238bceSAndroid Build Coastguard Worker             ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
4187*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const qualifierGroup =
4188*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
4189*35238bceSAndroid Build Coastguard Worker 
4190*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(qualifierGroup);
4191*35238bceSAndroid Build Coastguard Worker 
4192*35238bceSAndroid Build Coastguard Worker             if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
4193*35238bceSAndroid Build Coastguard Worker             {
4194*35238bceSAndroid Build Coastguard Worker                 glu::Layout layout;
4195*35238bceSAndroid Build Coastguard Worker                 layout.matrixOrder = qualifiers[qualifierNdx].order;
4196*35238bceSAndroid Build Coastguard Worker                 subStructure =
4197*35238bceSAndroid Build Coastguard Worker                     ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4198*35238bceSAndroid Build Coastguard Worker             }
4199*35238bceSAndroid Build Coastguard Worker 
4200*35238bceSAndroid Build Coastguard Worker             if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
4201*35238bceSAndroid Build Coastguard Worker             {
4202*35238bceSAndroid Build Coastguard Worker                 // .types
4203*35238bceSAndroid Build Coastguard Worker                 {
4204*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *const blockGroup =
4205*35238bceSAndroid Build Coastguard Worker                         new tcu::TestCaseGroup(context.getTestContext(), "types", "");
4206*35238bceSAndroid Build Coastguard Worker                     qualifierGroup->addChild(blockGroup);
4207*35238bceSAndroid Build Coastguard Worker 
4208*35238bceSAndroid Build Coastguard Worker                     generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
4209*35238bceSAndroid Build Coastguard Worker                     generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
4210*35238bceSAndroid Build Coastguard Worker                     if (opaqueCases)
4211*35238bceSAndroid Build Coastguard Worker                         generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
4212*35238bceSAndroid Build Coastguard Worker                 }
4213*35238bceSAndroid Build Coastguard Worker 
4214*35238bceSAndroid Build Coastguard Worker                 // .aggregates
4215*35238bceSAndroid Build Coastguard Worker                 {
4216*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *const blockGroup =
4217*35238bceSAndroid Build Coastguard Worker                         new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
4218*35238bceSAndroid Build Coastguard Worker                     qualifierGroup->addChild(blockGroup);
4219*35238bceSAndroid Build Coastguard Worker 
4220*35238bceSAndroid Build Coastguard Worker                     generateBufferBackedVariableAggregateTypeCases(
4221*35238bceSAndroid Build Coastguard Worker                         context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR,
4222*35238bceSAndroid Build Coastguard Worker                         glu::TYPE_FLOAT_MAT3X2, "", 1);
4223*35238bceSAndroid Build Coastguard Worker                 }
4224*35238bceSAndroid Build Coastguard Worker             }
4225*35238bceSAndroid Build Coastguard Worker             else
4226*35238bceSAndroid Build Coastguard Worker             {
4227*35238bceSAndroid Build Coastguard Worker                 generateBufferBackedVariableAggregateTypeCases(
4228*35238bceSAndroid Build Coastguard Worker                     context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR,
4229*35238bceSAndroid Build Coastguard Worker                     glu::TYPE_FLOAT_MAT3X2, "", 1);
4230*35238bceSAndroid Build Coastguard Worker             }
4231*35238bceSAndroid Build Coastguard Worker         }
4232*35238bceSAndroid Build Coastguard Worker     }
4233*35238bceSAndroid Build Coastguard Worker }
4234*35238bceSAndroid Build Coastguard Worker 
generateUniformMatrixStrideCaseBlockContentCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,bool extendedBasicTypeCases,bool opaqueCases)4235*35238bceSAndroid Build Coastguard Worker static void generateUniformMatrixStrideCaseBlockContentCases(Context &context,
4236*35238bceSAndroid Build Coastguard Worker                                                              const ResourceDefinition::Node::SharedPtr &parentStructure,
4237*35238bceSAndroid Build Coastguard Worker                                                              tcu::TestCaseGroup *const targetGroup,
4238*35238bceSAndroid Build Coastguard Worker                                                              bool extendedBasicTypeCases, bool opaqueCases)
4239*35238bceSAndroid Build Coastguard Worker {
4240*35238bceSAndroid Build Coastguard Worker     static const struct
4241*35238bceSAndroid Build Coastguard Worker     {
4242*35238bceSAndroid Build Coastguard Worker         const char *name;
4243*35238bceSAndroid Build Coastguard Worker         glu::MatrixOrder order;
4244*35238bceSAndroid Build Coastguard Worker     } qualifiers[] = {
4245*35238bceSAndroid Build Coastguard Worker         {"no_qualifier", glu::MATRIXORDER_LAST},
4246*35238bceSAndroid Build Coastguard Worker         {"row_major", glu::MATRIXORDER_ROW_MAJOR},
4247*35238bceSAndroid Build Coastguard Worker         {"column_major", glu::MATRIXORDER_COLUMN_MAJOR},
4248*35238bceSAndroid Build Coastguard Worker     };
4249*35238bceSAndroid Build Coastguard Worker 
4250*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
4251*35238bceSAndroid Build Coastguard Worker 
4252*35238bceSAndroid Build Coastguard Worker     for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
4253*35238bceSAndroid Build Coastguard Worker     {
4254*35238bceSAndroid Build Coastguard Worker         // Add layout qualifiers only for block members
4255*35238bceSAndroid Build Coastguard Worker         if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST ||
4256*35238bceSAndroid Build Coastguard Worker             parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
4257*35238bceSAndroid Build Coastguard Worker         {
4258*35238bceSAndroid Build Coastguard Worker             ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
4259*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const qualifierGroup =
4260*35238bceSAndroid Build Coastguard Worker                 new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
4261*35238bceSAndroid Build Coastguard Worker 
4262*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(qualifierGroup);
4263*35238bceSAndroid Build Coastguard Worker 
4264*35238bceSAndroid Build Coastguard Worker             if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
4265*35238bceSAndroid Build Coastguard Worker             {
4266*35238bceSAndroid Build Coastguard Worker                 glu::Layout layout;
4267*35238bceSAndroid Build Coastguard Worker                 layout.matrixOrder = qualifiers[qualifierNdx].order;
4268*35238bceSAndroid Build Coastguard Worker                 subStructure =
4269*35238bceSAndroid Build Coastguard Worker                     ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4270*35238bceSAndroid Build Coastguard Worker             }
4271*35238bceSAndroid Build Coastguard Worker 
4272*35238bceSAndroid Build Coastguard Worker             if (extendedBasicTypeCases)
4273*35238bceSAndroid Build Coastguard Worker             {
4274*35238bceSAndroid Build Coastguard Worker                 // .types
4275*35238bceSAndroid Build Coastguard Worker                 // .matrix
4276*35238bceSAndroid Build Coastguard Worker                 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
4277*35238bceSAndroid Build Coastguard Worker                 {
4278*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *const blockGroup =
4279*35238bceSAndroid Build Coastguard Worker                         new tcu::TestCaseGroup(context.getTestContext(), "types", "");
4280*35238bceSAndroid Build Coastguard Worker                     qualifierGroup->addChild(blockGroup);
4281*35238bceSAndroid Build Coastguard Worker 
4282*35238bceSAndroid Build Coastguard Worker                     generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
4283*35238bceSAndroid Build Coastguard Worker                     generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
4284*35238bceSAndroid Build Coastguard Worker                     if (opaqueCases)
4285*35238bceSAndroid Build Coastguard Worker                         generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
4286*35238bceSAndroid Build Coastguard Worker                 }
4287*35238bceSAndroid Build Coastguard Worker                 else
4288*35238bceSAndroid Build Coastguard Worker                     generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
4289*35238bceSAndroid Build Coastguard Worker 
4290*35238bceSAndroid Build Coastguard Worker                 // .aggregates
4291*35238bceSAndroid Build Coastguard Worker                 {
4292*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *const blockGroup =
4293*35238bceSAndroid Build Coastguard Worker                         new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
4294*35238bceSAndroid Build Coastguard Worker                     qualifierGroup->addChild(blockGroup);
4295*35238bceSAndroid Build Coastguard Worker 
4296*35238bceSAndroid Build Coastguard Worker                     generateBufferBackedVariableAggregateTypeCases(
4297*35238bceSAndroid Build Coastguard Worker                         context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR,
4298*35238bceSAndroid Build Coastguard Worker                         glu::TYPE_FLOAT_MAT3X2, "", 1);
4299*35238bceSAndroid Build Coastguard Worker                 }
4300*35238bceSAndroid Build Coastguard Worker             }
4301*35238bceSAndroid Build Coastguard Worker             else
4302*35238bceSAndroid Build Coastguard Worker                 generateBufferBackedVariableAggregateTypeCases(
4303*35238bceSAndroid Build Coastguard Worker                     context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR,
4304*35238bceSAndroid Build Coastguard Worker                     glu::TYPE_FLOAT_MAT3X2, "", 1);
4305*35238bceSAndroid Build Coastguard Worker         }
4306*35238bceSAndroid Build Coastguard Worker     }
4307*35238bceSAndroid Build Coastguard Worker }
4308*35238bceSAndroid Build Coastguard Worker 
generateUniformMatrixCaseBlocks(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup * const,bool,bool))4309*35238bceSAndroid Build Coastguard Worker static void generateUniformMatrixCaseBlocks(Context &context,
4310*35238bceSAndroid Build Coastguard Worker                                             const ResourceDefinition::Node::SharedPtr &parentStructure,
4311*35238bceSAndroid Build Coastguard Worker                                             tcu::TestCaseGroup *const targetGroup,
4312*35238bceSAndroid Build Coastguard Worker                                             void (*blockContentGenerator)(Context &,
4313*35238bceSAndroid Build Coastguard Worker                                                                           const ResourceDefinition::Node::SharedPtr &,
4314*35238bceSAndroid Build Coastguard Worker                                                                           tcu::TestCaseGroup *const, bool, bool))
4315*35238bceSAndroid Build Coastguard Worker {
4316*35238bceSAndroid Build Coastguard Worker     static const struct
4317*35238bceSAndroid Build Coastguard Worker     {
4318*35238bceSAndroid Build Coastguard Worker         const char *name;
4319*35238bceSAndroid Build Coastguard Worker         const char *description;
4320*35238bceSAndroid Build Coastguard Worker         bool block;
4321*35238bceSAndroid Build Coastguard Worker         bool namedBlock;
4322*35238bceSAndroid Build Coastguard Worker         bool extendedBasicTypeCases;
4323*35238bceSAndroid Build Coastguard Worker         glu::MatrixOrder order;
4324*35238bceSAndroid Build Coastguard Worker     } children[] = {
4325*35238bceSAndroid Build Coastguard Worker         {"default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST},
4326*35238bceSAndroid Build Coastguard Worker         {"named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST},
4327*35238bceSAndroid Build Coastguard Worker         {"named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR},
4328*35238bceSAndroid Build Coastguard Worker         {"named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR},
4329*35238bceSAndroid Build Coastguard Worker         {"unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST},
4330*35238bceSAndroid Build Coastguard Worker         {"unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR},
4331*35238bceSAndroid Build Coastguard Worker         {"unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR},
4332*35238bceSAndroid Build Coastguard Worker     };
4333*35238bceSAndroid Build Coastguard Worker 
4334*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
4335*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr uniform(
4336*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4337*35238bceSAndroid Build Coastguard Worker 
4338*35238bceSAndroid Build Coastguard Worker     for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4339*35238bceSAndroid Build Coastguard Worker     {
4340*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::Node::SharedPtr subStructure = uniform;
4341*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
4342*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4343*35238bceSAndroid Build Coastguard Worker         const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4344*35238bceSAndroid Build Coastguard Worker 
4345*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4346*35238bceSAndroid Build Coastguard Worker 
4347*35238bceSAndroid Build Coastguard Worker         if (children[childNdx].order != glu::MATRIXORDER_LAST)
4348*35238bceSAndroid Build Coastguard Worker         {
4349*35238bceSAndroid Build Coastguard Worker             glu::Layout layout;
4350*35238bceSAndroid Build Coastguard Worker             layout.matrixOrder = children[childNdx].order;
4351*35238bceSAndroid Build Coastguard Worker             subStructure =
4352*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4353*35238bceSAndroid Build Coastguard Worker         }
4354*35238bceSAndroid Build Coastguard Worker 
4355*35238bceSAndroid Build Coastguard Worker         if (children[childNdx].block)
4356*35238bceSAndroid Build Coastguard Worker             subStructure = ResourceDefinition::Node::SharedPtr(
4357*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4358*35238bceSAndroid Build Coastguard Worker 
4359*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases,
4360*35238bceSAndroid Build Coastguard Worker                               addOpaqueCases);
4361*35238bceSAndroid Build Coastguard Worker     }
4362*35238bceSAndroid Build Coastguard Worker }
4363*35238bceSAndroid Build Coastguard Worker 
generateBufferReferencedByShaderInterfaceBlockCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,const ProgramResourceQueryTestTarget & queryTarget,bool extendedCases)4364*35238bceSAndroid Build Coastguard Worker static void generateBufferReferencedByShaderInterfaceBlockCases(
4365*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup,
4366*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget &queryTarget, bool extendedCases)
4367*35238bceSAndroid Build Coastguard Worker {
4368*35238bceSAndroid Build Coastguard Worker     const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4369*35238bceSAndroid Build Coastguard Worker 
4370*35238bceSAndroid Build Coastguard Worker     // .float
4371*35238bceSAndroid Build Coastguard Worker     // .float_array
4372*35238bceSAndroid Build Coastguard Worker     // .float_struct
4373*35238bceSAndroid Build Coastguard Worker     {
4374*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
4375*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4376*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
4377*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
4378*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variableArray(
4379*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4380*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variableStruct(
4381*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4382*35238bceSAndroid Build Coastguard Worker 
4383*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4384*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4385*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4386*35238bceSAndroid Build Coastguard Worker     }
4387*35238bceSAndroid Build Coastguard Worker 
4388*35238bceSAndroid Build Coastguard Worker     // .sampler
4389*35238bceSAndroid Build Coastguard Worker     // .sampler_array
4390*35238bceSAndroid Build Coastguard Worker     // .sampler_struct
4391*35238bceSAndroid Build Coastguard Worker     if (isDefaultBlock)
4392*35238bceSAndroid Build Coastguard Worker     {
4393*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr layout(
4394*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4395*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
4396*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4397*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(layout));
4398*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
4399*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variableArray(
4400*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4401*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variableStruct(
4402*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4403*35238bceSAndroid Build Coastguard Worker 
4404*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4405*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4406*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4407*35238bceSAndroid Build Coastguard Worker     }
4408*35238bceSAndroid Build Coastguard Worker 
4409*35238bceSAndroid Build Coastguard Worker     // .atomic_uint
4410*35238bceSAndroid Build Coastguard Worker     // .atomic_uint_array
4411*35238bceSAndroid Build Coastguard Worker     if (isDefaultBlock)
4412*35238bceSAndroid Build Coastguard Worker     {
4413*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr layout(
4414*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4415*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
4416*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4417*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(layout));
4418*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variableArray(
4419*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4420*35238bceSAndroid Build Coastguard Worker 
4421*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4422*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4423*35238bceSAndroid Build Coastguard Worker     }
4424*35238bceSAndroid Build Coastguard Worker 
4425*35238bceSAndroid Build Coastguard Worker     if (extendedCases)
4426*35238bceSAndroid Build Coastguard Worker     {
4427*35238bceSAndroid Build Coastguard Worker         // .float_array_struct
4428*35238bceSAndroid Build Coastguard Worker         {
4429*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMember(
4430*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::StructMember(parentStructure));
4431*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(structMember));
4432*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variableArrayStruct(
4433*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4434*35238bceSAndroid Build Coastguard Worker 
4435*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(
4436*35238bceSAndroid Build Coastguard Worker                 new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4437*35238bceSAndroid Build Coastguard Worker         }
4438*35238bceSAndroid Build Coastguard Worker 
4439*35238bceSAndroid Build Coastguard Worker         // .float_struct_array
4440*35238bceSAndroid Build Coastguard Worker         {
4441*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(
4442*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(parentStructure));
4443*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayStructMember(
4444*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::StructMember(arrayElement));
4445*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variableArrayStruct(
4446*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4447*35238bceSAndroid Build Coastguard Worker 
4448*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(
4449*35238bceSAndroid Build Coastguard Worker                 new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4450*35238bceSAndroid Build Coastguard Worker         }
4451*35238bceSAndroid Build Coastguard Worker 
4452*35238bceSAndroid Build Coastguard Worker         // .float_array_array
4453*35238bceSAndroid Build Coastguard Worker         {
4454*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(
4455*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(parentStructure));
4456*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr subArrayElement(
4457*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(arrayElement));
4458*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variableArrayStruct(
4459*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4460*35238bceSAndroid Build Coastguard Worker 
4461*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4462*35238bceSAndroid Build Coastguard Worker         }
4463*35238bceSAndroid Build Coastguard Worker 
4464*35238bceSAndroid Build Coastguard Worker         // .float_struct_struct
4465*35238bceSAndroid Build Coastguard Worker         {
4466*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMember(
4467*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::StructMember(parentStructure));
4468*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr subStructMember(
4469*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::StructMember(structMember));
4470*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variableArrayStruct(
4471*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4472*35238bceSAndroid Build Coastguard Worker 
4473*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(
4474*35238bceSAndroid Build Coastguard Worker                 new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4475*35238bceSAndroid Build Coastguard Worker         }
4476*35238bceSAndroid Build Coastguard Worker 
4477*35238bceSAndroid Build Coastguard Worker         if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4478*35238bceSAndroid Build Coastguard Worker         {
4479*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(
4480*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4481*35238bceSAndroid Build Coastguard Worker 
4482*35238bceSAndroid Build Coastguard Worker             // .float_unsized_array
4483*35238bceSAndroid Build Coastguard Worker             {
4484*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr variableArray(
4485*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4486*35238bceSAndroid Build Coastguard Worker 
4487*35238bceSAndroid Build Coastguard Worker                 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4488*35238bceSAndroid Build Coastguard Worker             }
4489*35238bceSAndroid Build Coastguard Worker 
4490*35238bceSAndroid Build Coastguard Worker             // .float_unsized_struct_array
4491*35238bceSAndroid Build Coastguard Worker             {
4492*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr structMember(
4493*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::StructMember(arrayElement));
4494*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr variableArray(
4495*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4496*35238bceSAndroid Build Coastguard Worker 
4497*35238bceSAndroid Build Coastguard Worker                 targetGroup->addChild(
4498*35238bceSAndroid Build Coastguard Worker                     new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4499*35238bceSAndroid Build Coastguard Worker             }
4500*35238bceSAndroid Build Coastguard Worker         }
4501*35238bceSAndroid Build Coastguard Worker     }
4502*35238bceSAndroid Build Coastguard Worker }
4503*35238bceSAndroid Build Coastguard Worker 
generateUniformReferencedByShaderSingleBlockContentCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,int expandLevel)4504*35238bceSAndroid Build Coastguard Worker static void generateUniformReferencedByShaderSingleBlockContentCases(
4505*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup,
4506*35238bceSAndroid Build Coastguard Worker     int expandLevel)
4507*35238bceSAndroid Build Coastguard Worker {
4508*35238bceSAndroid Build Coastguard Worker     DE_UNREF(expandLevel);
4509*35238bceSAndroid Build Coastguard Worker 
4510*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
4511*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr uniform(
4512*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4513*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM,
4514*35238bceSAndroid Build Coastguard Worker                                                      PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4515*35238bceSAndroid Build Coastguard Worker     const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4516*35238bceSAndroid Build Coastguard Worker 
4517*35238bceSAndroid Build Coastguard Worker     // .default_block
4518*35238bceSAndroid Build Coastguard Worker     {
4519*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, "default_block", "");
4520*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4521*35238bceSAndroid Build Coastguard Worker 
4522*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget,
4523*35238bceSAndroid Build Coastguard Worker                                                             singleShaderCase);
4524*35238bceSAndroid Build Coastguard Worker     }
4525*35238bceSAndroid Build Coastguard Worker 
4526*35238bceSAndroid Build Coastguard Worker     // .named_block
4527*35238bceSAndroid Build Coastguard Worker     {
4528*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
4529*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4530*35238bceSAndroid Build Coastguard Worker 
4531*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4532*35238bceSAndroid Build Coastguard Worker 
4533*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4534*35238bceSAndroid Build Coastguard Worker     }
4535*35238bceSAndroid Build Coastguard Worker 
4536*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
4537*35238bceSAndroid Build Coastguard Worker     {
4538*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
4539*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4540*35238bceSAndroid Build Coastguard Worker 
4541*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4542*35238bceSAndroid Build Coastguard Worker 
4543*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4544*35238bceSAndroid Build Coastguard Worker     }
4545*35238bceSAndroid Build Coastguard Worker 
4546*35238bceSAndroid Build Coastguard Worker     // .block_array
4547*35238bceSAndroid Build Coastguard Worker     {
4548*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(uniform));
4549*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4550*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, "block_array", "");
4551*35238bceSAndroid Build Coastguard Worker 
4552*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4553*35238bceSAndroid Build Coastguard Worker 
4554*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4555*35238bceSAndroid Build Coastguard Worker     }
4556*35238bceSAndroid Build Coastguard Worker }
4557*35238bceSAndroid Build Coastguard Worker 
generateReferencedByShaderCaseBlocks(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion,void (* generateBlockContent)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup *,int expandLevel))4558*35238bceSAndroid Build Coastguard Worker static void generateReferencedByShaderCaseBlocks(
4559*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *const targetGroup, glu::GLSLVersion glslVersion,
4560*35238bceSAndroid Build Coastguard Worker     void (*generateBlockContent)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *,
4561*35238bceSAndroid Build Coastguard Worker                                  int expandLevel))
4562*35238bceSAndroid Build Coastguard Worker {
4563*35238bceSAndroid Build Coastguard Worker     static const struct
4564*35238bceSAndroid Build Coastguard Worker     {
4565*35238bceSAndroid Build Coastguard Worker         const char *name;
4566*35238bceSAndroid Build Coastguard Worker         glu::ShaderType stage;
4567*35238bceSAndroid Build Coastguard Worker         int expandLevel;
4568*35238bceSAndroid Build Coastguard Worker     } singleStageCases[] = {
4569*35238bceSAndroid Build Coastguard Worker         {"compute", glu::SHADERTYPE_COMPUTE, 3},
4570*35238bceSAndroid Build Coastguard Worker         {"separable_vertex", glu::SHADERTYPE_VERTEX, 2},
4571*35238bceSAndroid Build Coastguard Worker         {"separable_fragment", glu::SHADERTYPE_FRAGMENT, 2},
4572*35238bceSAndroid Build Coastguard Worker         {"separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2},
4573*35238bceSAndroid Build Coastguard Worker         {"separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2},
4574*35238bceSAndroid Build Coastguard Worker         {"separable_geometry", glu::SHADERTYPE_GEOMETRY, 2},
4575*35238bceSAndroid Build Coastguard Worker     };
4576*35238bceSAndroid Build Coastguard Worker     static const struct
4577*35238bceSAndroid Build Coastguard Worker     {
4578*35238bceSAndroid Build Coastguard Worker         const char *name;
4579*35238bceSAndroid Build Coastguard Worker         uint32_t flags;
4580*35238bceSAndroid Build Coastguard Worker         int expandLevel;
4581*35238bceSAndroid Build Coastguard Worker         int subExpandLevel;
4582*35238bceSAndroid Build Coastguard Worker     } pipelines[] = {
4583*35238bceSAndroid Build Coastguard Worker         {
4584*35238bceSAndroid Build Coastguard Worker             "vertex_fragment",
4585*35238bceSAndroid Build Coastguard Worker             (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4586*35238bceSAndroid Build Coastguard Worker             3,
4587*35238bceSAndroid Build Coastguard Worker             2,
4588*35238bceSAndroid Build Coastguard Worker         },
4589*35238bceSAndroid Build Coastguard Worker         {
4590*35238bceSAndroid Build Coastguard Worker             "vertex_tess_fragment",
4591*35238bceSAndroid Build Coastguard Worker             (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) |
4592*35238bceSAndroid Build Coastguard Worker                 (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4593*35238bceSAndroid Build Coastguard Worker             2,
4594*35238bceSAndroid Build Coastguard Worker             2,
4595*35238bceSAndroid Build Coastguard Worker         },
4596*35238bceSAndroid Build Coastguard Worker         {
4597*35238bceSAndroid Build Coastguard Worker             "vertex_geo_fragment",
4598*35238bceSAndroid Build Coastguard Worker             (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4599*35238bceSAndroid Build Coastguard Worker             2,
4600*35238bceSAndroid Build Coastguard Worker             2,
4601*35238bceSAndroid Build Coastguard Worker         },
4602*35238bceSAndroid Build Coastguard Worker         {
4603*35238bceSAndroid Build Coastguard Worker             "vertex_tess_geo_fragment",
4604*35238bceSAndroid Build Coastguard Worker             (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) |
4605*35238bceSAndroid Build Coastguard Worker                 (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) |
4606*35238bceSAndroid Build Coastguard Worker                 (1 << glu::SHADERTYPE_GEOMETRY),
4607*35238bceSAndroid Build Coastguard Worker             2,
4608*35238bceSAndroid Build Coastguard Worker             1,
4609*35238bceSAndroid Build Coastguard Worker         },
4610*35238bceSAndroid Build Coastguard Worker     };
4611*35238bceSAndroid Build Coastguard Worker 
4612*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4613*35238bceSAndroid Build Coastguard Worker     {
4614*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4615*35238bceSAndroid Build Coastguard Worker         const bool programSeparable     = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4616*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(programSeparable));
4617*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr stage(
4618*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
4619*35238bceSAndroid Build Coastguard Worker 
4620*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
4621*35238bceSAndroid Build Coastguard Worker 
4622*35238bceSAndroid Build Coastguard Worker         generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4623*35238bceSAndroid Build Coastguard Worker     }
4624*35238bceSAndroid Build Coastguard Worker 
4625*35238bceSAndroid Build Coastguard Worker     for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4626*35238bceSAndroid Build Coastguard Worker     {
4627*35238bceSAndroid Build Coastguard Worker         // whole pipeline
4628*35238bceSAndroid Build Coastguard Worker         {
4629*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4630*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4631*35238bceSAndroid Build Coastguard Worker             ResourceDefinition::ShaderSet *shaderSet = new ResourceDefinition::ShaderSet(
4632*35238bceSAndroid Build Coastguard Worker                 program, glslVersion, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags);
4633*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
4634*35238bceSAndroid Build Coastguard Worker 
4635*35238bceSAndroid Build Coastguard Worker             {
4636*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4637*35238bceSAndroid Build Coastguard Worker                 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4638*35238bceSAndroid Build Coastguard Worker             }
4639*35238bceSAndroid Build Coastguard Worker         }
4640*35238bceSAndroid Build Coastguard Worker 
4641*35238bceSAndroid Build Coastguard Worker         // only one stage
4642*35238bceSAndroid Build Coastguard Worker         for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4643*35238bceSAndroid Build Coastguard Worker         {
4644*35238bceSAndroid Build Coastguard Worker             if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4645*35238bceSAndroid Build Coastguard Worker             {
4646*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4647*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::ShaderSet *shaderSet = new ResourceDefinition::ShaderSet(
4648*35238bceSAndroid Build Coastguard Worker                     program, glslVersion, pipelines[pipelineNdx].flags, (1u << selectedStageBit));
4649*35238bceSAndroid Build Coastguard Worker                 const char *stageName           = (selectedStageBit == glu::SHADERTYPE_VERTEX)   ? ("vertex") :
4650*35238bceSAndroid Build Coastguard Worker                                                   (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment") :
4651*35238bceSAndroid Build Coastguard Worker                                                   (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo") :
4652*35238bceSAndroid Build Coastguard Worker                                                   (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl") :
4653*35238bceSAndroid Build Coastguard Worker                                                   (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval") :
4654*35238bceSAndroid Build Coastguard Worker                                                                                                                   (DE_NULL);
4655*35238bceSAndroid Build Coastguard Worker                 const std::string setName       = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4656*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4657*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4658*35238bceSAndroid Build Coastguard Worker 
4659*35238bceSAndroid Build Coastguard Worker                 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4660*35238bceSAndroid Build Coastguard Worker                 targetGroup->addChild(blockGroup);
4661*35238bceSAndroid Build Coastguard Worker             }
4662*35238bceSAndroid Build Coastguard Worker         }
4663*35238bceSAndroid Build Coastguard Worker     }
4664*35238bceSAndroid Build Coastguard Worker }
4665*35238bceSAndroid Build Coastguard Worker 
generateRandomDataType(de::Random & rnd,bool excludeOpaqueTypes)4666*35238bceSAndroid Build Coastguard Worker static glu::DataType generateRandomDataType(de::Random &rnd, bool excludeOpaqueTypes)
4667*35238bceSAndroid Build Coastguard Worker {
4668*35238bceSAndroid Build Coastguard Worker     static const glu::DataType s_types[] = {glu::TYPE_FLOAT,
4669*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT,
4670*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT,
4671*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_BOOL,
4672*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_VEC2,
4673*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_VEC3,
4674*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_VEC4,
4675*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_VEC2,
4676*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_VEC3,
4677*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_VEC4,
4678*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_VEC2,
4679*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_VEC3,
4680*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_VEC4,
4681*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_BOOL_VEC2,
4682*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_BOOL_VEC3,
4683*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_BOOL_VEC4,
4684*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT2,
4685*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT2X3,
4686*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT2X4,
4687*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT3X2,
4688*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT3,
4689*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT3X4,
4690*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT4X2,
4691*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT4X3,
4692*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_FLOAT_MAT4,
4693*35238bceSAndroid Build Coastguard Worker 
4694*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_2D,
4695*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_CUBE,
4696*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_2D_ARRAY,
4697*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_3D,
4698*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_2D_SHADOW,
4699*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_CUBE_SHADOW,
4700*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4701*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_SAMPLER_2D,
4702*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_SAMPLER_CUBE,
4703*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_SAMPLER_2D_ARRAY,
4704*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_SAMPLER_3D,
4705*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_SAMPLER_2D,
4706*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_SAMPLER_CUBE,
4707*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4708*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_SAMPLER_3D,
4709*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4710*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4711*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4712*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_IMAGE_2D,
4713*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_IMAGE_CUBE,
4714*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_IMAGE_2D_ARRAY,
4715*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_IMAGE_3D,
4716*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_IMAGE_2D,
4717*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_IMAGE_CUBE,
4718*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_IMAGE_2D_ARRAY,
4719*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_INT_IMAGE_3D,
4720*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_IMAGE_2D,
4721*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_IMAGE_CUBE,
4722*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_IMAGE_2D_ARRAY,
4723*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_IMAGE_3D,
4724*35238bceSAndroid Build Coastguard Worker                                             glu::TYPE_UINT_ATOMIC_COUNTER};
4725*35238bceSAndroid Build Coastguard Worker 
4726*35238bceSAndroid Build Coastguard Worker     for (;;)
4727*35238bceSAndroid Build Coastguard Worker     {
4728*35238bceSAndroid Build Coastguard Worker         const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types) - 1)];
4729*35238bceSAndroid Build Coastguard Worker 
4730*35238bceSAndroid Build Coastguard Worker         if (!excludeOpaqueTypes || glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
4731*35238bceSAndroid Build Coastguard Worker             return type;
4732*35238bceSAndroid Build Coastguard Worker     }
4733*35238bceSAndroid Build Coastguard Worker }
4734*35238bceSAndroid Build Coastguard Worker 
generateRandomVariableDefinition(de::Random & rnd,const ResourceDefinition::Node::SharedPtr & parentStructure,glu::DataType baseType,const glu::Layout & layout,bool allowUnsized)4735*35238bceSAndroid Build Coastguard Worker static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition(
4736*35238bceSAndroid Build Coastguard Worker     de::Random &rnd, const ResourceDefinition::Node::SharedPtr &parentStructure, glu::DataType baseType,
4737*35238bceSAndroid Build Coastguard Worker     const glu::Layout &layout, bool allowUnsized)
4738*35238bceSAndroid Build Coastguard Worker {
4739*35238bceSAndroid Build Coastguard Worker     const int maxNesting                                 = 4;
4740*35238bceSAndroid Build Coastguard Worker     ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4741*35238bceSAndroid Build Coastguard Worker     const bool canBeInsideAStruct                        = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4742*35238bceSAndroid Build Coastguard Worker 
4743*35238bceSAndroid Build Coastguard Worker     for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4744*35238bceSAndroid Build Coastguard Worker     {
4745*35238bceSAndroid Build Coastguard Worker         if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4746*35238bceSAndroid Build Coastguard Worker             currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(
4747*35238bceSAndroid Build Coastguard Worker                 currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4748*35238bceSAndroid Build Coastguard Worker         else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4749*35238bceSAndroid Build Coastguard Worker             currentStructure =
4750*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4751*35238bceSAndroid Build Coastguard Worker         else if (rnd.getFloat() < 0.3)
4752*35238bceSAndroid Build Coastguard Worker             currentStructure =
4753*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4754*35238bceSAndroid Build Coastguard Worker         else
4755*35238bceSAndroid Build Coastguard Worker             break;
4756*35238bceSAndroid Build Coastguard Worker     }
4757*35238bceSAndroid Build Coastguard Worker 
4758*35238bceSAndroid Build Coastguard Worker     return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4759*35238bceSAndroid Build Coastguard Worker }
4760*35238bceSAndroid Build Coastguard Worker 
generateRandomCoreShaderSet(de::Random & rnd,glu::GLSLVersion glslVersion)4761*35238bceSAndroid Build Coastguard Worker static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet(de::Random &rnd, glu::GLSLVersion glslVersion)
4762*35238bceSAndroid Build Coastguard Worker {
4763*35238bceSAndroid Build Coastguard Worker     if (rnd.getFloat() < 0.5f)
4764*35238bceSAndroid Build Coastguard Worker     {
4765*35238bceSAndroid Build Coastguard Worker         // compute only
4766*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4767*35238bceSAndroid Build Coastguard Worker         return ResourceDefinition::Node::SharedPtr(
4768*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4769*35238bceSAndroid Build Coastguard Worker     }
4770*35238bceSAndroid Build Coastguard Worker     else if (rnd.getFloat() < 0.5f)
4771*35238bceSAndroid Build Coastguard Worker     {
4772*35238bceSAndroid Build Coastguard Worker         // vertex and fragment
4773*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4774*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::ShaderSet *shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4775*35238bceSAndroid Build Coastguard Worker 
4776*35238bceSAndroid Build Coastguard Worker         if (rnd.getBool())
4777*35238bceSAndroid Build Coastguard Worker         {
4778*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4779*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4780*35238bceSAndroid Build Coastguard Worker         }
4781*35238bceSAndroid Build Coastguard Worker         else
4782*35238bceSAndroid Build Coastguard Worker         {
4783*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4784*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4785*35238bceSAndroid Build Coastguard Worker         }
4786*35238bceSAndroid Build Coastguard Worker 
4787*35238bceSAndroid Build Coastguard Worker         return ResourceDefinition::Node::SharedPtr(shaderSet);
4788*35238bceSAndroid Build Coastguard Worker     }
4789*35238bceSAndroid Build Coastguard Worker     else
4790*35238bceSAndroid Build Coastguard Worker     {
4791*35238bceSAndroid Build Coastguard Worker         // separate vertex or fragment
4792*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
4793*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4794*35238bceSAndroid Build Coastguard Worker 
4795*35238bceSAndroid Build Coastguard Worker         return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4796*35238bceSAndroid Build Coastguard Worker     }
4797*35238bceSAndroid Build Coastguard Worker }
4798*35238bceSAndroid Build Coastguard Worker 
generateRandomExtShaderSet(de::Random & rnd,glu::GLSLVersion glslVersion)4799*35238bceSAndroid Build Coastguard Worker static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet(de::Random &rnd, glu::GLSLVersion glslVersion)
4800*35238bceSAndroid Build Coastguard Worker {
4801*35238bceSAndroid Build Coastguard Worker     if (rnd.getFloat() < 0.5f)
4802*35238bceSAndroid Build Coastguard Worker     {
4803*35238bceSAndroid Build Coastguard Worker         // whole pipeline
4804*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4805*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::ShaderSet *shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4806*35238bceSAndroid Build Coastguard Worker 
4807*35238bceSAndroid Build Coastguard Worker         shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4808*35238bceSAndroid Build Coastguard Worker         shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4809*35238bceSAndroid Build Coastguard Worker 
4810*35238bceSAndroid Build Coastguard Worker         // tess shader are either both or neither present. Make cases interesting
4811*35238bceSAndroid Build Coastguard Worker         // by forcing one extended shader to always have reference
4812*35238bceSAndroid Build Coastguard Worker         if (rnd.getBool())
4813*35238bceSAndroid Build Coastguard Worker         {
4814*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4815*35238bceSAndroid Build Coastguard Worker 
4816*35238bceSAndroid Build Coastguard Worker             if (rnd.getBool())
4817*35238bceSAndroid Build Coastguard Worker             {
4818*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4819*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4820*35238bceSAndroid Build Coastguard Worker             }
4821*35238bceSAndroid Build Coastguard Worker         }
4822*35238bceSAndroid Build Coastguard Worker         else
4823*35238bceSAndroid Build Coastguard Worker         {
4824*35238bceSAndroid Build Coastguard Worker             shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4825*35238bceSAndroid Build Coastguard Worker 
4826*35238bceSAndroid Build Coastguard Worker             if (rnd.getBool())
4827*35238bceSAndroid Build Coastguard Worker             {
4828*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4829*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4830*35238bceSAndroid Build Coastguard Worker             }
4831*35238bceSAndroid Build Coastguard Worker             else
4832*35238bceSAndroid Build Coastguard Worker             {
4833*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4834*35238bceSAndroid Build Coastguard Worker                 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4835*35238bceSAndroid Build Coastguard Worker             }
4836*35238bceSAndroid Build Coastguard Worker         }
4837*35238bceSAndroid Build Coastguard Worker 
4838*35238bceSAndroid Build Coastguard Worker         return ResourceDefinition::Node::SharedPtr(shaderSet);
4839*35238bceSAndroid Build Coastguard Worker     }
4840*35238bceSAndroid Build Coastguard Worker     else
4841*35238bceSAndroid Build Coastguard Worker     {
4842*35238bceSAndroid Build Coastguard Worker         // separate
4843*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
4844*35238bceSAndroid Build Coastguard Worker         const int selector               = rnd.getInt(0, 2);
4845*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY) :
4846*35238bceSAndroid Build Coastguard Worker                                            (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL) :
4847*35238bceSAndroid Build Coastguard Worker                                            (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION) :
4848*35238bceSAndroid Build Coastguard Worker                                                              (glu::SHADERTYPE_LAST);
4849*35238bceSAndroid Build Coastguard Worker 
4850*35238bceSAndroid Build Coastguard Worker         return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4851*35238bceSAndroid Build Coastguard Worker     }
4852*35238bceSAndroid Build Coastguard Worker }
4853*35238bceSAndroid Build Coastguard Worker 
generateRandomShaderSet(de::Random & rnd,glu::GLSLVersion glslVersion,bool onlyExtensionStages)4854*35238bceSAndroid Build Coastguard Worker static ResourceDefinition::Node::SharedPtr generateRandomShaderSet(de::Random &rnd, glu::GLSLVersion glslVersion,
4855*35238bceSAndroid Build Coastguard Worker                                                                    bool onlyExtensionStages)
4856*35238bceSAndroid Build Coastguard Worker {
4857*35238bceSAndroid Build Coastguard Worker     if (!onlyExtensionStages)
4858*35238bceSAndroid Build Coastguard Worker         return generateRandomCoreShaderSet(rnd, glslVersion);
4859*35238bceSAndroid Build Coastguard Worker     else
4860*35238bceSAndroid Build Coastguard Worker         return generateRandomExtShaderSet(rnd, glslVersion);
4861*35238bceSAndroid Build Coastguard Worker }
4862*35238bceSAndroid Build Coastguard Worker 
generateRandomUniformBlockLayout(de::Random & rnd)4863*35238bceSAndroid Build Coastguard Worker static glu::Layout generateRandomUniformBlockLayout(de::Random &rnd)
4864*35238bceSAndroid Build Coastguard Worker {
4865*35238bceSAndroid Build Coastguard Worker     glu::Layout layout;
4866*35238bceSAndroid Build Coastguard Worker 
4867*35238bceSAndroid Build Coastguard Worker     if (rnd.getBool())
4868*35238bceSAndroid Build Coastguard Worker         layout.binding = rnd.getInt(0, 5);
4869*35238bceSAndroid Build Coastguard Worker 
4870*35238bceSAndroid Build Coastguard Worker     if (rnd.getBool())
4871*35238bceSAndroid Build Coastguard Worker         layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4872*35238bceSAndroid Build Coastguard Worker 
4873*35238bceSAndroid Build Coastguard Worker     return layout;
4874*35238bceSAndroid Build Coastguard Worker }
4875*35238bceSAndroid Build Coastguard Worker 
generateRandomBufferBlockLayout(de::Random & rnd)4876*35238bceSAndroid Build Coastguard Worker static glu::Layout generateRandomBufferBlockLayout(de::Random &rnd)
4877*35238bceSAndroid Build Coastguard Worker {
4878*35238bceSAndroid Build Coastguard Worker     return generateRandomUniformBlockLayout(rnd);
4879*35238bceSAndroid Build Coastguard Worker }
4880*35238bceSAndroid Build Coastguard Worker 
generateRandomVariableLayout(de::Random & rnd,glu::DataType type,bool interfaceBlockMember)4881*35238bceSAndroid Build Coastguard Worker static glu::Layout generateRandomVariableLayout(de::Random &rnd, glu::DataType type, bool interfaceBlockMember)
4882*35238bceSAndroid Build Coastguard Worker {
4883*35238bceSAndroid Build Coastguard Worker     glu::Layout layout;
4884*35238bceSAndroid Build Coastguard Worker 
4885*35238bceSAndroid Build Coastguard Worker     if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) &&
4886*35238bceSAndroid Build Coastguard Worker         rnd.getBool())
4887*35238bceSAndroid Build Coastguard Worker         layout.binding = rnd.getInt(0, 5);
4888*35238bceSAndroid Build Coastguard Worker 
4889*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4890*35238bceSAndroid Build Coastguard Worker         layout.offset = rnd.getInt(0, 3) * 4;
4891*35238bceSAndroid Build Coastguard Worker 
4892*35238bceSAndroid Build Coastguard Worker     if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4893*35238bceSAndroid Build Coastguard Worker         layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4894*35238bceSAndroid Build Coastguard Worker 
4895*35238bceSAndroid Build Coastguard Worker     return layout;
4896*35238bceSAndroid Build Coastguard Worker }
4897*35238bceSAndroid Build Coastguard Worker 
generateUniformRandomCase(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion,int index,bool onlyExtensionStages)4898*35238bceSAndroid Build Coastguard Worker static void generateUniformRandomCase(Context &context, tcu::TestCaseGroup *const targetGroup,
4899*35238bceSAndroid Build Coastguard Worker                                       glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
4900*35238bceSAndroid Build Coastguard Worker {
4901*35238bceSAndroid Build Coastguard Worker     de::Random rnd(index * 0x12345);
4902*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
4903*35238bceSAndroid Build Coastguard Worker     const bool interfaceBlock                        = rnd.getBool();
4904*35238bceSAndroid Build Coastguard Worker     const glu::DataType type                         = generateRandomDataType(rnd, interfaceBlock);
4905*35238bceSAndroid Build Coastguard Worker     const glu::Layout layout                         = generateRandomVariableLayout(rnd, type, interfaceBlock);
4906*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
4907*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr uniform(
4908*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4909*35238bceSAndroid Build Coastguard Worker     ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4910*35238bceSAndroid Build Coastguard Worker 
4911*35238bceSAndroid Build Coastguard Worker     if (interfaceBlock)
4912*35238bceSAndroid Build Coastguard Worker     {
4913*35238bceSAndroid Build Coastguard Worker         const bool namedBlock = rnd.getBool();
4914*35238bceSAndroid Build Coastguard Worker 
4915*35238bceSAndroid Build Coastguard Worker         currentStructure = ResourceDefinition::Node::SharedPtr(
4916*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4917*35238bceSAndroid Build Coastguard Worker 
4918*35238bceSAndroid Build Coastguard Worker         if (namedBlock && rnd.getBool())
4919*35238bceSAndroid Build Coastguard Worker             currentStructure =
4920*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4921*35238bceSAndroid Build Coastguard Worker 
4922*35238bceSAndroid Build Coastguard Worker         currentStructure =
4923*35238bceSAndroid Build Coastguard Worker             ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4924*35238bceSAndroid Build Coastguard Worker     }
4925*35238bceSAndroid Build Coastguard Worker 
4926*35238bceSAndroid Build Coastguard Worker     currentStructure =
4927*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4928*35238bceSAndroid Build Coastguard Worker     currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4929*35238bceSAndroid Build Coastguard Worker 
4930*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new ResourceTestCase(
4931*35238bceSAndroid Build Coastguard Worker         context, currentStructure,
4932*35238bceSAndroid Build Coastguard Worker         ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK),
4933*35238bceSAndroid Build Coastguard Worker         de::toString(index).c_str()));
4934*35238bceSAndroid Build Coastguard Worker }
4935*35238bceSAndroid Build Coastguard Worker 
generateUniformCaseRandomCases(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion)4936*35238bceSAndroid Build Coastguard Worker static void generateUniformCaseRandomCases(Context &context, tcu::TestCaseGroup *const targetGroup,
4937*35238bceSAndroid Build Coastguard Worker                                            glu::GLSLVersion glslVersion)
4938*35238bceSAndroid Build Coastguard Worker {
4939*35238bceSAndroid Build Coastguard Worker     const int numBasicCases   = 40;
4940*35238bceSAndroid Build Coastguard Worker     const int numTessGeoCases = 40;
4941*35238bceSAndroid Build Coastguard Worker 
4942*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numBasicCases; ++ndx)
4943*35238bceSAndroid Build Coastguard Worker         generateUniformRandomCase(context, targetGroup, glslVersion, ndx, false);
4944*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4945*35238bceSAndroid Build Coastguard Worker         generateUniformRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
4946*35238bceSAndroid Build Coastguard Worker }
4947*35238bceSAndroid Build Coastguard Worker 
4948*35238bceSAndroid Build Coastguard Worker class UniformInterfaceTestGroup : public TestCaseGroup
4949*35238bceSAndroid Build Coastguard Worker {
4950*35238bceSAndroid Build Coastguard Worker public:
4951*35238bceSAndroid Build Coastguard Worker     UniformInterfaceTestGroup(Context &context);
4952*35238bceSAndroid Build Coastguard Worker     void init(void);
4953*35238bceSAndroid Build Coastguard Worker };
4954*35238bceSAndroid Build Coastguard Worker 
UniformInterfaceTestGroup(Context & context)4955*35238bceSAndroid Build Coastguard Worker UniformInterfaceTestGroup::UniformInterfaceTestGroup(Context &context)
4956*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "uniform", "Uniform interace")
4957*35238bceSAndroid Build Coastguard Worker {
4958*35238bceSAndroid Build Coastguard Worker }
4959*35238bceSAndroid Build Coastguard Worker 
init(void)4960*35238bceSAndroid Build Coastguard Worker void UniformInterfaceTestGroup::init(void)
4961*35238bceSAndroid Build Coastguard Worker {
4962*35238bceSAndroid Build Coastguard Worker     glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4963*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4964*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr computeShader(
4965*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4966*35238bceSAndroid Build Coastguard Worker 
4967*35238bceSAndroid Build Coastguard Worker     // .resource_list
4968*35238bceSAndroid Build Coastguard Worker     {
4969*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4970*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
4971*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
4972*35238bceSAndroid Build Coastguard Worker                                   generateUniformResourceListBlockContents);
4973*35238bceSAndroid Build Coastguard Worker     }
4974*35238bceSAndroid Build Coastguard Worker 
4975*35238bceSAndroid Build Coastguard Worker     // .array_size
4976*35238bceSAndroid Build Coastguard Worker     {
4977*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4978*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
4979*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
4980*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockArraySizeContents);
4981*35238bceSAndroid Build Coastguard Worker     }
4982*35238bceSAndroid Build Coastguard Worker 
4983*35238bceSAndroid Build Coastguard Worker     // .array_stride
4984*35238bceSAndroid Build Coastguard Worker     {
4985*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4986*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
4987*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
4988*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockArrayStrideContents);
4989*35238bceSAndroid Build Coastguard Worker     }
4990*35238bceSAndroid Build Coastguard Worker 
4991*35238bceSAndroid Build Coastguard Worker     // .atomic_counter_buffer_index
4992*35238bceSAndroid Build Coastguard Worker     {
4993*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
4994*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4995*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
4996*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED,
4997*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockAtomicCounterBufferIndexContents);
4998*35238bceSAndroid Build Coastguard Worker     }
4999*35238bceSAndroid Build Coastguard Worker 
5000*35238bceSAndroid Build Coastguard Worker     // .block_index
5001*35238bceSAndroid Build Coastguard Worker     {
5002*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
5003*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5004*35238bceSAndroid Build Coastguard Worker         generateUniformBlockBlockIndexContents(m_context, blockGroup, glslVersion);
5005*35238bceSAndroid Build Coastguard Worker     }
5006*35238bceSAndroid Build Coastguard Worker 
5007*35238bceSAndroid Build Coastguard Worker     // .location
5008*35238bceSAndroid Build Coastguard Worker     {
5009*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
5010*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5011*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup,
5012*35238bceSAndroid Build Coastguard Worker                                   BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED,
5013*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockLocationContents);
5014*35238bceSAndroid Build Coastguard Worker     }
5015*35238bceSAndroid Build Coastguard Worker 
5016*35238bceSAndroid Build Coastguard Worker     // .matrix_row_major
5017*35238bceSAndroid Build Coastguard Worker     {
5018*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5019*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
5020*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5021*35238bceSAndroid Build Coastguard Worker         generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup,
5022*35238bceSAndroid Build Coastguard Worker                                         generateUniformMatrixOrderCaseBlockContentCases);
5023*35238bceSAndroid Build Coastguard Worker     }
5024*35238bceSAndroid Build Coastguard Worker 
5025*35238bceSAndroid Build Coastguard Worker     // .matrix_stride
5026*35238bceSAndroid Build Coastguard Worker     {
5027*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5028*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
5029*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5030*35238bceSAndroid Build Coastguard Worker         generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup,
5031*35238bceSAndroid Build Coastguard Worker                                         generateUniformMatrixStrideCaseBlockContentCases);
5032*35238bceSAndroid Build Coastguard Worker     }
5033*35238bceSAndroid Build Coastguard Worker 
5034*35238bceSAndroid Build Coastguard Worker     // .name_length
5035*35238bceSAndroid Build Coastguard Worker     {
5036*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
5037*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5038*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
5039*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockNameLengthContents);
5040*35238bceSAndroid Build Coastguard Worker     }
5041*35238bceSAndroid Build Coastguard Worker 
5042*35238bceSAndroid Build Coastguard Worker     // .offset
5043*35238bceSAndroid Build Coastguard Worker     {
5044*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
5045*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5046*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
5047*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockOffsetContents);
5048*35238bceSAndroid Build Coastguard Worker     }
5049*35238bceSAndroid Build Coastguard Worker 
5050*35238bceSAndroid Build Coastguard Worker     // .referenced_by_shader
5051*35238bceSAndroid Build Coastguard Worker     {
5052*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5053*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
5054*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5055*35238bceSAndroid Build Coastguard Worker         generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion,
5056*35238bceSAndroid Build Coastguard Worker                                              generateUniformReferencedByShaderSingleBlockContentCases);
5057*35238bceSAndroid Build Coastguard Worker     }
5058*35238bceSAndroid Build Coastguard Worker 
5059*35238bceSAndroid Build Coastguard Worker     // .type
5060*35238bceSAndroid Build Coastguard Worker     {
5061*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
5062*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5063*35238bceSAndroid Build Coastguard Worker         generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL,
5064*35238bceSAndroid Build Coastguard Worker                                   generateUniformBlockTypeContents);
5065*35238bceSAndroid Build Coastguard Worker     }
5066*35238bceSAndroid Build Coastguard Worker 
5067*35238bceSAndroid Build Coastguard Worker     // .random
5068*35238bceSAndroid Build Coastguard Worker     {
5069*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
5070*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5071*35238bceSAndroid Build Coastguard Worker         generateUniformCaseRandomCases(m_context, blockGroup, glslVersion);
5072*35238bceSAndroid Build Coastguard Worker     }
5073*35238bceSAndroid Build Coastguard Worker }
5074*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceResourceListCase(Context & context,const ResourceDefinition::Node::SharedPtr & targetResource,tcu::TestCaseGroup * const targetGroup,ProgramInterface interface,const char * blockName)5075*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceResourceListCase(Context &context,
5076*35238bceSAndroid Build Coastguard Worker                                                           const ResourceDefinition::Node::SharedPtr &targetResource,
5077*35238bceSAndroid Build Coastguard Worker                                                           tcu::TestCaseGroup *const targetGroup,
5078*35238bceSAndroid Build Coastguard Worker                                                           ProgramInterface interface, const char *blockName)
5079*35238bceSAndroid Build Coastguard Worker {
5080*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
5081*35238bceSAndroid Build Coastguard Worker }
5082*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceNameLengthCase(Context & context,const ResourceDefinition::Node::SharedPtr & targetResource,tcu::TestCaseGroup * const targetGroup,ProgramInterface interface,const char * blockName)5083*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceNameLengthCase(Context &context,
5084*35238bceSAndroid Build Coastguard Worker                                                         const ResourceDefinition::Node::SharedPtr &targetResource,
5085*35238bceSAndroid Build Coastguard Worker                                                         tcu::TestCaseGroup *const targetGroup,
5086*35238bceSAndroid Build Coastguard Worker                                                         ProgramInterface interface, const char *blockName)
5087*35238bceSAndroid Build Coastguard Worker {
5088*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
5089*35238bceSAndroid Build Coastguard Worker         new ResourceTestCase(context, targetResource,
5090*35238bceSAndroid Build Coastguard Worker                              ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
5091*35238bceSAndroid Build Coastguard Worker }
5092*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceResourceBasicBlockTypes(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion,glu::Storage storage,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup * const,ProgramInterface interface,const char * blockName))5093*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceResourceBasicBlockTypes(
5094*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage,
5095*35238bceSAndroid Build Coastguard Worker     void (*blockContentGenerator)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *const,
5096*35238bceSAndroid Build Coastguard Worker                                   ProgramInterface interface, const char *blockName))
5097*35238bceSAndroid Build Coastguard Worker {
5098*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
5099*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
5100*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5101*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
5102*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr storageQualifier(
5103*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, storage));
5104*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr binding(
5105*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
5106*35238bceSAndroid Build Coastguard Worker     const ProgramInterface programInterface =
5107*35238bceSAndroid Build Coastguard Worker         (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
5108*35238bceSAndroid Build Coastguard Worker 
5109*35238bceSAndroid Build Coastguard Worker     // .named_block
5110*35238bceSAndroid Build Coastguard Worker     {
5111*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(binding, true));
5112*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5113*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5114*35238bceSAndroid Build Coastguard Worker 
5115*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "named_block");
5116*35238bceSAndroid Build Coastguard Worker     }
5117*35238bceSAndroid Build Coastguard Worker 
5118*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
5119*35238bceSAndroid Build Coastguard Worker     {
5120*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(binding, false));
5121*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5122*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5123*35238bceSAndroid Build Coastguard Worker 
5124*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "unnamed_block");
5125*35238bceSAndroid Build Coastguard Worker     }
5126*35238bceSAndroid Build Coastguard Worker 
5127*35238bceSAndroid Build Coastguard Worker     // .block_array
5128*35238bceSAndroid Build Coastguard Worker     {
5129*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding, 3));
5130*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
5131*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5132*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5133*35238bceSAndroid Build Coastguard Worker 
5134*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array");
5135*35238bceSAndroid Build Coastguard Worker     }
5136*35238bceSAndroid Build Coastguard Worker 
5137*35238bceSAndroid Build Coastguard Worker     // .block_array_single_element
5138*35238bceSAndroid Build Coastguard Worker     {
5139*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding, 1));
5140*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
5141*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5142*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5143*35238bceSAndroid Build Coastguard Worker 
5144*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array_single_element");
5145*35238bceSAndroid Build Coastguard Worker     }
5146*35238bceSAndroid Build Coastguard Worker }
5147*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceResourceBufferBindingCases(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion,glu::Storage storage)5148*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceResourceBufferBindingCases(Context &context, tcu::TestCaseGroup *targetGroup,
5149*35238bceSAndroid Build Coastguard Worker                                                                     glu::GLSLVersion glslVersion, glu::Storage storage)
5150*35238bceSAndroid Build Coastguard Worker {
5151*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
5152*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
5153*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5154*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
5155*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr storageQualifier(
5156*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, storage));
5157*35238bceSAndroid Build Coastguard Worker 
5158*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < 2; ++ndx)
5159*35238bceSAndroid Build Coastguard Worker     {
5160*35238bceSAndroid Build Coastguard Worker         const bool explicitBinding   = (ndx == 1);
5161*35238bceSAndroid Build Coastguard Worker         const int bindingNdx         = (explicitBinding) ? (1) : (-1);
5162*35238bceSAndroid Build Coastguard Worker         const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
5163*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr binding(
5164*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
5165*35238bceSAndroid Build Coastguard Worker         const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ?
5166*35238bceSAndroid Build Coastguard Worker                                                       (PROGRAMINTERFACE_UNIFORM_BLOCK) :
5167*35238bceSAndroid Build Coastguard Worker                                                       (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
5168*35238bceSAndroid Build Coastguard Worker 
5169*35238bceSAndroid Build Coastguard Worker         // .named_block*
5170*35238bceSAndroid Build Coastguard Worker         {
5171*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(binding, true));
5172*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr unusedVariable(
5173*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5174*35238bceSAndroid Build Coastguard Worker 
5175*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5176*35238bceSAndroid Build Coastguard Worker                 context, unusedVariable,
5177*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING),
5178*35238bceSAndroid Build Coastguard Worker                 ("named_block" + nameSuffix).c_str()));
5179*35238bceSAndroid Build Coastguard Worker         }
5180*35238bceSAndroid Build Coastguard Worker 
5181*35238bceSAndroid Build Coastguard Worker         // .unnamed_block*
5182*35238bceSAndroid Build Coastguard Worker         {
5183*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(binding, false));
5184*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr unusedVariable(
5185*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5186*35238bceSAndroid Build Coastguard Worker 
5187*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5188*35238bceSAndroid Build Coastguard Worker                 context, unusedVariable,
5189*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING),
5190*35238bceSAndroid Build Coastguard Worker                 ("unnamed_block" + nameSuffix).c_str()));
5191*35238bceSAndroid Build Coastguard Worker         }
5192*35238bceSAndroid Build Coastguard Worker 
5193*35238bceSAndroid Build Coastguard Worker         // .block_array*
5194*35238bceSAndroid Build Coastguard Worker         {
5195*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding, 3));
5196*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
5197*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr unusedVariable(
5198*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5199*35238bceSAndroid Build Coastguard Worker 
5200*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5201*35238bceSAndroid Build Coastguard Worker                 context, unusedVariable,
5202*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING),
5203*35238bceSAndroid Build Coastguard Worker                 ("block_array" + nameSuffix).c_str()));
5204*35238bceSAndroid Build Coastguard Worker         }
5205*35238bceSAndroid Build Coastguard Worker     }
5206*35238bceSAndroid Build Coastguard Worker }
5207*35238bceSAndroid Build Coastguard Worker 
5208*35238bceSAndroid Build Coastguard Worker template <glu::Storage Storage>
generateBufferBlockReferencedByShaderSingleBlockContentCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,int expandLevel)5209*35238bceSAndroid Build Coastguard Worker static void generateBufferBlockReferencedByShaderSingleBlockContentCases(
5210*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
5211*35238bceSAndroid Build Coastguard Worker     int expandLevel)
5212*35238bceSAndroid Build Coastguard Worker {
5213*35238bceSAndroid Build Coastguard Worker     const ProgramInterface programInterface =
5214*35238bceSAndroid Build Coastguard Worker         (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
5215*35238bceSAndroid Build Coastguard Worker         (Storage == glu::STORAGE_BUFFER)  ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
5216*35238bceSAndroid Build Coastguard Worker                                             (PROGRAMINTERFACE_LAST);
5217*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
5218*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr storage(new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
5219*35238bceSAndroid Build Coastguard Worker 
5220*35238bceSAndroid Build Coastguard Worker     DE_UNREF(expandLevel);
5221*35238bceSAndroid Build Coastguard Worker 
5222*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
5223*35238bceSAndroid Build Coastguard Worker 
5224*35238bceSAndroid Build Coastguard Worker     // .named_block
5225*35238bceSAndroid Build Coastguard Worker     {
5226*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(storage, true));
5227*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5228*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5229*35238bceSAndroid Build Coastguard Worker 
5230*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
5231*35238bceSAndroid Build Coastguard Worker             context, unusedVariable,
5232*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
5233*35238bceSAndroid Build Coastguard Worker     }
5234*35238bceSAndroid Build Coastguard Worker 
5235*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
5236*35238bceSAndroid Build Coastguard Worker     {
5237*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(storage, false));
5238*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5239*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5240*35238bceSAndroid Build Coastguard Worker 
5241*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
5242*35238bceSAndroid Build Coastguard Worker             context, unusedVariable,
5243*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER),
5244*35238bceSAndroid Build Coastguard Worker             "unnamed_block"));
5245*35238bceSAndroid Build Coastguard Worker     }
5246*35238bceSAndroid Build Coastguard Worker 
5247*35238bceSAndroid Build Coastguard Worker     // .block_array
5248*35238bceSAndroid Build Coastguard Worker     {
5249*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(storage, 3));
5250*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(arrayElement, true));
5251*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unusedVariable(
5252*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
5253*35238bceSAndroid Build Coastguard Worker 
5254*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
5255*35238bceSAndroid Build Coastguard Worker             context, unusedVariable,
5256*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
5257*35238bceSAndroid Build Coastguard Worker     }
5258*35238bceSAndroid Build Coastguard Worker }
5259*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceResourceActiveVariablesCase(Context & context,tcu::TestCaseGroup * targetGroup,glu::Storage storage)5260*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceResourceActiveVariablesCase(Context &context, tcu::TestCaseGroup *targetGroup,
5261*35238bceSAndroid Build Coastguard Worker                                                                      glu::Storage storage)
5262*35238bceSAndroid Build Coastguard Worker {
5263*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(
5264*35238bceSAndroid Build Coastguard Worker         context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
5265*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(
5266*35238bceSAndroid Build Coastguard Worker         context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
5267*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(
5268*35238bceSAndroid Build Coastguard Worker         context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
5269*35238bceSAndroid Build Coastguard Worker }
5270*35238bceSAndroid Build Coastguard Worker 
generateBufferBackedInterfaceResourceBufferDataSizeCases(Context & context,tcu::TestCaseGroup * targetGroup,glu::Storage storage)5271*35238bceSAndroid Build Coastguard Worker static void generateBufferBackedInterfaceResourceBufferDataSizeCases(Context &context, tcu::TestCaseGroup *targetGroup,
5272*35238bceSAndroid Build Coastguard Worker                                                                      glu::Storage storage)
5273*35238bceSAndroid Build Coastguard Worker {
5274*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage,
5275*35238bceSAndroid Build Coastguard Worker                                                              InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
5276*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage,
5277*35238bceSAndroid Build Coastguard Worker                                                              InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
5278*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage,
5279*35238bceSAndroid Build Coastguard Worker                                                              InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
5280*35238bceSAndroid Build Coastguard Worker }
5281*35238bceSAndroid Build Coastguard Worker 
5282*35238bceSAndroid Build Coastguard Worker class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
5283*35238bceSAndroid Build Coastguard Worker {
5284*35238bceSAndroid Build Coastguard Worker public:
5285*35238bceSAndroid Build Coastguard Worker     BufferBackedBlockInterfaceTestGroup(Context &context, glu::Storage interfaceBlockStorage);
5286*35238bceSAndroid Build Coastguard Worker     void init(void);
5287*35238bceSAndroid Build Coastguard Worker 
5288*35238bceSAndroid Build Coastguard Worker private:
5289*35238bceSAndroid Build Coastguard Worker     static const char *getGroupName(glu::Storage storage);
5290*35238bceSAndroid Build Coastguard Worker     static const char *getGroupDescription(glu::Storage storage);
5291*35238bceSAndroid Build Coastguard Worker 
5292*35238bceSAndroid Build Coastguard Worker     const glu::Storage m_storage;
5293*35238bceSAndroid Build Coastguard Worker };
5294*35238bceSAndroid Build Coastguard Worker 
BufferBackedBlockInterfaceTestGroup(Context & context,glu::Storage storage)5295*35238bceSAndroid Build Coastguard Worker BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context &context, glu::Storage storage)
5296*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, getGroupName(storage), getGroupDescription(storage))
5297*35238bceSAndroid Build Coastguard Worker     , m_storage(storage)
5298*35238bceSAndroid Build Coastguard Worker {
5299*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
5300*35238bceSAndroid Build Coastguard Worker }
5301*35238bceSAndroid Build Coastguard Worker 
init(void)5302*35238bceSAndroid Build Coastguard Worker void BufferBackedBlockInterfaceTestGroup::init(void)
5303*35238bceSAndroid Build Coastguard Worker {
5304*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
5305*35238bceSAndroid Build Coastguard Worker 
5306*35238bceSAndroid Build Coastguard Worker     // .resource_list
5307*35238bceSAndroid Build Coastguard Worker     {
5308*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
5309*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5310*35238bceSAndroid Build Coastguard Worker         generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage,
5311*35238bceSAndroid Build Coastguard Worker                                                              generateBufferBackedInterfaceResourceListCase);
5312*35238bceSAndroid Build Coastguard Worker     }
5313*35238bceSAndroid Build Coastguard Worker 
5314*35238bceSAndroid Build Coastguard Worker     // .active_variables
5315*35238bceSAndroid Build Coastguard Worker     {
5316*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5317*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
5318*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5319*35238bceSAndroid Build Coastguard Worker         generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
5320*35238bceSAndroid Build Coastguard Worker     }
5321*35238bceSAndroid Build Coastguard Worker 
5322*35238bceSAndroid Build Coastguard Worker     // .buffer_binding
5323*35238bceSAndroid Build Coastguard Worker     {
5324*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
5325*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5326*35238bceSAndroid Build Coastguard Worker         generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, glslVersion, m_storage);
5327*35238bceSAndroid Build Coastguard Worker     }
5328*35238bceSAndroid Build Coastguard Worker 
5329*35238bceSAndroid Build Coastguard Worker     // .buffer_data_size
5330*35238bceSAndroid Build Coastguard Worker     {
5331*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5332*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
5333*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5334*35238bceSAndroid Build Coastguard Worker         generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
5335*35238bceSAndroid Build Coastguard Worker     }
5336*35238bceSAndroid Build Coastguard Worker 
5337*35238bceSAndroid Build Coastguard Worker     // .name_length
5338*35238bceSAndroid Build Coastguard Worker     {
5339*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
5340*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5341*35238bceSAndroid Build Coastguard Worker         generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage,
5342*35238bceSAndroid Build Coastguard Worker                                                              generateBufferBackedInterfaceNameLengthCase);
5343*35238bceSAndroid Build Coastguard Worker     }
5344*35238bceSAndroid Build Coastguard Worker 
5345*35238bceSAndroid Build Coastguard Worker     // .referenced_by
5346*35238bceSAndroid Build Coastguard Worker     {
5347*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
5348*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
5349*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
5350*35238bceSAndroid Build Coastguard Worker 
5351*35238bceSAndroid Build Coastguard Worker         if (m_storage == glu::STORAGE_UNIFORM)
5352*35238bceSAndroid Build Coastguard Worker             generateReferencedByShaderCaseBlocks(
5353*35238bceSAndroid Build Coastguard Worker                 m_context, blockGroup, glslVersion,
5354*35238bceSAndroid Build Coastguard Worker                 generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
5355*35238bceSAndroid Build Coastguard Worker         else if (m_storage == glu::STORAGE_BUFFER)
5356*35238bceSAndroid Build Coastguard Worker             generateReferencedByShaderCaseBlocks(
5357*35238bceSAndroid Build Coastguard Worker                 m_context, blockGroup, glslVersion,
5358*35238bceSAndroid Build Coastguard Worker                 generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
5359*35238bceSAndroid Build Coastguard Worker         else
5360*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
5361*35238bceSAndroid Build Coastguard Worker     }
5362*35238bceSAndroid Build Coastguard Worker }
5363*35238bceSAndroid Build Coastguard Worker 
getGroupName(glu::Storage storage)5364*35238bceSAndroid Build Coastguard Worker const char *BufferBackedBlockInterfaceTestGroup::getGroupName(glu::Storage storage)
5365*35238bceSAndroid Build Coastguard Worker {
5366*35238bceSAndroid Build Coastguard Worker     switch (storage)
5367*35238bceSAndroid Build Coastguard Worker     {
5368*35238bceSAndroid Build Coastguard Worker     case glu::STORAGE_UNIFORM:
5369*35238bceSAndroid Build Coastguard Worker         return "uniform_block";
5370*35238bceSAndroid Build Coastguard Worker     case glu::STORAGE_BUFFER:
5371*35238bceSAndroid Build Coastguard Worker         return "shader_storage_block";
5372*35238bceSAndroid Build Coastguard Worker     default:
5373*35238bceSAndroid Build Coastguard Worker         DE_FATAL("invalid storage enum value");
5374*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
5375*35238bceSAndroid Build Coastguard Worker     }
5376*35238bceSAndroid Build Coastguard Worker }
5377*35238bceSAndroid Build Coastguard Worker 
getGroupDescription(glu::Storage storage)5378*35238bceSAndroid Build Coastguard Worker const char *BufferBackedBlockInterfaceTestGroup::getGroupDescription(glu::Storage storage)
5379*35238bceSAndroid Build Coastguard Worker {
5380*35238bceSAndroid Build Coastguard Worker     switch (storage)
5381*35238bceSAndroid Build Coastguard Worker     {
5382*35238bceSAndroid Build Coastguard Worker     case glu::STORAGE_UNIFORM:
5383*35238bceSAndroid Build Coastguard Worker         return "Uniform block interface";
5384*35238bceSAndroid Build Coastguard Worker     case glu::STORAGE_BUFFER:
5385*35238bceSAndroid Build Coastguard Worker         return "Shader storage block interface";
5386*35238bceSAndroid Build Coastguard Worker     default:
5387*35238bceSAndroid Build Coastguard Worker         DE_FATAL("invalid storage enum value");
5388*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
5389*35238bceSAndroid Build Coastguard Worker     }
5390*35238bceSAndroid Build Coastguard Worker }
5391*35238bceSAndroid Build Coastguard Worker 
5392*35238bceSAndroid Build Coastguard Worker class AtomicCounterTestGroup : public TestCaseGroup
5393*35238bceSAndroid Build Coastguard Worker {
5394*35238bceSAndroid Build Coastguard Worker public:
5395*35238bceSAndroid Build Coastguard Worker     AtomicCounterTestGroup(Context &context);
5396*35238bceSAndroid Build Coastguard Worker     void init(void);
5397*35238bceSAndroid Build Coastguard Worker };
5398*35238bceSAndroid Build Coastguard Worker 
AtomicCounterTestGroup(Context & context)5399*35238bceSAndroid Build Coastguard Worker AtomicCounterTestGroup::AtomicCounterTestGroup(Context &context)
5400*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
5401*35238bceSAndroid Build Coastguard Worker {
5402*35238bceSAndroid Build Coastguard Worker }
5403*35238bceSAndroid Build Coastguard Worker 
init(void)5404*35238bceSAndroid Build Coastguard Worker void AtomicCounterTestGroup::init(void)
5405*35238bceSAndroid Build Coastguard Worker {
5406*35238bceSAndroid Build Coastguard Worker     static const struct
5407*35238bceSAndroid Build Coastguard Worker     {
5408*35238bceSAndroid Build Coastguard Worker         const char *name;
5409*35238bceSAndroid Build Coastguard Worker         uint32_t flags;
5410*35238bceSAndroid Build Coastguard Worker     } pipelines[] = {
5411*35238bceSAndroid Build Coastguard Worker         {"vertex_fragment", (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)},
5412*35238bceSAndroid Build Coastguard Worker         {"vertex_tess_fragment", (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) |
5413*35238bceSAndroid Build Coastguard Worker                                      (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) |
5414*35238bceSAndroid Build Coastguard Worker                                      (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)},
5415*35238bceSAndroid Build Coastguard Worker         {"vertex_geo_fragment",
5416*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)},
5417*35238bceSAndroid Build Coastguard Worker         {
5418*35238bceSAndroid Build Coastguard Worker             "vertex_tess_geo_fragment",
5419*35238bceSAndroid Build Coastguard Worker             (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) |
5420*35238bceSAndroid Build Coastguard Worker                 (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) |
5421*35238bceSAndroid Build Coastguard Worker                 (1 << glu::SHADERTYPE_GEOMETRY),
5422*35238bceSAndroid Build Coastguard Worker         },
5423*35238bceSAndroid Build Coastguard Worker     };
5424*35238bceSAndroid Build Coastguard Worker 
5425*35238bceSAndroid Build Coastguard Worker     // .resource_list
5426*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
5427*35238bceSAndroid Build Coastguard Worker 
5428*35238bceSAndroid Build Coastguard Worker     // .active_variables
5429*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
5430*35238bceSAndroid Build Coastguard Worker 
5431*35238bceSAndroid Build Coastguard Worker     // .buffer_binding
5432*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
5433*35238bceSAndroid Build Coastguard Worker 
5434*35238bceSAndroid Build Coastguard Worker     // .buffer_data_size
5435*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
5436*35238bceSAndroid Build Coastguard Worker 
5437*35238bceSAndroid Build Coastguard Worker     // .referenced_by
5438*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false,
5439*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
5440*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true,
5441*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
5442*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true,
5443*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
5444*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true,
5445*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
5446*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true,
5447*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_TESSELLATION_CONTROL),
5448*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
5449*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true,
5450*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
5451*35238bceSAndroid Build Coastguard Worker                                                (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
5452*35238bceSAndroid Build Coastguard Worker 
5453*35238bceSAndroid Build Coastguard Worker     for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
5454*35238bceSAndroid Build Coastguard Worker     {
5455*35238bceSAndroid Build Coastguard Worker         addChild(new AtomicCounterReferencedByCase(
5456*35238bceSAndroid Build Coastguard Worker             m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false,
5457*35238bceSAndroid Build Coastguard Worker             pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
5458*35238bceSAndroid Build Coastguard Worker 
5459*35238bceSAndroid Build Coastguard Worker         for (uint32_t stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5460*35238bceSAndroid Build Coastguard Worker         {
5461*35238bceSAndroid Build Coastguard Worker             const uint32_t currentBit = (1u << stageNdx);
5462*35238bceSAndroid Build Coastguard Worker             if (currentBit > pipelines[pipelineNdx].flags)
5463*35238bceSAndroid Build Coastguard Worker                 break;
5464*35238bceSAndroid Build Coastguard Worker             if (currentBit & pipelines[pipelineNdx].flags)
5465*35238bceSAndroid Build Coastguard Worker             {
5466*35238bceSAndroid Build Coastguard Worker                 const char *stageName = (stageNdx == glu::SHADERTYPE_VERTEX)                  ? ("vertex") :
5467*35238bceSAndroid Build Coastguard Worker                                         (stageNdx == glu::SHADERTYPE_FRAGMENT)                ? ("fragment") :
5468*35238bceSAndroid Build Coastguard Worker                                         (stageNdx == glu::SHADERTYPE_GEOMETRY)                ? ("geo") :
5469*35238bceSAndroid Build Coastguard Worker                                         (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL)    ? ("tess_ctrl") :
5470*35238bceSAndroid Build Coastguard Worker                                         (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval") :
5471*35238bceSAndroid Build Coastguard Worker                                                                                                 (DE_NULL);
5472*35238bceSAndroid Build Coastguard Worker                 const std::string name =
5473*35238bceSAndroid Build Coastguard Worker                     std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5474*35238bceSAndroid Build Coastguard Worker 
5475*35238bceSAndroid Build Coastguard Worker                 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false,
5476*35238bceSAndroid Build Coastguard Worker                                                            pipelines[pipelineNdx].flags, currentBit));
5477*35238bceSAndroid Build Coastguard Worker             }
5478*35238bceSAndroid Build Coastguard Worker         }
5479*35238bceSAndroid Build Coastguard Worker     }
5480*35238bceSAndroid Build Coastguard Worker }
5481*35238bceSAndroid Build Coastguard Worker 
generateProgramInputOutputShaderCaseBlocks(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion,bool withCompute,bool inputCase,bool isGL45,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup *,uint32_t,bool))5482*35238bceSAndroid Build Coastguard Worker static void generateProgramInputOutputShaderCaseBlocks(
5483*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *targetGroup, glu::GLSLVersion glslVersion, bool withCompute, bool inputCase,
5484*35238bceSAndroid Build Coastguard Worker     bool isGL45,
5485*35238bceSAndroid Build Coastguard Worker     void (*blockContentGenerator)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *,
5486*35238bceSAndroid Build Coastguard Worker                                   uint32_t, bool))
5487*35238bceSAndroid Build Coastguard Worker {
5488*35238bceSAndroid Build Coastguard Worker     static const struct
5489*35238bceSAndroid Build Coastguard Worker     {
5490*35238bceSAndroid Build Coastguard Worker         const char *name;
5491*35238bceSAndroid Build Coastguard Worker         glu::ShaderType stage;
5492*35238bceSAndroid Build Coastguard Worker     } singleStageCases[] = {
5493*35238bceSAndroid Build Coastguard Worker         {"separable_vertex", glu::SHADERTYPE_VERTEX},
5494*35238bceSAndroid Build Coastguard Worker         {"separable_fragment", glu::SHADERTYPE_FRAGMENT},
5495*35238bceSAndroid Build Coastguard Worker         {"separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL},
5496*35238bceSAndroid Build Coastguard Worker         {"separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION},
5497*35238bceSAndroid Build Coastguard Worker         {"separable_geometry", glu::SHADERTYPE_GEOMETRY},
5498*35238bceSAndroid Build Coastguard Worker     };
5499*35238bceSAndroid Build Coastguard Worker 
5500*35238bceSAndroid Build Coastguard Worker     // .vertex_fragment
5501*35238bceSAndroid Build Coastguard Worker     {
5502*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5503*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(false));
5504*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::ShaderSet *shaderSetPtr = new ResourceDefinition::ShaderSet(program, glslVersion);
5505*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr shaderSet(shaderSetPtr);
5506*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shaderSet));
5507*35238bceSAndroid Build Coastguard Worker 
5508*35238bceSAndroid Build Coastguard Worker         shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5509*35238bceSAndroid Build Coastguard Worker         shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5510*35238bceSAndroid Build Coastguard Worker 
5511*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
5512*35238bceSAndroid Build Coastguard Worker 
5513*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, defaultBlock, blockGroup,
5514*35238bceSAndroid Build Coastguard Worker                               (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT), isGL45);
5515*35238bceSAndroid Build Coastguard Worker     }
5516*35238bceSAndroid Build Coastguard Worker 
5517*35238bceSAndroid Build Coastguard Worker     // .separable_*
5518*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5519*35238bceSAndroid Build Coastguard Worker     {
5520*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5521*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
5522*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr shader(
5523*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
5524*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
5525*35238bceSAndroid Build Coastguard Worker 
5526*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
5527*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage), isGL45);
5528*35238bceSAndroid Build Coastguard Worker     }
5529*35238bceSAndroid Build Coastguard Worker 
5530*35238bceSAndroid Build Coastguard Worker     // .compute
5531*35238bceSAndroid Build Coastguard Worker     if (withCompute)
5532*35238bceSAndroid Build Coastguard Worker     {
5533*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5534*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
5535*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr shader(
5536*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5537*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
5538*35238bceSAndroid Build Coastguard Worker 
5539*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
5540*35238bceSAndroid Build Coastguard Worker 
5541*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE), isGL45);
5542*35238bceSAndroid Build Coastguard Worker     }
5543*35238bceSAndroid Build Coastguard Worker 
5544*35238bceSAndroid Build Coastguard Worker     // .interface_blocks
5545*35238bceSAndroid Build Coastguard Worker     {
5546*35238bceSAndroid Build Coastguard Worker         static const struct
5547*35238bceSAndroid Build Coastguard Worker         {
5548*35238bceSAndroid Build Coastguard Worker             const char *inputName;
5549*35238bceSAndroid Build Coastguard Worker             glu::ShaderType inputStage;
5550*35238bceSAndroid Build Coastguard Worker             glu::Storage inputStorage;
5551*35238bceSAndroid Build Coastguard Worker             const char *outputName;
5552*35238bceSAndroid Build Coastguard Worker             glu::ShaderType outputStage;
5553*35238bceSAndroid Build Coastguard Worker             glu::Storage outputStorage;
5554*35238bceSAndroid Build Coastguard Worker         } ioBlockTypes[] = {
5555*35238bceSAndroid Build Coastguard Worker             {
5556*35238bceSAndroid Build Coastguard Worker                 "in",
5557*35238bceSAndroid Build Coastguard Worker                 glu::SHADERTYPE_FRAGMENT,
5558*35238bceSAndroid Build Coastguard Worker                 glu::STORAGE_IN,
5559*35238bceSAndroid Build Coastguard Worker                 "out",
5560*35238bceSAndroid Build Coastguard Worker                 glu::SHADERTYPE_VERTEX,
5561*35238bceSAndroid Build Coastguard Worker                 glu::STORAGE_OUT,
5562*35238bceSAndroid Build Coastguard Worker             },
5563*35238bceSAndroid Build Coastguard Worker             {
5564*35238bceSAndroid Build Coastguard Worker                 "patch_in",
5565*35238bceSAndroid Build Coastguard Worker                 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5566*35238bceSAndroid Build Coastguard Worker                 glu::STORAGE_PATCH_IN,
5567*35238bceSAndroid Build Coastguard Worker                 "patch_out",
5568*35238bceSAndroid Build Coastguard Worker                 glu::SHADERTYPE_TESSELLATION_CONTROL,
5569*35238bceSAndroid Build Coastguard Worker                 glu::STORAGE_PATCH_OUT,
5570*35238bceSAndroid Build Coastguard Worker             },
5571*35238bceSAndroid Build Coastguard Worker         };
5572*35238bceSAndroid Build Coastguard Worker 
5573*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5574*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(ioBlocksGroup);
5575*35238bceSAndroid Build Coastguard Worker 
5576*35238bceSAndroid Build Coastguard Worker         // .in/out
5577*35238bceSAndroid Build Coastguard Worker         // .sample in/out
5578*35238bceSAndroid Build Coastguard Worker         // .patch in/out
5579*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5580*35238bceSAndroid Build Coastguard Worker         {
5581*35238bceSAndroid Build Coastguard Worker             const char *const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5582*35238bceSAndroid Build Coastguard Worker             const glu::ShaderType shaderType =
5583*35238bceSAndroid Build Coastguard Worker                 (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5584*35238bceSAndroid Build Coastguard Worker             const glu::Storage storageType =
5585*35238bceSAndroid Build Coastguard Worker                 (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5586*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const ioBlockGroup = new TestCaseGroup(context, name, "");
5587*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
5588*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr shader(
5589*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Shader(program, shaderType, glslVersion));
5590*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
5591*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr storage(
5592*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5593*35238bceSAndroid Build Coastguard Worker 
5594*35238bceSAndroid Build Coastguard Worker             ioBlocksGroup->addChild(ioBlockGroup);
5595*35238bceSAndroid Build Coastguard Worker 
5596*35238bceSAndroid Build Coastguard Worker             // .named_block
5597*35238bceSAndroid Build Coastguard Worker             {
5598*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(storage, true));
5599*35238bceSAndroid Build Coastguard Worker                 tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5600*35238bceSAndroid Build Coastguard Worker 
5601*35238bceSAndroid Build Coastguard Worker                 ioBlockGroup->addChild(blockGroup);
5602*35238bceSAndroid Build Coastguard Worker 
5603*35238bceSAndroid Build Coastguard Worker                 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5604*35238bceSAndroid Build Coastguard Worker             }
5605*35238bceSAndroid Build Coastguard Worker 
5606*35238bceSAndroid Build Coastguard Worker             // .named_block_explicit_location
5607*35238bceSAndroid Build Coastguard Worker             {
5608*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr layout(
5609*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5610*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(layout, true));
5611*35238bceSAndroid Build Coastguard Worker                 tcu::TestCaseGroup *const blockGroup =
5612*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5613*35238bceSAndroid Build Coastguard Worker 
5614*35238bceSAndroid Build Coastguard Worker                 ioBlockGroup->addChild(blockGroup);
5615*35238bceSAndroid Build Coastguard Worker 
5616*35238bceSAndroid Build Coastguard Worker                 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5617*35238bceSAndroid Build Coastguard Worker             }
5618*35238bceSAndroid Build Coastguard Worker 
5619*35238bceSAndroid Build Coastguard Worker             // .unnamed_block
5620*35238bceSAndroid Build Coastguard Worker             if (!isGL45)
5621*35238bceSAndroid Build Coastguard Worker             {
5622*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(storage, false));
5623*35238bceSAndroid Build Coastguard Worker                 tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5624*35238bceSAndroid Build Coastguard Worker 
5625*35238bceSAndroid Build Coastguard Worker                 ioBlockGroup->addChild(blockGroup);
5626*35238bceSAndroid Build Coastguard Worker 
5627*35238bceSAndroid Build Coastguard Worker                 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5628*35238bceSAndroid Build Coastguard Worker             }
5629*35238bceSAndroid Build Coastguard Worker 
5630*35238bceSAndroid Build Coastguard Worker             // .block_array
5631*35238bceSAndroid Build Coastguard Worker             {
5632*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(storage));
5633*35238bceSAndroid Build Coastguard Worker                 const ResourceDefinition::Node::SharedPtr block(
5634*35238bceSAndroid Build Coastguard Worker                     new ResourceDefinition::InterfaceBlock(arrayElement, true));
5635*35238bceSAndroid Build Coastguard Worker                 tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5636*35238bceSAndroid Build Coastguard Worker 
5637*35238bceSAndroid Build Coastguard Worker                 ioBlockGroup->addChild(blockGroup);
5638*35238bceSAndroid Build Coastguard Worker 
5639*35238bceSAndroid Build Coastguard Worker                 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5640*35238bceSAndroid Build Coastguard Worker             }
5641*35238bceSAndroid Build Coastguard Worker         }
5642*35238bceSAndroid Build Coastguard Worker     }
5643*35238bceSAndroid Build Coastguard Worker }
5644*35238bceSAndroid Build Coastguard Worker 
generateProgramInputBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool includeEmpty,void (* genCase)(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramInterface interface,const char * name))5645*35238bceSAndroid Build Coastguard Worker static void generateProgramInputBlockContents(
5646*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
5647*35238bceSAndroid Build Coastguard Worker     uint32_t presentShadersMask, bool includeEmpty,
5648*35238bceSAndroid Build Coastguard Worker     void (*genCase)(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
5649*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *targetGroup, ProgramInterface interface, const char *name))
5650*35238bceSAndroid Build Coastguard Worker {
5651*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5652*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr input =
5653*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
5654*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN))) :
5655*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
5656*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5657*35238bceSAndroid Build Coastguard Worker 
5658*35238bceSAndroid Build Coastguard Worker     // .empty
5659*35238bceSAndroid Build Coastguard Worker     if (includeEmpty && inDefaultBlock)
5660*35238bceSAndroid Build Coastguard Worker         genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5661*35238bceSAndroid Build Coastguard Worker 
5662*35238bceSAndroid Build Coastguard Worker     if (firstStage == glu::SHADERTYPE_VERTEX)
5663*35238bceSAndroid Build Coastguard Worker     {
5664*35238bceSAndroid Build Coastguard Worker         // .var
5665*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
5666*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5667*35238bceSAndroid Build Coastguard Worker         genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5668*35238bceSAndroid Build Coastguard Worker     }
5669*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5670*35238bceSAndroid Build Coastguard Worker     {
5671*35238bceSAndroid Build Coastguard Worker         // .var
5672*35238bceSAndroid Build Coastguard Worker         {
5673*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5674*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5675*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5676*35238bceSAndroid Build Coastguard Worker         }
5677*35238bceSAndroid Build Coastguard Worker         // .var_struct
5678*35238bceSAndroid Build Coastguard Worker         {
5679*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(input));
5680*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5681*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5682*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5683*35238bceSAndroid Build Coastguard Worker         }
5684*35238bceSAndroid Build Coastguard Worker         // .var_array
5685*35238bceSAndroid Build Coastguard Worker         {
5686*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(input));
5687*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5688*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5689*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5690*35238bceSAndroid Build Coastguard Worker         }
5691*35238bceSAndroid Build Coastguard Worker     }
5692*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL || firstStage == glu::SHADERTYPE_GEOMETRY)
5693*35238bceSAndroid Build Coastguard Worker     {
5694*35238bceSAndroid Build Coastguard Worker         // arrayed interface
5695*35238bceSAndroid Build Coastguard Worker 
5696*35238bceSAndroid Build Coastguard Worker         // .var
5697*35238bceSAndroid Build Coastguard Worker         {
5698*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
5699*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5700*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5701*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5702*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5703*35238bceSAndroid Build Coastguard Worker         }
5704*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
5705*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
5706*35238bceSAndroid Build Coastguard Worker     }
5707*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5708*35238bceSAndroid Build Coastguard Worker     {
5709*35238bceSAndroid Build Coastguard Worker         // arrayed interface
5710*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchInput(
5711*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5712*35238bceSAndroid Build Coastguard Worker 
5713*35238bceSAndroid Build Coastguard Worker         // .var
5714*35238bceSAndroid Build Coastguard Worker         {
5715*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
5716*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5717*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5718*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5719*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5720*35238bceSAndroid Build Coastguard Worker         }
5721*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
5722*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
5723*35238bceSAndroid Build Coastguard Worker 
5724*35238bceSAndroid Build Coastguard Worker         // .patch_var
5725*35238bceSAndroid Build Coastguard Worker         {
5726*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5727*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5728*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5729*35238bceSAndroid Build Coastguard Worker         }
5730*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
5731*35238bceSAndroid Build Coastguard Worker         {
5732*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchInput));
5733*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5734*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5735*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5736*35238bceSAndroid Build Coastguard Worker         }
5737*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
5738*35238bceSAndroid Build Coastguard Worker         {
5739*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchInput));
5740*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5741*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5742*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5743*35238bceSAndroid Build Coastguard Worker         }
5744*35238bceSAndroid Build Coastguard Worker     }
5745*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_COMPUTE)
5746*35238bceSAndroid Build Coastguard Worker     {
5747*35238bceSAndroid Build Coastguard Worker         // nada
5748*35238bceSAndroid Build Coastguard Worker     }
5749*35238bceSAndroid Build Coastguard Worker     else
5750*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
5751*35238bceSAndroid Build Coastguard Worker }
5752*35238bceSAndroid Build Coastguard Worker 
generateProgramOutputBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool includeEmpty,void (* genCase)(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramInterface interface,const char * name))5753*35238bceSAndroid Build Coastguard Worker static void generateProgramOutputBlockContents(
5754*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
5755*35238bceSAndroid Build Coastguard Worker     uint32_t presentShadersMask, bool includeEmpty,
5756*35238bceSAndroid Build Coastguard Worker     void (*genCase)(Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure,
5757*35238bceSAndroid Build Coastguard Worker                     tcu::TestCaseGroup *targetGroup, ProgramInterface interface, const char *name))
5758*35238bceSAndroid Build Coastguard Worker {
5759*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5760*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output =
5761*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
5762*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT))) :
5763*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
5764*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5765*35238bceSAndroid Build Coastguard Worker 
5766*35238bceSAndroid Build Coastguard Worker     // .empty
5767*35238bceSAndroid Build Coastguard Worker     if (includeEmpty && inDefaultBlock)
5768*35238bceSAndroid Build Coastguard Worker         genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5769*35238bceSAndroid Build Coastguard Worker 
5770*35238bceSAndroid Build Coastguard Worker     if (lastStage == glu::SHADERTYPE_VERTEX || lastStage == glu::SHADERTYPE_GEOMETRY ||
5771*35238bceSAndroid Build Coastguard Worker         lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION || !inDefaultBlock)
5772*35238bceSAndroid Build Coastguard Worker     {
5773*35238bceSAndroid Build Coastguard Worker         // .var
5774*35238bceSAndroid Build Coastguard Worker         {
5775*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5776*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5777*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5778*35238bceSAndroid Build Coastguard Worker         }
5779*35238bceSAndroid Build Coastguard Worker         // .var_struct
5780*35238bceSAndroid Build Coastguard Worker         {
5781*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(output));
5782*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5783*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5784*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5785*35238bceSAndroid Build Coastguard Worker         }
5786*35238bceSAndroid Build Coastguard Worker         // .var_array
5787*35238bceSAndroid Build Coastguard Worker         {
5788*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
5789*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5790*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5791*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5792*35238bceSAndroid Build Coastguard Worker         }
5793*35238bceSAndroid Build Coastguard Worker     }
5794*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5795*35238bceSAndroid Build Coastguard Worker     {
5796*35238bceSAndroid Build Coastguard Worker         // .var
5797*35238bceSAndroid Build Coastguard Worker         {
5798*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5799*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5800*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5801*35238bceSAndroid Build Coastguard Worker         }
5802*35238bceSAndroid Build Coastguard Worker         // .var_array
5803*35238bceSAndroid Build Coastguard Worker         {
5804*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
5805*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5806*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5807*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5808*35238bceSAndroid Build Coastguard Worker         }
5809*35238bceSAndroid Build Coastguard Worker     }
5810*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5811*35238bceSAndroid Build Coastguard Worker     {
5812*35238bceSAndroid Build Coastguard Worker         // arrayed interface
5813*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchOutput(
5814*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5815*35238bceSAndroid Build Coastguard Worker 
5816*35238bceSAndroid Build Coastguard Worker         // .var
5817*35238bceSAndroid Build Coastguard Worker         {
5818*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
5819*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5820*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5821*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5822*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5823*35238bceSAndroid Build Coastguard Worker         }
5824*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
5825*35238bceSAndroid Build Coastguard Worker         // extension forbids use array of arrays
5826*35238bceSAndroid Build Coastguard Worker 
5827*35238bceSAndroid Build Coastguard Worker         // .patch_var
5828*35238bceSAndroid Build Coastguard Worker         {
5829*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5830*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5831*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5832*35238bceSAndroid Build Coastguard Worker         }
5833*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
5834*35238bceSAndroid Build Coastguard Worker         {
5835*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchOutput));
5836*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5837*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5838*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5839*35238bceSAndroid Build Coastguard Worker         }
5840*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
5841*35238bceSAndroid Build Coastguard Worker         {
5842*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchOutput));
5843*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5844*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5845*35238bceSAndroid Build Coastguard Worker             genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5846*35238bceSAndroid Build Coastguard Worker         }
5847*35238bceSAndroid Build Coastguard Worker     }
5848*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_COMPUTE)
5849*35238bceSAndroid Build Coastguard Worker     {
5850*35238bceSAndroid Build Coastguard Worker         // nada
5851*35238bceSAndroid Build Coastguard Worker     }
5852*35238bceSAndroid Build Coastguard Worker     else
5853*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
5854*35238bceSAndroid Build Coastguard Worker }
5855*35238bceSAndroid Build Coastguard Worker 
addProgramInputOutputResourceListCase(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramInterface programInterface,const char * name)5856*35238bceSAndroid Build Coastguard Worker static void addProgramInputOutputResourceListCase(Context &context,
5857*35238bceSAndroid Build Coastguard Worker                                                   const ResourceDefinition::Node::SharedPtr &parentStructure,
5858*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *targetGroup, ProgramInterface programInterface,
5859*35238bceSAndroid Build Coastguard Worker                                                   const char *name)
5860*35238bceSAndroid Build Coastguard Worker {
5861*35238bceSAndroid Build Coastguard Worker     ResourceListTestCase *const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5862*35238bceSAndroid Build Coastguard Worker 
5863*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5864*35238bceSAndroid Build Coastguard Worker     DE_UNREF(name);
5865*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(resourceListCase);
5866*35238bceSAndroid Build Coastguard Worker }
5867*35238bceSAndroid Build Coastguard Worker 
generateProgramInputResourceListBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)5868*35238bceSAndroid Build Coastguard Worker static void generateProgramInputResourceListBlockContents(Context &context,
5869*35238bceSAndroid Build Coastguard Worker                                                           const ResourceDefinition::Node::SharedPtr &parentStructure,
5870*35238bceSAndroid Build Coastguard Worker                                                           tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
5871*35238bceSAndroid Build Coastguard Worker                                                           bool isGL45)
5872*35238bceSAndroid Build Coastguard Worker {
5873*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
5874*35238bceSAndroid Build Coastguard Worker     generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true,
5875*35238bceSAndroid Build Coastguard Worker                                       addProgramInputOutputResourceListCase);
5876*35238bceSAndroid Build Coastguard Worker }
5877*35238bceSAndroid Build Coastguard Worker 
generateProgramOutputResourceListBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)5878*35238bceSAndroid Build Coastguard Worker static void generateProgramOutputResourceListBlockContents(Context &context,
5879*35238bceSAndroid Build Coastguard Worker                                                            const ResourceDefinition::Node::SharedPtr &parentStructure,
5880*35238bceSAndroid Build Coastguard Worker                                                            tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
5881*35238bceSAndroid Build Coastguard Worker                                                            bool isGL45)
5882*35238bceSAndroid Build Coastguard Worker {
5883*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
5884*35238bceSAndroid Build Coastguard Worker     generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true,
5885*35238bceSAndroid Build Coastguard Worker                                        addProgramInputOutputResourceListCase);
5886*35238bceSAndroid Build Coastguard Worker }
5887*35238bceSAndroid Build Coastguard Worker 
5888*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
addProgramInputOutputResourceTestCase(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramInterface programInterface,const char * name)5889*35238bceSAndroid Build Coastguard Worker static void addProgramInputOutputResourceTestCase(Context &context,
5890*35238bceSAndroid Build Coastguard Worker                                                   const ResourceDefinition::Node::SharedPtr &parentStructure,
5891*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *targetGroup, ProgramInterface programInterface,
5892*35238bceSAndroid Build Coastguard Worker                                                   const char *name)
5893*35238bceSAndroid Build Coastguard Worker {
5894*35238bceSAndroid Build Coastguard Worker     ResourceTestCase *const resourceTestCase = new ResourceTestCase(
5895*35238bceSAndroid Build Coastguard Worker         context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5896*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(resourceTestCase);
5897*35238bceSAndroid Build Coastguard Worker }
5898*35238bceSAndroid Build Coastguard Worker 
5899*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateProgramInputBasicBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)5900*35238bceSAndroid Build Coastguard Worker static void generateProgramInputBasicBlockContents(Context &context,
5901*35238bceSAndroid Build Coastguard Worker                                                    const ResourceDefinition::Node::SharedPtr &parentStructure,
5902*35238bceSAndroid Build Coastguard Worker                                                    tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
5903*35238bceSAndroid Build Coastguard Worker                                                    bool isGL45)
5904*35238bceSAndroid Build Coastguard Worker {
5905*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
5906*35238bceSAndroid Build Coastguard Worker     generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false,
5907*35238bceSAndroid Build Coastguard Worker                                       addProgramInputOutputResourceTestCase<TargetProp>);
5908*35238bceSAndroid Build Coastguard Worker }
5909*35238bceSAndroid Build Coastguard Worker 
5910*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateProgramOutputBasicBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)5911*35238bceSAndroid Build Coastguard Worker static void generateProgramOutputBasicBlockContents(Context &context,
5912*35238bceSAndroid Build Coastguard Worker                                                     const ResourceDefinition::Node::SharedPtr &parentStructure,
5913*35238bceSAndroid Build Coastguard Worker                                                     tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
5914*35238bceSAndroid Build Coastguard Worker                                                     bool isGL45)
5915*35238bceSAndroid Build Coastguard Worker {
5916*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
5917*35238bceSAndroid Build Coastguard Worker     generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false,
5918*35238bceSAndroid Build Coastguard Worker                                        addProgramInputOutputResourceTestCase<TargetProp>);
5919*35238bceSAndroid Build Coastguard Worker }
5920*35238bceSAndroid Build Coastguard Worker 
generateProgramInputLocationBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)5921*35238bceSAndroid Build Coastguard Worker static void generateProgramInputLocationBlockContents(Context &context,
5922*35238bceSAndroid Build Coastguard Worker                                                       const ResourceDefinition::Node::SharedPtr &parentStructure,
5923*35238bceSAndroid Build Coastguard Worker                                                       tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
5924*35238bceSAndroid Build Coastguard Worker                                                       bool isGL45)
5925*35238bceSAndroid Build Coastguard Worker {
5926*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
5927*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5928*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr input =
5929*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
5930*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN))) :
5931*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
5932*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5933*35238bceSAndroid Build Coastguard Worker 
5934*35238bceSAndroid Build Coastguard Worker     const bool inBlockArray = true == deStringEqual("block_array", targetGroup->getName());
5935*35238bceSAndroid Build Coastguard Worker 
5936*35238bceSAndroid Build Coastguard Worker     if (firstStage == glu::SHADERTYPE_VERTEX)
5937*35238bceSAndroid Build Coastguard Worker     {
5938*35238bceSAndroid Build Coastguard Worker         // .var
5939*35238bceSAndroid Build Coastguard Worker         {
5940*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5941*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5942*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5943*35238bceSAndroid Build Coastguard Worker                 context, variable,
5944*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5945*35238bceSAndroid Build Coastguard Worker         }
5946*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
5947*35238bceSAndroid Build Coastguard Worker         {
5948*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
5949*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5950*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5951*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5952*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5953*35238bceSAndroid Build Coastguard Worker                 context, variable,
5954*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
5955*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
5956*35238bceSAndroid Build Coastguard Worker         }
5957*35238bceSAndroid Build Coastguard Worker     }
5958*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5959*35238bceSAndroid Build Coastguard Worker     {
5960*35238bceSAndroid Build Coastguard Worker         // .var
5961*35238bceSAndroid Build Coastguard Worker         {
5962*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5963*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5964*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5965*35238bceSAndroid Build Coastguard Worker                 context, variable,
5966*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5967*35238bceSAndroid Build Coastguard Worker         }
5968*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
5969*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
5970*35238bceSAndroid Build Coastguard Worker         {
5971*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
5972*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5973*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5974*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5975*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5976*35238bceSAndroid Build Coastguard Worker                 context, variable,
5977*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
5978*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
5979*35238bceSAndroid Build Coastguard Worker         }
5980*35238bceSAndroid Build Coastguard Worker         // .var_struct
5981*35238bceSAndroid Build Coastguard Worker         {
5982*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(input));
5983*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5984*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5985*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5986*35238bceSAndroid Build Coastguard Worker                 context, variable,
5987*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
5988*35238bceSAndroid Build Coastguard Worker                 "var_struct"));
5989*35238bceSAndroid Build Coastguard Worker         }
5990*35238bceSAndroid Build Coastguard Worker         // .var_struct_explicit_location
5991*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
5992*35238bceSAndroid Build Coastguard Worker         {
5993*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
5994*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5995*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(layout));
5996*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
5997*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5998*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
5999*35238bceSAndroid Build Coastguard Worker                 context, variable,
6000*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6001*35238bceSAndroid Build Coastguard Worker                 "var_struct_explicit_location"));
6002*35238bceSAndroid Build Coastguard Worker         }
6003*35238bceSAndroid Build Coastguard Worker         // .var_array
6004*35238bceSAndroid Build Coastguard Worker         {
6005*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(input));
6006*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6007*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6008*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6009*35238bceSAndroid Build Coastguard Worker                 context, variable,
6010*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6011*35238bceSAndroid Build Coastguard Worker                 "var_array"));
6012*35238bceSAndroid Build Coastguard Worker         }
6013*35238bceSAndroid Build Coastguard Worker         // .var_array_explicit_location
6014*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6015*35238bceSAndroid Build Coastguard Worker         {
6016*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6017*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
6018*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(layout));
6019*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6020*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6021*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6022*35238bceSAndroid Build Coastguard Worker                 context, variable,
6023*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6024*35238bceSAndroid Build Coastguard Worker                 "var_array_explicit_location"));
6025*35238bceSAndroid Build Coastguard Worker         }
6026*35238bceSAndroid Build Coastguard Worker     }
6027*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL || firstStage == glu::SHADERTYPE_GEOMETRY)
6028*35238bceSAndroid Build Coastguard Worker     {
6029*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6030*35238bceSAndroid Build Coastguard Worker 
6031*35238bceSAndroid Build Coastguard Worker         // .var
6032*35238bceSAndroid Build Coastguard Worker         {
6033*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6034*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6035*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6036*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6037*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6038*35238bceSAndroid Build Coastguard Worker                 context, variable,
6039*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
6040*35238bceSAndroid Build Coastguard Worker         }
6041*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
6042*35238bceSAndroid Build Coastguard Worker         {
6043*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6044*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
6045*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6046*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6047*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6048*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6049*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6050*35238bceSAndroid Build Coastguard Worker                 context, variable,
6051*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6052*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
6053*35238bceSAndroid Build Coastguard Worker         }
6054*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
6055*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
6056*35238bceSAndroid Build Coastguard Worker     }
6057*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
6058*35238bceSAndroid Build Coastguard Worker     {
6059*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6060*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchInput(
6061*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
6062*35238bceSAndroid Build Coastguard Worker 
6063*35238bceSAndroid Build Coastguard Worker         // .var
6064*35238bceSAndroid Build Coastguard Worker         {
6065*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6066*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6067*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6068*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6069*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6070*35238bceSAndroid Build Coastguard Worker                 context, variable,
6071*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
6072*35238bceSAndroid Build Coastguard Worker         }
6073*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
6074*35238bceSAndroid Build Coastguard Worker         {
6075*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6076*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
6077*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6078*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6079*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6080*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6081*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6082*35238bceSAndroid Build Coastguard Worker                 context, variable,
6083*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6084*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
6085*35238bceSAndroid Build Coastguard Worker         }
6086*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
6087*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
6088*35238bceSAndroid Build Coastguard Worker 
6089*35238bceSAndroid Build Coastguard Worker         // .patch_var
6090*35238bceSAndroid Build Coastguard Worker         {
6091*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6092*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
6093*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6094*35238bceSAndroid Build Coastguard Worker                 context, variable,
6095*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6096*35238bceSAndroid Build Coastguard Worker                 "patch_var"));
6097*35238bceSAndroid Build Coastguard Worker         }
6098*35238bceSAndroid Build Coastguard Worker         // .patch_var_explicit_location
6099*35238bceSAndroid Build Coastguard Worker         {
6100*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6101*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
6102*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6103*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
6104*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6105*35238bceSAndroid Build Coastguard Worker                 context, variable,
6106*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6107*35238bceSAndroid Build Coastguard Worker                 "patch_var_explicit_location"));
6108*35238bceSAndroid Build Coastguard Worker         }
6109*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
6110*35238bceSAndroid Build Coastguard Worker         {
6111*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchInput));
6112*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6113*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6114*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6115*35238bceSAndroid Build Coastguard Worker                 context, variable,
6116*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6117*35238bceSAndroid Build Coastguard Worker                 "patch_var_struct"));
6118*35238bceSAndroid Build Coastguard Worker         }
6119*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct_explicit_location
6120*35238bceSAndroid Build Coastguard Worker         {
6121*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6122*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
6123*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(layout));
6124*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6125*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6126*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6127*35238bceSAndroid Build Coastguard Worker                 context, variable,
6128*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6129*35238bceSAndroid Build Coastguard Worker                 "patch_var_struct_explicit_location"));
6130*35238bceSAndroid Build Coastguard Worker         }
6131*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
6132*35238bceSAndroid Build Coastguard Worker         {
6133*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchInput));
6134*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6135*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6136*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6137*35238bceSAndroid Build Coastguard Worker                 context, variable,
6138*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6139*35238bceSAndroid Build Coastguard Worker                 "patch_var_array"));
6140*35238bceSAndroid Build Coastguard Worker         }
6141*35238bceSAndroid Build Coastguard Worker         // .patch_var_array_explicit_location
6142*35238bceSAndroid Build Coastguard Worker         {
6143*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6144*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
6145*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(layout));
6146*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6147*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6148*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6149*35238bceSAndroid Build Coastguard Worker                 context, variable,
6150*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION),
6151*35238bceSAndroid Build Coastguard Worker                 "patch_var_array_explicit_location"));
6152*35238bceSAndroid Build Coastguard Worker         }
6153*35238bceSAndroid Build Coastguard Worker     }
6154*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_COMPUTE)
6155*35238bceSAndroid Build Coastguard Worker     {
6156*35238bceSAndroid Build Coastguard Worker         // nada
6157*35238bceSAndroid Build Coastguard Worker     }
6158*35238bceSAndroid Build Coastguard Worker     else
6159*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6160*35238bceSAndroid Build Coastguard Worker }
6161*35238bceSAndroid Build Coastguard Worker 
generateProgramOutputLocationBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)6162*35238bceSAndroid Build Coastguard Worker static void generateProgramOutputLocationBlockContents(Context &context,
6163*35238bceSAndroid Build Coastguard Worker                                                        const ResourceDefinition::Node::SharedPtr &parentStructure,
6164*35238bceSAndroid Build Coastguard Worker                                                        tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
6165*35238bceSAndroid Build Coastguard Worker                                                        bool isGL45)
6166*35238bceSAndroid Build Coastguard Worker {
6167*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
6168*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
6169*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output =
6170*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
6171*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT))) :
6172*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
6173*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
6174*35238bceSAndroid Build Coastguard Worker 
6175*35238bceSAndroid Build Coastguard Worker     const bool inBlockArray = true == deStringEqual("block_array", targetGroup->getName());
6176*35238bceSAndroid Build Coastguard Worker 
6177*35238bceSAndroid Build Coastguard Worker     if (lastStage == glu::SHADERTYPE_VERTEX || lastStage == glu::SHADERTYPE_GEOMETRY ||
6178*35238bceSAndroid Build Coastguard Worker         lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION || !inDefaultBlock)
6179*35238bceSAndroid Build Coastguard Worker     {
6180*35238bceSAndroid Build Coastguard Worker         // .var
6181*35238bceSAndroid Build Coastguard Worker         {
6182*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6183*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
6184*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6185*35238bceSAndroid Build Coastguard Worker                 context, variable,
6186*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
6187*35238bceSAndroid Build Coastguard Worker         }
6188*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
6189*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6190*35238bceSAndroid Build Coastguard Worker         {
6191*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6192*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
6193*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6194*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
6195*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6196*35238bceSAndroid Build Coastguard Worker                 context, variable,
6197*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6198*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
6199*35238bceSAndroid Build Coastguard Worker         }
6200*35238bceSAndroid Build Coastguard Worker         // .var_struct
6201*35238bceSAndroid Build Coastguard Worker         {
6202*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(output));
6203*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6204*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6205*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6206*35238bceSAndroid Build Coastguard Worker                 context, variable,
6207*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6208*35238bceSAndroid Build Coastguard Worker                 "var_struct"));
6209*35238bceSAndroid Build Coastguard Worker         }
6210*35238bceSAndroid Build Coastguard Worker         // .var_struct_explicit_location
6211*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6212*35238bceSAndroid Build Coastguard Worker         {
6213*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6214*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
6215*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(layout));
6216*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6217*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6218*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6219*35238bceSAndroid Build Coastguard Worker                 context, variable,
6220*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6221*35238bceSAndroid Build Coastguard Worker                 "var_struct_explicit_location"));
6222*35238bceSAndroid Build Coastguard Worker         }
6223*35238bceSAndroid Build Coastguard Worker         // .var_array
6224*35238bceSAndroid Build Coastguard Worker         {
6225*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
6226*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6227*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6228*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6229*35238bceSAndroid Build Coastguard Worker                 context, variable,
6230*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6231*35238bceSAndroid Build Coastguard Worker                 "var_array"));
6232*35238bceSAndroid Build Coastguard Worker         }
6233*35238bceSAndroid Build Coastguard Worker         // .var_array_explicit_location
6234*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6235*35238bceSAndroid Build Coastguard Worker         {
6236*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6237*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
6238*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(layout));
6239*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6240*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6241*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6242*35238bceSAndroid Build Coastguard Worker                 context, variable,
6243*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6244*35238bceSAndroid Build Coastguard Worker                 "var_array_explicit_location"));
6245*35238bceSAndroid Build Coastguard Worker         }
6246*35238bceSAndroid Build Coastguard Worker     }
6247*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_FRAGMENT)
6248*35238bceSAndroid Build Coastguard Worker     {
6249*35238bceSAndroid Build Coastguard Worker         // .var
6250*35238bceSAndroid Build Coastguard Worker         {
6251*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6252*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
6253*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6254*35238bceSAndroid Build Coastguard Worker                 context, variable,
6255*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
6256*35238bceSAndroid Build Coastguard Worker         }
6257*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
6258*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6259*35238bceSAndroid Build Coastguard Worker         {
6260*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6261*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
6262*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6263*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
6264*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6265*35238bceSAndroid Build Coastguard Worker                 context, variable,
6266*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6267*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
6268*35238bceSAndroid Build Coastguard Worker         }
6269*35238bceSAndroid Build Coastguard Worker         // .var_array
6270*35238bceSAndroid Build Coastguard Worker         {
6271*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
6272*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6273*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6274*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6275*35238bceSAndroid Build Coastguard Worker                 context, variable,
6276*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6277*35238bceSAndroid Build Coastguard Worker                 "var_array"));
6278*35238bceSAndroid Build Coastguard Worker         }
6279*35238bceSAndroid Build Coastguard Worker         // .var_array_explicit_location
6280*35238bceSAndroid Build Coastguard Worker         if (!inBlockArray)
6281*35238bceSAndroid Build Coastguard Worker         {
6282*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6283*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
6284*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(layout));
6285*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6286*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6287*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6288*35238bceSAndroid Build Coastguard Worker                 context, variable,
6289*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6290*35238bceSAndroid Build Coastguard Worker                 "var_array_explicit_location"));
6291*35238bceSAndroid Build Coastguard Worker         }
6292*35238bceSAndroid Build Coastguard Worker     }
6293*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
6294*35238bceSAndroid Build Coastguard Worker     {
6295*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6296*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchOutput(
6297*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
6298*35238bceSAndroid Build Coastguard Worker 
6299*35238bceSAndroid Build Coastguard Worker         // .var
6300*35238bceSAndroid Build Coastguard Worker         {
6301*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6302*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6303*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6304*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6305*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6306*35238bceSAndroid Build Coastguard Worker                 context, variable,
6307*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
6308*35238bceSAndroid Build Coastguard Worker         }
6309*35238bceSAndroid Build Coastguard Worker         // .var_explicit_location
6310*35238bceSAndroid Build Coastguard Worker         {
6311*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6312*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
6313*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6314*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6315*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6316*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6317*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6318*35238bceSAndroid Build Coastguard Worker                 context, variable,
6319*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6320*35238bceSAndroid Build Coastguard Worker                 "var_explicit_location"));
6321*35238bceSAndroid Build Coastguard Worker         }
6322*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
6323*35238bceSAndroid Build Coastguard Worker         // extension forbids use array of arrays
6324*35238bceSAndroid Build Coastguard Worker 
6325*35238bceSAndroid Build Coastguard Worker         // .patch_var
6326*35238bceSAndroid Build Coastguard Worker         {
6327*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6328*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
6329*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6330*35238bceSAndroid Build Coastguard Worker                 context, variable,
6331*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6332*35238bceSAndroid Build Coastguard Worker                 "patch_var"));
6333*35238bceSAndroid Build Coastguard Worker         }
6334*35238bceSAndroid Build Coastguard Worker         // .patch_var_explicit_location
6335*35238bceSAndroid Build Coastguard Worker         {
6336*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6337*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
6338*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6339*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
6340*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6341*35238bceSAndroid Build Coastguard Worker                 context, variable,
6342*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6343*35238bceSAndroid Build Coastguard Worker                 "patch_var_explicit_location"));
6344*35238bceSAndroid Build Coastguard Worker         }
6345*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
6346*35238bceSAndroid Build Coastguard Worker         {
6347*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchOutput));
6348*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6349*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6350*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6351*35238bceSAndroid Build Coastguard Worker                 context, variable,
6352*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6353*35238bceSAndroid Build Coastguard Worker                 "patch_var_struct"));
6354*35238bceSAndroid Build Coastguard Worker         }
6355*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct_explicit_location
6356*35238bceSAndroid Build Coastguard Worker         {
6357*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6358*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
6359*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(layout));
6360*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6361*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
6362*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6363*35238bceSAndroid Build Coastguard Worker                 context, variable,
6364*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6365*35238bceSAndroid Build Coastguard Worker                 "patch_var_struct_explicit_location"));
6366*35238bceSAndroid Build Coastguard Worker         }
6367*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
6368*35238bceSAndroid Build Coastguard Worker         {
6369*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchOutput));
6370*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6371*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6372*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6373*35238bceSAndroid Build Coastguard Worker                 context, variable,
6374*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6375*35238bceSAndroid Build Coastguard Worker                 "patch_var_array"));
6376*35238bceSAndroid Build Coastguard Worker         }
6377*35238bceSAndroid Build Coastguard Worker         // .patch_var_array_explicit_location
6378*35238bceSAndroid Build Coastguard Worker         {
6379*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr layout(
6380*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
6381*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(layout));
6382*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6383*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6384*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6385*35238bceSAndroid Build Coastguard Worker                 context, variable,
6386*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION),
6387*35238bceSAndroid Build Coastguard Worker                 "patch_var_array_explicit_location"));
6388*35238bceSAndroid Build Coastguard Worker         }
6389*35238bceSAndroid Build Coastguard Worker     }
6390*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_COMPUTE)
6391*35238bceSAndroid Build Coastguard Worker     {
6392*35238bceSAndroid Build Coastguard Worker         // nada
6393*35238bceSAndroid Build Coastguard Worker     }
6394*35238bceSAndroid Build Coastguard Worker     else
6395*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6396*35238bceSAndroid Build Coastguard Worker }
6397*35238bceSAndroid Build Coastguard Worker 
generateProgramInputOutputReferencedByCases(Context & context,tcu::TestCaseGroup * targetGroup,glu::Storage storage)6398*35238bceSAndroid Build Coastguard Worker static void generateProgramInputOutputReferencedByCases(Context &context, tcu::TestCaseGroup *targetGroup,
6399*35238bceSAndroid Build Coastguard Worker                                                         glu::Storage storage)
6400*35238bceSAndroid Build Coastguard Worker {
6401*35238bceSAndroid Build Coastguard Worker     // all whole pipelines
6402*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6403*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage,
6404*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
6405*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6406*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage,
6407*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
6408*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6409*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage,
6410*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
6411*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6412*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage,
6413*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
6414*35238bceSAndroid Build Coastguard Worker 
6415*35238bceSAndroid Build Coastguard Worker     // all partial pipelines
6416*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6417*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage,
6418*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
6419*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6420*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage,
6421*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
6422*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6423*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage,
6424*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
6425*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6426*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage,
6427*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
6428*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(
6429*35238bceSAndroid Build Coastguard Worker         new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage,
6430*35238bceSAndroid Build Coastguard Worker                                                ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
6431*35238bceSAndroid Build Coastguard Worker 
6432*35238bceSAndroid Build Coastguard Worker     // patch
6433*35238bceSAndroid Build Coastguard Worker     if (storage == glu::STORAGE_IN)
6434*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ProgramInputOutputReferencedByCase(
6435*35238bceSAndroid Build Coastguard Worker             context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN,
6436*35238bceSAndroid Build Coastguard Worker             ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
6437*35238bceSAndroid Build Coastguard Worker     else if (storage == glu::STORAGE_OUT)
6438*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ProgramInputOutputReferencedByCase(
6439*35238bceSAndroid Build Coastguard Worker             context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT,
6440*35238bceSAndroid Build Coastguard Worker             ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
6441*35238bceSAndroid Build Coastguard Worker     else
6442*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6443*35238bceSAndroid Build Coastguard Worker }
6444*35238bceSAndroid Build Coastguard Worker 
6445*35238bceSAndroid Build Coastguard Worker template <ProgramInterface interface>
generateProgramInputOutputTypeBasicTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool allowMatrixCases,int expandLevel)6446*35238bceSAndroid Build Coastguard Worker static void generateProgramInputOutputTypeBasicTypeCases(Context &context,
6447*35238bceSAndroid Build Coastguard Worker                                                          const ResourceDefinition::Node::SharedPtr &parentStructure,
6448*35238bceSAndroid Build Coastguard Worker                                                          tcu::TestCaseGroup *targetGroup, bool allowMatrixCases,
6449*35238bceSAndroid Build Coastguard Worker                                                          int expandLevel)
6450*35238bceSAndroid Build Coastguard Worker {
6451*35238bceSAndroid Build Coastguard Worker     static const struct
6452*35238bceSAndroid Build Coastguard Worker     {
6453*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
6454*35238bceSAndroid Build Coastguard Worker         bool isMatrix;
6455*35238bceSAndroid Build Coastguard Worker         int level;
6456*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
6457*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT, false, 0},       {glu::TYPE_INT, false, 1},         {glu::TYPE_UINT, false, 1},
6458*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_VEC2, false, 2},  {glu::TYPE_FLOAT_VEC3, false, 1},  {glu::TYPE_FLOAT_VEC4, false, 2},
6459*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_INT_VEC2, false, 0},    {glu::TYPE_INT_VEC3, false, 2},    {glu::TYPE_INT_VEC4, false, 2},
6460*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_UINT_VEC2, false, 2},   {glu::TYPE_UINT_VEC3, false, 2},   {glu::TYPE_UINT_VEC4, false, 0},
6461*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT2, true, 2},   {glu::TYPE_FLOAT_MAT2X3, true, 2}, {glu::TYPE_FLOAT_MAT2X4, true, 2},
6462*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT3X2, true, 0}, {glu::TYPE_FLOAT_MAT3, true, 2},   {glu::TYPE_FLOAT_MAT3X4, true, 2},
6463*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT4X2, true, 2}, {glu::TYPE_FLOAT_MAT4X3, true, 2}, {glu::TYPE_FLOAT_MAT4, true, 2},
6464*35238bceSAndroid Build Coastguard Worker     };
6465*35238bceSAndroid Build Coastguard Worker 
6466*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6467*35238bceSAndroid Build Coastguard Worker     {
6468*35238bceSAndroid Build Coastguard Worker         if (!allowMatrixCases && variableTypes[ndx].isMatrix)
6469*35238bceSAndroid Build Coastguard Worker             continue;
6470*35238bceSAndroid Build Coastguard Worker 
6471*35238bceSAndroid Build Coastguard Worker         if (variableTypes[ndx].level <= expandLevel)
6472*35238bceSAndroid Build Coastguard Worker         {
6473*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
6474*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6475*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
6476*35238bceSAndroid Build Coastguard Worker                 context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
6477*35238bceSAndroid Build Coastguard Worker         }
6478*35238bceSAndroid Build Coastguard Worker     }
6479*35238bceSAndroid Build Coastguard Worker }
6480*35238bceSAndroid Build Coastguard Worker 
generateProgramInputTypeBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)6481*35238bceSAndroid Build Coastguard Worker static void generateProgramInputTypeBlockContents(Context &context,
6482*35238bceSAndroid Build Coastguard Worker                                                   const ResourceDefinition::Node::SharedPtr &parentStructure,
6483*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
6484*35238bceSAndroid Build Coastguard Worker                                                   bool isGL45)
6485*35238bceSAndroid Build Coastguard Worker {
6486*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
6487*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
6488*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr input =
6489*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
6490*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN))) :
6491*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
6492*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
6493*35238bceSAndroid Build Coastguard Worker     const int interfaceBlockExpansionReducement =
6494*35238bceSAndroid Build Coastguard Worker         (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
6495*35238bceSAndroid Build Coastguard Worker 
6496*35238bceSAndroid Build Coastguard Worker     if (firstStage == glu::SHADERTYPE_VERTEX)
6497*35238bceSAndroid Build Coastguard Worker     {
6498*35238bceSAndroid Build Coastguard Worker         // Only basic types (and no booleans)
6499*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(
6500*35238bceSAndroid Build Coastguard Worker             context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
6501*35238bceSAndroid Build Coastguard Worker     }
6502*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
6503*35238bceSAndroid Build Coastguard Worker     {
6504*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr flatShading(
6505*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
6506*35238bceSAndroid Build Coastguard Worker 
6507*35238bceSAndroid Build Coastguard Worker         // Only basic types, arrays of basic types, struct of basic types (and no booleans)
6508*35238bceSAndroid Build Coastguard Worker         {
6509*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6510*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6511*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(
6512*35238bceSAndroid Build Coastguard Worker                 context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
6513*35238bceSAndroid Build Coastguard Worker         }
6514*35238bceSAndroid Build Coastguard Worker         {
6515*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(flatShading));
6516*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "array", "Array types");
6517*35238bceSAndroid Build Coastguard Worker 
6518*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6519*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(
6520*35238bceSAndroid Build Coastguard Worker                 context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
6521*35238bceSAndroid Build Coastguard Worker         }
6522*35238bceSAndroid Build Coastguard Worker         {
6523*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(flatShading));
6524*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6525*35238bceSAndroid Build Coastguard Worker 
6526*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6527*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(
6528*35238bceSAndroid Build Coastguard Worker                 context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
6529*35238bceSAndroid Build Coastguard Worker         }
6530*35238bceSAndroid Build Coastguard Worker     }
6531*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL || firstStage == glu::SHADERTYPE_GEOMETRY)
6532*35238bceSAndroid Build Coastguard Worker     {
6533*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6534*35238bceSAndroid Build Coastguard Worker 
6535*35238bceSAndroid Build Coastguard Worker         // Only basic types (and no booleans)
6536*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(
6537*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6538*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup,
6539*35238bceSAndroid Build Coastguard Worker                                                                                      true, 2);
6540*35238bceSAndroid Build Coastguard Worker     }
6541*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
6542*35238bceSAndroid Build Coastguard Worker     {
6543*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6544*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchInput(
6545*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
6546*35238bceSAndroid Build Coastguard Worker 
6547*35238bceSAndroid Build Coastguard Worker         // .var
6548*35238bceSAndroid Build Coastguard Worker         {
6549*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6550*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6551*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6552*35238bceSAndroid Build Coastguard Worker 
6553*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6554*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup,
6555*35238bceSAndroid Build Coastguard Worker                                                                                          true, 2);
6556*35238bceSAndroid Build Coastguard Worker         }
6557*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
6558*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
6559*35238bceSAndroid Build Coastguard Worker 
6560*35238bceSAndroid Build Coastguard Worker         // .patch_var
6561*35238bceSAndroid Build Coastguard Worker         {
6562*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
6563*35238bceSAndroid Build Coastguard Worker 
6564*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6565*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput,
6566*35238bceSAndroid Build Coastguard Worker                                                                                          blockGroup, true, 1);
6567*35238bceSAndroid Build Coastguard Worker         }
6568*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
6569*35238bceSAndroid Build Coastguard Worker         {
6570*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchInput));
6571*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
6572*35238bceSAndroid Build Coastguard Worker                 new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
6573*35238bceSAndroid Build Coastguard Worker 
6574*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6575*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup,
6576*35238bceSAndroid Build Coastguard Worker                                                                                          true, 1);
6577*35238bceSAndroid Build Coastguard Worker         }
6578*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
6579*35238bceSAndroid Build Coastguard Worker         {
6580*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchInput));
6581*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
6582*35238bceSAndroid Build Coastguard Worker                 new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
6583*35238bceSAndroid Build Coastguard Worker 
6584*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6585*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup,
6586*35238bceSAndroid Build Coastguard Worker                                                                                          true, 1);
6587*35238bceSAndroid Build Coastguard Worker         }
6588*35238bceSAndroid Build Coastguard Worker     }
6589*35238bceSAndroid Build Coastguard Worker     else if (firstStage == glu::SHADERTYPE_COMPUTE)
6590*35238bceSAndroid Build Coastguard Worker     {
6591*35238bceSAndroid Build Coastguard Worker         // nada
6592*35238bceSAndroid Build Coastguard Worker     }
6593*35238bceSAndroid Build Coastguard Worker     else
6594*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6595*35238bceSAndroid Build Coastguard Worker }
6596*35238bceSAndroid Build Coastguard Worker 
generateProgramOutputTypeBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,uint32_t presentShadersMask,bool isGL45)6597*35238bceSAndroid Build Coastguard Worker static void generateProgramOutputTypeBlockContents(Context &context,
6598*35238bceSAndroid Build Coastguard Worker                                                    const ResourceDefinition::Node::SharedPtr &parentStructure,
6599*35238bceSAndroid Build Coastguard Worker                                                    tcu::TestCaseGroup *targetGroup, uint32_t presentShadersMask,
6600*35238bceSAndroid Build Coastguard Worker                                                    bool isGL45)
6601*35238bceSAndroid Build Coastguard Worker {
6602*35238bceSAndroid Build Coastguard Worker     DE_UNREF(isGL45);
6603*35238bceSAndroid Build Coastguard Worker     const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
6604*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output =
6605*35238bceSAndroid Build Coastguard Worker         (inDefaultBlock) ? (ResourceDefinition::Node::SharedPtr(
6606*35238bceSAndroid Build Coastguard Worker                                new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT))) :
6607*35238bceSAndroid Build Coastguard Worker                            (parentStructure);
6608*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
6609*35238bceSAndroid Build Coastguard Worker     const int interfaceBlockExpansionReducement =
6610*35238bceSAndroid Build Coastguard Worker         (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
6611*35238bceSAndroid Build Coastguard Worker 
6612*35238bceSAndroid Build Coastguard Worker     if (lastStage == glu::SHADERTYPE_VERTEX || lastStage == glu::SHADERTYPE_GEOMETRY ||
6613*35238bceSAndroid Build Coastguard Worker         lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION || !inDefaultBlock)
6614*35238bceSAndroid Build Coastguard Worker     {
6615*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr flatShading(
6616*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6617*35238bceSAndroid Build Coastguard Worker 
6618*35238bceSAndroid Build Coastguard Worker         // Only basic types, arrays of basic types, struct of basic types (and no booleans)
6619*35238bceSAndroid Build Coastguard Worker         {
6620*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6621*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6622*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(
6623*35238bceSAndroid Build Coastguard Worker                 context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
6624*35238bceSAndroid Build Coastguard Worker         }
6625*35238bceSAndroid Build Coastguard Worker         {
6626*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(flatShading));
6627*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "array", "Array types");
6628*35238bceSAndroid Build Coastguard Worker             const int typeExpansionReducement =
6629*35238bceSAndroid Build Coastguard Worker                 (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
6630*35238bceSAndroid Build Coastguard Worker             const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
6631*35238bceSAndroid Build Coastguard Worker 
6632*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6633*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(
6634*35238bceSAndroid Build Coastguard Worker                 context, arrayElement, blockGroup, true, expansionLevel);
6635*35238bceSAndroid Build Coastguard Worker         }
6636*35238bceSAndroid Build Coastguard Worker         {
6637*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(flatShading));
6638*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6639*35238bceSAndroid Build Coastguard Worker             const int typeExpansionReducement =
6640*35238bceSAndroid Build Coastguard Worker                 (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
6641*35238bceSAndroid Build Coastguard Worker             const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
6642*35238bceSAndroid Build Coastguard Worker 
6643*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6644*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(
6645*35238bceSAndroid Build Coastguard Worker                 context, structMember, blockGroup, true, expansionLevel);
6646*35238bceSAndroid Build Coastguard Worker         }
6647*35238bceSAndroid Build Coastguard Worker     }
6648*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_FRAGMENT)
6649*35238bceSAndroid Build Coastguard Worker     {
6650*35238bceSAndroid Build Coastguard Worker         // only basic type and basic type array (and no booleans or matrices)
6651*35238bceSAndroid Build Coastguard Worker         {
6652*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6653*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6654*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup,
6655*35238bceSAndroid Build Coastguard Worker                                                                                           false, 2);
6656*35238bceSAndroid Build Coastguard Worker         }
6657*35238bceSAndroid Build Coastguard Worker         {
6658*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(output));
6659*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "array", "Array types");
6660*35238bceSAndroid Build Coastguard Worker 
6661*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6662*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement,
6663*35238bceSAndroid Build Coastguard Worker                                                                                           blockGroup, false, 2);
6664*35238bceSAndroid Build Coastguard Worker         }
6665*35238bceSAndroid Build Coastguard Worker     }
6666*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
6667*35238bceSAndroid Build Coastguard Worker     {
6668*35238bceSAndroid Build Coastguard Worker         // arrayed interface
6669*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr patchOutput(
6670*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
6671*35238bceSAndroid Build Coastguard Worker 
6672*35238bceSAndroid Build Coastguard Worker         // .var
6673*35238bceSAndroid Build Coastguard Worker         {
6674*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(
6675*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6676*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6677*35238bceSAndroid Build Coastguard Worker 
6678*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6679*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem,
6680*35238bceSAndroid Build Coastguard Worker                                                                                           blockGroup, true, 2);
6681*35238bceSAndroid Build Coastguard Worker         }
6682*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of structs
6683*35238bceSAndroid Build Coastguard Worker         // extension forbids use arrays of arrays
6684*35238bceSAndroid Build Coastguard Worker 
6685*35238bceSAndroid Build Coastguard Worker         // .patch_var
6686*35238bceSAndroid Build Coastguard Worker         {
6687*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
6688*35238bceSAndroid Build Coastguard Worker 
6689*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6690*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput,
6691*35238bceSAndroid Build Coastguard Worker                                                                                           blockGroup, true, 1);
6692*35238bceSAndroid Build Coastguard Worker         }
6693*35238bceSAndroid Build Coastguard Worker         // .patch_var_struct
6694*35238bceSAndroid Build Coastguard Worker         {
6695*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(patchOutput));
6696*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
6697*35238bceSAndroid Build Coastguard Worker                 new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
6698*35238bceSAndroid Build Coastguard Worker 
6699*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6700*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr,
6701*35238bceSAndroid Build Coastguard Worker                                                                                           blockGroup, true, 1);
6702*35238bceSAndroid Build Coastguard Worker         }
6703*35238bceSAndroid Build Coastguard Worker         // .patch_var_array
6704*35238bceSAndroid Build Coastguard Worker         {
6705*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(patchOutput));
6706*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const blockGroup =
6707*35238bceSAndroid Build Coastguard Worker                 new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
6708*35238bceSAndroid Build Coastguard Worker 
6709*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(blockGroup);
6710*35238bceSAndroid Build Coastguard Worker             generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem,
6711*35238bceSAndroid Build Coastguard Worker                                                                                           blockGroup, true, 1);
6712*35238bceSAndroid Build Coastguard Worker         }
6713*35238bceSAndroid Build Coastguard Worker     }
6714*35238bceSAndroid Build Coastguard Worker     else if (lastStage == glu::SHADERTYPE_COMPUTE)
6715*35238bceSAndroid Build Coastguard Worker     {
6716*35238bceSAndroid Build Coastguard Worker         // nada
6717*35238bceSAndroid Build Coastguard Worker     }
6718*35238bceSAndroid Build Coastguard Worker     else
6719*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
6720*35238bceSAndroid Build Coastguard Worker }
6721*35238bceSAndroid Build Coastguard Worker 
6722*35238bceSAndroid Build Coastguard Worker class ProgramInputTestGroup : public TestCaseGroup
6723*35238bceSAndroid Build Coastguard Worker {
6724*35238bceSAndroid Build Coastguard Worker public:
6725*35238bceSAndroid Build Coastguard Worker     ProgramInputTestGroup(Context &context, bool is_GL45);
6726*35238bceSAndroid Build Coastguard Worker     void init(void);
6727*35238bceSAndroid Build Coastguard Worker 
6728*35238bceSAndroid Build Coastguard Worker private:
6729*35238bceSAndroid Build Coastguard Worker     bool m_isGL45;
6730*35238bceSAndroid Build Coastguard Worker };
6731*35238bceSAndroid Build Coastguard Worker 
ProgramInputTestGroup(Context & context,bool is_GL45)6732*35238bceSAndroid Build Coastguard Worker ProgramInputTestGroup::ProgramInputTestGroup(Context &context, bool is_GL45)
6733*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "program_input", "Program input")
6734*35238bceSAndroid Build Coastguard Worker     , m_isGL45(is_GL45)
6735*35238bceSAndroid Build Coastguard Worker {
6736*35238bceSAndroid Build Coastguard Worker }
6737*35238bceSAndroid Build Coastguard Worker 
init(void)6738*35238bceSAndroid Build Coastguard Worker void ProgramInputTestGroup::init(void)
6739*35238bceSAndroid Build Coastguard Worker {
6740*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6741*35238bceSAndroid Build Coastguard Worker 
6742*35238bceSAndroid Build Coastguard Worker     // .resource_list
6743*35238bceSAndroid Build Coastguard Worker     {
6744*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6745*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6746*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, true, m_isGL45,
6747*35238bceSAndroid Build Coastguard Worker                                                    generateProgramInputResourceListBlockContents);
6748*35238bceSAndroid Build Coastguard Worker     }
6749*35238bceSAndroid Build Coastguard Worker 
6750*35238bceSAndroid Build Coastguard Worker     // .array_size
6751*35238bceSAndroid Build Coastguard Worker     {
6752*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6753*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6754*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6755*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, true, m_isGL45,
6756*35238bceSAndroid Build Coastguard Worker             generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6757*35238bceSAndroid Build Coastguard Worker     }
6758*35238bceSAndroid Build Coastguard Worker 
6759*35238bceSAndroid Build Coastguard Worker     // .location
6760*35238bceSAndroid Build Coastguard Worker     {
6761*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6762*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6763*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45,
6764*35238bceSAndroid Build Coastguard Worker                                                    generateProgramInputLocationBlockContents);
6765*35238bceSAndroid Build Coastguard Worker     }
6766*35238bceSAndroid Build Coastguard Worker 
6767*35238bceSAndroid Build Coastguard Worker     // .name_length
6768*35238bceSAndroid Build Coastguard Worker     {
6769*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6770*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6771*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6772*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, true, m_isGL45,
6773*35238bceSAndroid Build Coastguard Worker             generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6774*35238bceSAndroid Build Coastguard Worker     }
6775*35238bceSAndroid Build Coastguard Worker 
6776*35238bceSAndroid Build Coastguard Worker     // .referenced_by
6777*35238bceSAndroid Build Coastguard Worker     {
6778*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
6779*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6780*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6781*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6782*35238bceSAndroid Build Coastguard Worker     }
6783*35238bceSAndroid Build Coastguard Worker 
6784*35238bceSAndroid Build Coastguard Worker     // .type
6785*35238bceSAndroid Build Coastguard Worker     {
6786*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6787*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6788*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45,
6789*35238bceSAndroid Build Coastguard Worker                                                    generateProgramInputTypeBlockContents);
6790*35238bceSAndroid Build Coastguard Worker     }
6791*35238bceSAndroid Build Coastguard Worker 
6792*35238bceSAndroid Build Coastguard Worker     // .is_per_patch
6793*35238bceSAndroid Build Coastguard Worker     {
6794*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6795*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6796*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6797*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, true, m_isGL45,
6798*35238bceSAndroid Build Coastguard Worker             generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6799*35238bceSAndroid Build Coastguard Worker     }
6800*35238bceSAndroid Build Coastguard Worker }
6801*35238bceSAndroid Build Coastguard Worker 
6802*35238bceSAndroid Build Coastguard Worker class ProgramOutputTestGroup : public TestCaseGroup
6803*35238bceSAndroid Build Coastguard Worker {
6804*35238bceSAndroid Build Coastguard Worker public:
6805*35238bceSAndroid Build Coastguard Worker     ProgramOutputTestGroup(Context &context, bool is_GL45);
6806*35238bceSAndroid Build Coastguard Worker     void init(void);
6807*35238bceSAndroid Build Coastguard Worker 
6808*35238bceSAndroid Build Coastguard Worker private:
6809*35238bceSAndroid Build Coastguard Worker     bool m_isGL45;
6810*35238bceSAndroid Build Coastguard Worker };
6811*35238bceSAndroid Build Coastguard Worker 
ProgramOutputTestGroup(Context & context,bool is_GL45)6812*35238bceSAndroid Build Coastguard Worker ProgramOutputTestGroup::ProgramOutputTestGroup(Context &context, bool is_GL45)
6813*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "program_output", "Program output")
6814*35238bceSAndroid Build Coastguard Worker     , m_isGL45(is_GL45)
6815*35238bceSAndroid Build Coastguard Worker {
6816*35238bceSAndroid Build Coastguard Worker }
6817*35238bceSAndroid Build Coastguard Worker 
init(void)6818*35238bceSAndroid Build Coastguard Worker void ProgramOutputTestGroup::init(void)
6819*35238bceSAndroid Build Coastguard Worker {
6820*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6821*35238bceSAndroid Build Coastguard Worker 
6822*35238bceSAndroid Build Coastguard Worker     // .resource_list
6823*35238bceSAndroid Build Coastguard Worker     {
6824*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6825*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6826*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, false, m_isGL45,
6827*35238bceSAndroid Build Coastguard Worker                                                    generateProgramOutputResourceListBlockContents);
6828*35238bceSAndroid Build Coastguard Worker     }
6829*35238bceSAndroid Build Coastguard Worker 
6830*35238bceSAndroid Build Coastguard Worker     // .array_size
6831*35238bceSAndroid Build Coastguard Worker     {
6832*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6833*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6834*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6835*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, false, m_isGL45,
6836*35238bceSAndroid Build Coastguard Worker             generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6837*35238bceSAndroid Build Coastguard Worker     }
6838*35238bceSAndroid Build Coastguard Worker 
6839*35238bceSAndroid Build Coastguard Worker     // .location
6840*35238bceSAndroid Build Coastguard Worker     {
6841*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6842*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6843*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45,
6844*35238bceSAndroid Build Coastguard Worker                                                    generateProgramOutputLocationBlockContents);
6845*35238bceSAndroid Build Coastguard Worker     }
6846*35238bceSAndroid Build Coastguard Worker 
6847*35238bceSAndroid Build Coastguard Worker     // .name_length
6848*35238bceSAndroid Build Coastguard Worker     {
6849*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6850*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6851*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6852*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, false, m_isGL45,
6853*35238bceSAndroid Build Coastguard Worker             generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6854*35238bceSAndroid Build Coastguard Worker     }
6855*35238bceSAndroid Build Coastguard Worker 
6856*35238bceSAndroid Build Coastguard Worker     // .referenced_by
6857*35238bceSAndroid Build Coastguard Worker     {
6858*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
6859*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6860*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6861*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6862*35238bceSAndroid Build Coastguard Worker     }
6863*35238bceSAndroid Build Coastguard Worker 
6864*35238bceSAndroid Build Coastguard Worker     // .type
6865*35238bceSAndroid Build Coastguard Worker     {
6866*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6867*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6868*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45,
6869*35238bceSAndroid Build Coastguard Worker                                                    generateProgramOutputTypeBlockContents);
6870*35238bceSAndroid Build Coastguard Worker     }
6871*35238bceSAndroid Build Coastguard Worker 
6872*35238bceSAndroid Build Coastguard Worker     // .is_per_patch
6873*35238bceSAndroid Build Coastguard Worker     {
6874*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6875*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
6876*35238bceSAndroid Build Coastguard Worker         generateProgramInputOutputShaderCaseBlocks(
6877*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion, false, false, m_isGL45,
6878*35238bceSAndroid Build Coastguard Worker             generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6879*35238bceSAndroid Build Coastguard Worker     }
6880*35238bceSAndroid Build Coastguard Worker }
6881*35238bceSAndroid Build Coastguard Worker 
generateTransformFeedbackShaderCaseBlocks(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup *,bool))6882*35238bceSAndroid Build Coastguard Worker static void generateTransformFeedbackShaderCaseBlocks(
6883*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *targetGroup, glu::GLSLVersion glslVersion,
6884*35238bceSAndroid Build Coastguard Worker     void (*blockContentGenerator)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *, bool))
6885*35238bceSAndroid Build Coastguard Worker {
6886*35238bceSAndroid Build Coastguard Worker     static const struct
6887*35238bceSAndroid Build Coastguard Worker     {
6888*35238bceSAndroid Build Coastguard Worker         const char *name;
6889*35238bceSAndroid Build Coastguard Worker         uint32_t stageBits;
6890*35238bceSAndroid Build Coastguard Worker         uint32_t lastStageBit;
6891*35238bceSAndroid Build Coastguard Worker         bool reducedSet;
6892*35238bceSAndroid Build Coastguard Worker     } pipelines[] = {
6893*35238bceSAndroid Build Coastguard Worker         {"vertex_fragment", (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6894*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_VERTEX), false},
6895*35238bceSAndroid Build Coastguard Worker         {"vertex_tess_fragment",
6896*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) |
6897*35238bceSAndroid Build Coastguard Worker              (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6898*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), true},
6899*35238bceSAndroid Build Coastguard Worker         {"vertex_geo_fragment",
6900*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6901*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_GEOMETRY), true},
6902*35238bceSAndroid Build Coastguard Worker         {"vertex_tess_geo_fragment",
6903*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) |
6904*35238bceSAndroid Build Coastguard Worker              (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6905*35238bceSAndroid Build Coastguard Worker          (1 << glu::SHADERTYPE_GEOMETRY), true},
6906*35238bceSAndroid Build Coastguard Worker     };
6907*35238bceSAndroid Build Coastguard Worker     static const struct
6908*35238bceSAndroid Build Coastguard Worker     {
6909*35238bceSAndroid Build Coastguard Worker         const char *name;
6910*35238bceSAndroid Build Coastguard Worker         glu::ShaderType stage;
6911*35238bceSAndroid Build Coastguard Worker         bool reducedSet;
6912*35238bceSAndroid Build Coastguard Worker     } singleStageCases[] = {
6913*35238bceSAndroid Build Coastguard Worker         {"separable_vertex", glu::SHADERTYPE_VERTEX, false},
6914*35238bceSAndroid Build Coastguard Worker         {"separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true},
6915*35238bceSAndroid Build Coastguard Worker         {"separable_geometry", glu::SHADERTYPE_GEOMETRY, true},
6916*35238bceSAndroid Build Coastguard Worker     };
6917*35238bceSAndroid Build Coastguard Worker 
6918*35238bceSAndroid Build Coastguard Worker     // monolithic pipeline
6919*35238bceSAndroid Build Coastguard Worker     for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6920*35238bceSAndroid Build Coastguard Worker     {
6921*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6922*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
6923*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr shaderSet(new ResourceDefinition::ShaderSet(
6924*35238bceSAndroid Build Coastguard Worker             program, glslVersion, pipelines[pipelineNdx].stageBits, pipelines[pipelineNdx].lastStageBit));
6925*35238bceSAndroid Build Coastguard Worker 
6926*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
6927*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6928*35238bceSAndroid Build Coastguard Worker     }
6929*35238bceSAndroid Build Coastguard Worker 
6930*35238bceSAndroid Build Coastguard Worker     // separable pipeline
6931*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6932*35238bceSAndroid Build Coastguard Worker     {
6933*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6934*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program(true));
6935*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr shader(
6936*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
6937*35238bceSAndroid Build Coastguard Worker 
6938*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
6939*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6940*35238bceSAndroid Build Coastguard Worker     }
6941*35238bceSAndroid Build Coastguard Worker }
6942*35238bceSAndroid Build Coastguard Worker 
generateTransformFeedbackResourceListBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool reducedSet)6943*35238bceSAndroid Build Coastguard Worker static void generateTransformFeedbackResourceListBlockContents(
6944*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
6945*35238bceSAndroid Build Coastguard Worker     bool reducedSet)
6946*35238bceSAndroid Build Coastguard Worker {
6947*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
6948*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output(
6949*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6950*35238bceSAndroid Build Coastguard Worker 
6951*35238bceSAndroid Build Coastguard Worker     DE_UNREF(reducedSet);
6952*35238bceSAndroid Build Coastguard Worker 
6953*35238bceSAndroid Build Coastguard Worker     // .builtin_gl_position
6954*35238bceSAndroid Build Coastguard Worker     {
6955*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
6956*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6957*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6958*35238bceSAndroid Build Coastguard Worker     }
6959*35238bceSAndroid Build Coastguard Worker     // .default_block_basic_type
6960*35238bceSAndroid Build Coastguard Worker     {
6961*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(output));
6962*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
6963*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6964*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6965*35238bceSAndroid Build Coastguard Worker     }
6966*35238bceSAndroid Build Coastguard Worker     // .default_block_struct_member
6967*35238bceSAndroid Build Coastguard Worker     {
6968*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(output));
6969*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(structMbr));
6970*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
6971*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6972*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6973*35238bceSAndroid Build Coastguard Worker     }
6974*35238bceSAndroid Build Coastguard Worker     // .default_block_array
6975*35238bceSAndroid Build Coastguard Worker     {
6976*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(output));
6977*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(xfbTarget));
6978*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
6979*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6980*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6981*35238bceSAndroid Build Coastguard Worker     }
6982*35238bceSAndroid Build Coastguard Worker     // .default_block_array_element
6983*35238bceSAndroid Build Coastguard Worker     {
6984*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
6985*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6986*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
6987*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6988*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6989*35238bceSAndroid Build Coastguard Worker     }
6990*35238bceSAndroid Build Coastguard Worker }
6991*35238bceSAndroid Build Coastguard Worker 
6992*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateTransformFeedbackVariableBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool reducedSet)6993*35238bceSAndroid Build Coastguard Worker static void generateTransformFeedbackVariableBlockContents(Context &context,
6994*35238bceSAndroid Build Coastguard Worker                                                            const ResourceDefinition::Node::SharedPtr &parentStructure,
6995*35238bceSAndroid Build Coastguard Worker                                                            tcu::TestCaseGroup *targetGroup, bool reducedSet)
6996*35238bceSAndroid Build Coastguard Worker {
6997*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
6998*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output(
6999*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
7000*35238bceSAndroid Build Coastguard Worker 
7001*35238bceSAndroid Build Coastguard Worker     DE_UNREF(reducedSet);
7002*35238bceSAndroid Build Coastguard Worker 
7003*35238bceSAndroid Build Coastguard Worker     // .builtin_gl_position
7004*35238bceSAndroid Build Coastguard Worker     {
7005*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7006*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
7007*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7008*35238bceSAndroid Build Coastguard Worker             context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp),
7009*35238bceSAndroid Build Coastguard Worker             "builtin_gl_position"));
7010*35238bceSAndroid Build Coastguard Worker     }
7011*35238bceSAndroid Build Coastguard Worker     // .default_block_basic_type
7012*35238bceSAndroid Build Coastguard Worker     {
7013*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(output));
7014*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7015*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
7016*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7017*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp),
7018*35238bceSAndroid Build Coastguard Worker             "default_block_basic_type"));
7019*35238bceSAndroid Build Coastguard Worker     }
7020*35238bceSAndroid Build Coastguard Worker     // .default_block_struct_member
7021*35238bceSAndroid Build Coastguard Worker     {
7022*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMbr(new ResourceDefinition::StructMember(output));
7023*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(structMbr));
7024*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7025*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
7026*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7027*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp),
7028*35238bceSAndroid Build Coastguard Worker             "default_block_struct_member"));
7029*35238bceSAndroid Build Coastguard Worker     }
7030*35238bceSAndroid Build Coastguard Worker     // .default_block_array
7031*35238bceSAndroid Build Coastguard Worker     {
7032*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(output));
7033*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(xfbTarget));
7034*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7035*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
7036*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7037*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp),
7038*35238bceSAndroid Build Coastguard Worker             "default_block_array"));
7039*35238bceSAndroid Build Coastguard Worker     }
7040*35238bceSAndroid Build Coastguard Worker     // .default_block_array_element
7041*35238bceSAndroid Build Coastguard Worker     {
7042*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElem(new ResourceDefinition::ArrayElement(output));
7043*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
7044*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7045*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
7046*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7047*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp),
7048*35238bceSAndroid Build Coastguard Worker             "default_block_array_element"));
7049*35238bceSAndroid Build Coastguard Worker     }
7050*35238bceSAndroid Build Coastguard Worker }
7051*35238bceSAndroid Build Coastguard Worker 
generateTransformFeedbackVariableBasicTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool reducedSet)7052*35238bceSAndroid Build Coastguard Worker static void generateTransformFeedbackVariableBasicTypeCases(Context &context,
7053*35238bceSAndroid Build Coastguard Worker                                                             const ResourceDefinition::Node::SharedPtr &parentStructure,
7054*35238bceSAndroid Build Coastguard Worker                                                             tcu::TestCaseGroup *targetGroup, bool reducedSet)
7055*35238bceSAndroid Build Coastguard Worker {
7056*35238bceSAndroid Build Coastguard Worker     static const struct
7057*35238bceSAndroid Build Coastguard Worker     {
7058*35238bceSAndroid Build Coastguard Worker         glu::DataType type;
7059*35238bceSAndroid Build Coastguard Worker         bool important;
7060*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
7061*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT, true},         {glu::TYPE_INT, true},           {glu::TYPE_UINT, true},
7062*35238bceSAndroid Build Coastguard Worker 
7063*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_VEC2, false},   {glu::TYPE_FLOAT_VEC3, true},    {glu::TYPE_FLOAT_VEC4, false},
7064*35238bceSAndroid Build Coastguard Worker 
7065*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_INT_VEC2, false},     {glu::TYPE_INT_VEC3, true},      {glu::TYPE_INT_VEC4, false},
7066*35238bceSAndroid Build Coastguard Worker 
7067*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_UINT_VEC2, true},     {glu::TYPE_UINT_VEC3, false},    {glu::TYPE_UINT_VEC4, false},
7068*35238bceSAndroid Build Coastguard Worker 
7069*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT2, false},   {glu::TYPE_FLOAT_MAT2X3, false}, {glu::TYPE_FLOAT_MAT2X4, false},
7070*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT3X2, false}, {glu::TYPE_FLOAT_MAT3, false},   {glu::TYPE_FLOAT_MAT3X4, true},
7071*35238bceSAndroid Build Coastguard Worker         {glu::TYPE_FLOAT_MAT4X2, false}, {glu::TYPE_FLOAT_MAT4X3, false}, {glu::TYPE_FLOAT_MAT4, false},
7072*35238bceSAndroid Build Coastguard Worker     };
7073*35238bceSAndroid Build Coastguard Worker 
7074*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
7075*35238bceSAndroid Build Coastguard Worker     {
7076*35238bceSAndroid Build Coastguard Worker         if (variableTypes[ndx].important || !reducedSet)
7077*35238bceSAndroid Build Coastguard Worker         {
7078*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
7079*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
7080*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
7081*35238bceSAndroid Build Coastguard Worker                 context, variable,
7082*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
7083*35238bceSAndroid Build Coastguard Worker         }
7084*35238bceSAndroid Build Coastguard Worker     }
7085*35238bceSAndroid Build Coastguard Worker }
7086*35238bceSAndroid Build Coastguard Worker 
generateTransformFeedbackVariableTypeBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool reducedSet)7087*35238bceSAndroid Build Coastguard Worker static void generateTransformFeedbackVariableTypeBlockContents(
7088*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
7089*35238bceSAndroid Build Coastguard Worker     bool reducedSet)
7090*35238bceSAndroid Build Coastguard Worker {
7091*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
7092*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr output(
7093*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
7094*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr flatShading(
7095*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
7096*35238bceSAndroid Build Coastguard Worker 
7097*35238bceSAndroid Build Coastguard Worker     // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
7098*35238bceSAndroid Build Coastguard Worker     {
7099*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7100*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
7101*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
7102*35238bceSAndroid Build Coastguard Worker 
7103*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7104*35238bceSAndroid Build Coastguard Worker         blockGroup->addChild(new ResourceTestCase(
7105*35238bceSAndroid Build Coastguard Worker             context, xfbTarget,
7106*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE),
7107*35238bceSAndroid Build Coastguard Worker             "gl_position"));
7108*35238bceSAndroid Build Coastguard Worker     }
7109*35238bceSAndroid Build Coastguard Worker     {
7110*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7111*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(flatShading));
7112*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
7113*35238bceSAndroid Build Coastguard Worker 
7114*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7115*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
7116*35238bceSAndroid Build Coastguard Worker     }
7117*35238bceSAndroid Build Coastguard Worker     {
7118*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(flatShading));
7119*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7120*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(arrayElement));
7121*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "array", "Array types");
7122*35238bceSAndroid Build Coastguard Worker 
7123*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7124*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
7125*35238bceSAndroid Build Coastguard Worker     }
7126*35238bceSAndroid Build Coastguard Worker     {
7127*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7128*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(flatShading));
7129*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(xfbTarget));
7130*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
7131*35238bceSAndroid Build Coastguard Worker 
7132*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7133*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
7134*35238bceSAndroid Build Coastguard Worker     }
7135*35238bceSAndroid Build Coastguard Worker     {
7136*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(flatShading));
7137*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr xfbTarget(
7138*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::TransformFeedbackTarget(structMember));
7139*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
7140*35238bceSAndroid Build Coastguard Worker 
7141*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7142*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
7143*35238bceSAndroid Build Coastguard Worker     }
7144*35238bceSAndroid Build Coastguard Worker }
7145*35238bceSAndroid Build Coastguard Worker 
7146*35238bceSAndroid Build Coastguard Worker class TransformFeedbackVaryingTestGroup : public TestCaseGroup
7147*35238bceSAndroid Build Coastguard Worker {
7148*35238bceSAndroid Build Coastguard Worker public:
7149*35238bceSAndroid Build Coastguard Worker     TransformFeedbackVaryingTestGroup(Context &context);
7150*35238bceSAndroid Build Coastguard Worker     void init(void);
7151*35238bceSAndroid Build Coastguard Worker };
7152*35238bceSAndroid Build Coastguard Worker 
TransformFeedbackVaryingTestGroup(Context & context)7153*35238bceSAndroid Build Coastguard Worker TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup(Context &context)
7154*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
7155*35238bceSAndroid Build Coastguard Worker {
7156*35238bceSAndroid Build Coastguard Worker }
7157*35238bceSAndroid Build Coastguard Worker 
init(void)7158*35238bceSAndroid Build Coastguard Worker void TransformFeedbackVaryingTestGroup::init(void)
7159*35238bceSAndroid Build Coastguard Worker {
7160*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7161*35238bceSAndroid Build Coastguard Worker 
7162*35238bceSAndroid Build Coastguard Worker     // .resource_list
7163*35238bceSAndroid Build Coastguard Worker     {
7164*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
7165*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7166*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion,
7167*35238bceSAndroid Build Coastguard Worker                                                   generateTransformFeedbackResourceListBlockContents);
7168*35238bceSAndroid Build Coastguard Worker     }
7169*35238bceSAndroid Build Coastguard Worker 
7170*35238bceSAndroid Build Coastguard Worker     // .array_size
7171*35238bceSAndroid Build Coastguard Worker     {
7172*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
7173*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7174*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackShaderCaseBlocks(
7175*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion,
7176*35238bceSAndroid Build Coastguard Worker             generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
7177*35238bceSAndroid Build Coastguard Worker     }
7178*35238bceSAndroid Build Coastguard Worker 
7179*35238bceSAndroid Build Coastguard Worker     // .name_length
7180*35238bceSAndroid Build Coastguard Worker     {
7181*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
7182*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7183*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackShaderCaseBlocks(
7184*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion,
7185*35238bceSAndroid Build Coastguard Worker             generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
7186*35238bceSAndroid Build Coastguard Worker     }
7187*35238bceSAndroid Build Coastguard Worker 
7188*35238bceSAndroid Build Coastguard Worker     // .type
7189*35238bceSAndroid Build Coastguard Worker     {
7190*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "type", "Type");
7191*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7192*35238bceSAndroid Build Coastguard Worker         generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion,
7193*35238bceSAndroid Build Coastguard Worker                                                   generateTransformFeedbackVariableTypeBlockContents);
7194*35238bceSAndroid Build Coastguard Worker     }
7195*35238bceSAndroid Build Coastguard Worker }
7196*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableBufferCaseBlocks(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup *))7197*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableBufferCaseBlocks(
7198*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *targetGroup, glu::GLSLVersion glslVersion,
7199*35238bceSAndroid Build Coastguard Worker     void (*blockContentGenerator)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *))
7200*35238bceSAndroid Build Coastguard Worker {
7201*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
7202*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
7203*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
7204*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
7205*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr bufferStorage(
7206*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7207*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr binding(
7208*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
7209*35238bceSAndroid Build Coastguard Worker 
7210*35238bceSAndroid Build Coastguard Worker     // .named_block
7211*35238bceSAndroid Build Coastguard Worker     {
7212*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, true));
7213*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
7214*35238bceSAndroid Build Coastguard Worker 
7215*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7216*35238bceSAndroid Build Coastguard Worker 
7217*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, buffer, blockGroup);
7218*35238bceSAndroid Build Coastguard Worker     }
7219*35238bceSAndroid Build Coastguard Worker 
7220*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
7221*35238bceSAndroid Build Coastguard Worker     {
7222*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, false));
7223*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
7224*35238bceSAndroid Build Coastguard Worker 
7225*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7226*35238bceSAndroid Build Coastguard Worker 
7227*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, buffer, blockGroup);
7228*35238bceSAndroid Build Coastguard Worker     }
7229*35238bceSAndroid Build Coastguard Worker 
7230*35238bceSAndroid Build Coastguard Worker     // .block_array
7231*35238bceSAndroid Build Coastguard Worker     {
7232*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding));
7233*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(arrayElement, true));
7234*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
7235*35238bceSAndroid Build Coastguard Worker 
7236*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7237*35238bceSAndroid Build Coastguard Worker 
7238*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, buffer, blockGroup);
7239*35238bceSAndroid Build Coastguard Worker     }
7240*35238bceSAndroid Build Coastguard Worker }
7241*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableResourceListBlockContentsProxy(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)7242*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableResourceListBlockContentsProxy(
7243*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *const targetGroup)
7244*35238bceSAndroid Build Coastguard Worker {
7245*35238bceSAndroid Build Coastguard Worker     generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup,
7246*35238bceSAndroid Build Coastguard Worker                                                       PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
7247*35238bceSAndroid Build Coastguard Worker }
7248*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableArraySizeSubCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup,ProgramResourcePropFlags targetProp,bool sizedArray,bool extendedCases)7249*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableArraySizeSubCases(Context &context,
7250*35238bceSAndroid Build Coastguard Worker                                                     const ResourceDefinition::Node::SharedPtr &parentStructure,
7251*35238bceSAndroid Build Coastguard Worker                                                     tcu::TestCaseGroup *const targetGroup,
7252*35238bceSAndroid Build Coastguard Worker                                                     ProgramResourcePropFlags targetProp, bool sizedArray,
7253*35238bceSAndroid Build Coastguard Worker                                                     bool extendedCases)
7254*35238bceSAndroid Build Coastguard Worker {
7255*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
7256*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *aggregateGroup;
7257*35238bceSAndroid Build Coastguard Worker 
7258*35238bceSAndroid Build Coastguard Worker     // .types
7259*35238bceSAndroid Build Coastguard Worker     if (extendedCases)
7260*35238bceSAndroid Build Coastguard Worker     {
7261*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
7262*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7263*35238bceSAndroid Build Coastguard Worker 
7264*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
7265*35238bceSAndroid Build Coastguard Worker     }
7266*35238bceSAndroid Build Coastguard Worker 
7267*35238bceSAndroid Build Coastguard Worker     // .aggregates
7268*35238bceSAndroid Build Coastguard Worker     if (extendedCases)
7269*35238bceSAndroid Build Coastguard Worker     {
7270*35238bceSAndroid Build Coastguard Worker         aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
7271*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(aggregateGroup);
7272*35238bceSAndroid Build Coastguard Worker     }
7273*35238bceSAndroid Build Coastguard Worker     else
7274*35238bceSAndroid Build Coastguard Worker         aggregateGroup = targetGroup;
7275*35238bceSAndroid Build Coastguard Worker 
7276*35238bceSAndroid Build Coastguard Worker     // .float_*
7277*35238bceSAndroid Build Coastguard Worker     generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface,
7278*35238bceSAndroid Build Coastguard Worker                                                       glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1),
7279*35238bceSAndroid Build Coastguard Worker                                                       !extendedCases);
7280*35238bceSAndroid Build Coastguard Worker 
7281*35238bceSAndroid Build Coastguard Worker     // .bool_*
7282*35238bceSAndroid Build Coastguard Worker     generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface,
7283*35238bceSAndroid Build Coastguard Worker                                                       glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0),
7284*35238bceSAndroid Build Coastguard Worker                                                       !extendedCases);
7285*35238bceSAndroid Build Coastguard Worker 
7286*35238bceSAndroid Build Coastguard Worker     // .bvec3_*
7287*35238bceSAndroid Build Coastguard Worker     generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface,
7288*35238bceSAndroid Build Coastguard Worker                                                       glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1),
7289*35238bceSAndroid Build Coastguard Worker                                                       !extendedCases);
7290*35238bceSAndroid Build Coastguard Worker 
7291*35238bceSAndroid Build Coastguard Worker     // .vec4_*
7292*35238bceSAndroid Build Coastguard Worker     generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface,
7293*35238bceSAndroid Build Coastguard Worker                                                       glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1),
7294*35238bceSAndroid Build Coastguard Worker                                                       !extendedCases);
7295*35238bceSAndroid Build Coastguard Worker 
7296*35238bceSAndroid Build Coastguard Worker     // .ivec2_*
7297*35238bceSAndroid Build Coastguard Worker     generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface,
7298*35238bceSAndroid Build Coastguard Worker                                                       glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1),
7299*35238bceSAndroid Build Coastguard Worker                                                       !extendedCases);
7300*35238bceSAndroid Build Coastguard Worker }
7301*35238bceSAndroid Build Coastguard Worker 
7302*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateBufferVariableArrayCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * const targetGroup)7303*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableArrayCases(Context &context,
7304*35238bceSAndroid Build Coastguard Worker                                              const ResourceDefinition::Node::SharedPtr &parentStructure,
7305*35238bceSAndroid Build Coastguard Worker                                              tcu::TestCaseGroup *const targetGroup)
7306*35238bceSAndroid Build Coastguard Worker {
7307*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
7308*35238bceSAndroid Build Coastguard Worker     const bool namedNonArrayBlock =
7309*35238bceSAndroid Build Coastguard Worker         static_cast<const ResourceDefinition::InterfaceBlock *>(parentStructure.get())->m_named &&
7310*35238bceSAndroid Build Coastguard Worker         parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
7311*35238bceSAndroid Build Coastguard Worker 
7312*35238bceSAndroid Build Coastguard Worker     // .non_array
7313*35238bceSAndroid Build Coastguard Worker     if (namedNonArrayBlock)
7314*35238bceSAndroid Build Coastguard Worker     {
7315*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
7316*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7317*35238bceSAndroid Build Coastguard Worker 
7318*35238bceSAndroid Build Coastguard Worker         generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
7319*35238bceSAndroid Build Coastguard Worker     }
7320*35238bceSAndroid Build Coastguard Worker 
7321*35238bceSAndroid Build Coastguard Worker     // .sized
7322*35238bceSAndroid Build Coastguard Worker     {
7323*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr sized(new ResourceDefinition::ArrayElement(parentStructure));
7324*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
7325*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7326*35238bceSAndroid Build Coastguard Worker 
7327*35238bceSAndroid Build Coastguard Worker         generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
7328*35238bceSAndroid Build Coastguard Worker     }
7329*35238bceSAndroid Build Coastguard Worker 
7330*35238bceSAndroid Build Coastguard Worker     // .unsized
7331*35238bceSAndroid Build Coastguard Worker     {
7332*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unsized(
7333*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
7334*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
7335*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7336*35238bceSAndroid Build Coastguard Worker 
7337*35238bceSAndroid Build Coastguard Worker         generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
7338*35238bceSAndroid Build Coastguard Worker     }
7339*35238bceSAndroid Build Coastguard Worker }
7340*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableBlockIndexCases(Context & context,glu::GLSLVersion glslVersion,tcu::TestCaseGroup * const targetGroup)7341*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableBlockIndexCases(Context &context, glu::GLSLVersion glslVersion,
7342*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *const targetGroup)
7343*35238bceSAndroid Build Coastguard Worker {
7344*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
7345*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
7346*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
7347*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
7348*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr bufferStorage(
7349*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7350*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr binding(
7351*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
7352*35238bceSAndroid Build Coastguard Worker 
7353*35238bceSAndroid Build Coastguard Worker     // .named_block
7354*35238bceSAndroid Build Coastguard Worker     {
7355*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, true));
7356*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7357*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
7358*35238bceSAndroid Build Coastguard Worker 
7359*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7360*35238bceSAndroid Build Coastguard Worker             context, variable,
7361*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX),
7362*35238bceSAndroid Build Coastguard Worker             "named_block"));
7363*35238bceSAndroid Build Coastguard Worker     }
7364*35238bceSAndroid Build Coastguard Worker 
7365*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
7366*35238bceSAndroid Build Coastguard Worker     {
7367*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(binding, false));
7368*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7369*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
7370*35238bceSAndroid Build Coastguard Worker 
7371*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7372*35238bceSAndroid Build Coastguard Worker             context, variable,
7373*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX),
7374*35238bceSAndroid Build Coastguard Worker             "unnamed_block"));
7375*35238bceSAndroid Build Coastguard Worker     }
7376*35238bceSAndroid Build Coastguard Worker 
7377*35238bceSAndroid Build Coastguard Worker     // .block_array
7378*35238bceSAndroid Build Coastguard Worker     {
7379*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(binding));
7380*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(arrayElement, true));
7381*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7382*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
7383*35238bceSAndroid Build Coastguard Worker 
7384*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7385*35238bceSAndroid Build Coastguard Worker             context, variable,
7386*35238bceSAndroid Build Coastguard Worker             ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX),
7387*35238bceSAndroid Build Coastguard Worker             "block_array"));
7388*35238bceSAndroid Build Coastguard Worker     }
7389*35238bceSAndroid Build Coastguard Worker }
7390*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableMatrixCaseBlocks(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion,void (* blockContentGenerator)(Context &,const ResourceDefinition::Node::SharedPtr &,tcu::TestCaseGroup *,bool))7391*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableMatrixCaseBlocks(
7392*35238bceSAndroid Build Coastguard Worker     Context &context, tcu::TestCaseGroup *const targetGroup, glu::GLSLVersion glslVersion,
7393*35238bceSAndroid Build Coastguard Worker     void (*blockContentGenerator)(Context &, const ResourceDefinition::Node::SharedPtr &, tcu::TestCaseGroup *, bool))
7394*35238bceSAndroid Build Coastguard Worker {
7395*35238bceSAndroid Build Coastguard Worker     static const struct
7396*35238bceSAndroid Build Coastguard Worker     {
7397*35238bceSAndroid Build Coastguard Worker         const char *name;
7398*35238bceSAndroid Build Coastguard Worker         const char *description;
7399*35238bceSAndroid Build Coastguard Worker         bool namedBlock;
7400*35238bceSAndroid Build Coastguard Worker         bool extendedBasicTypeCases;
7401*35238bceSAndroid Build Coastguard Worker         glu::MatrixOrder order;
7402*35238bceSAndroid Build Coastguard Worker     } children[] = {
7403*35238bceSAndroid Build Coastguard Worker         {"named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST},
7404*35238bceSAndroid Build Coastguard Worker         {"named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR},
7405*35238bceSAndroid Build Coastguard Worker         {"named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR},
7406*35238bceSAndroid Build Coastguard Worker         {"unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST},
7407*35238bceSAndroid Build Coastguard Worker         {"unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR},
7408*35238bceSAndroid Build Coastguard Worker         {"unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR},
7409*35238bceSAndroid Build Coastguard Worker     };
7410*35238bceSAndroid Build Coastguard Worker 
7411*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
7412*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
7413*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
7414*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
7415*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr buffer(
7416*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7417*35238bceSAndroid Build Coastguard Worker 
7418*35238bceSAndroid Build Coastguard Worker     for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
7419*35238bceSAndroid Build Coastguard Worker     {
7420*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::Node::SharedPtr parentStructure = buffer;
7421*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
7422*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
7423*35238bceSAndroid Build Coastguard Worker 
7424*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7425*35238bceSAndroid Build Coastguard Worker 
7426*35238bceSAndroid Build Coastguard Worker         if (children[childNdx].order != glu::MATRIXORDER_LAST)
7427*35238bceSAndroid Build Coastguard Worker         {
7428*35238bceSAndroid Build Coastguard Worker             glu::Layout layout;
7429*35238bceSAndroid Build Coastguard Worker             layout.matrixOrder = children[childNdx].order;
7430*35238bceSAndroid Build Coastguard Worker             parentStructure =
7431*35238bceSAndroid Build Coastguard Worker                 ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
7432*35238bceSAndroid Build Coastguard Worker         }
7433*35238bceSAndroid Build Coastguard Worker 
7434*35238bceSAndroid Build Coastguard Worker         parentStructure = ResourceDefinition::Node::SharedPtr(
7435*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
7436*35238bceSAndroid Build Coastguard Worker 
7437*35238bceSAndroid Build Coastguard Worker         blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
7438*35238bceSAndroid Build Coastguard Worker     }
7439*35238bceSAndroid Build Coastguard Worker }
7440*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableMatrixVariableBasicTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramResourcePropFlags targetProp)7441*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableMatrixVariableBasicTypeCases(
7442*35238bceSAndroid Build Coastguard Worker     Context &context, const ResourceDefinition::Node::SharedPtr &parentStructure, tcu::TestCaseGroup *targetGroup,
7443*35238bceSAndroid Build Coastguard Worker     ProgramResourcePropFlags targetProp)
7444*35238bceSAndroid Build Coastguard Worker {
7445*35238bceSAndroid Build Coastguard Worker     // all matrix types and some non-matrix
7446*35238bceSAndroid Build Coastguard Worker 
7447*35238bceSAndroid Build Coastguard Worker     static const glu::DataType variableTypes[] = {
7448*35238bceSAndroid Build Coastguard Worker         glu::TYPE_FLOAT,        glu::TYPE_INT_VEC3,     glu::TYPE_FLOAT_MAT2, glu::TYPE_FLOAT_MAT2X3,
7449*35238bceSAndroid Build Coastguard Worker         glu::TYPE_FLOAT_MAT2X4, glu::TYPE_FLOAT_MAT3X2, glu::TYPE_FLOAT_MAT3, glu::TYPE_FLOAT_MAT3X4,
7450*35238bceSAndroid Build Coastguard Worker         glu::TYPE_FLOAT_MAT4X2, glu::TYPE_FLOAT_MAT4X3, glu::TYPE_FLOAT_MAT4,
7451*35238bceSAndroid Build Coastguard Worker     };
7452*35238bceSAndroid Build Coastguard Worker 
7453*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
7454*35238bceSAndroid Build Coastguard Worker     {
7455*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7456*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
7457*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7458*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
7459*35238bceSAndroid Build Coastguard Worker     }
7460*35238bceSAndroid Build Coastguard Worker }
7461*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableMatrixVariableCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,ProgramResourcePropFlags targetProp)7462*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableMatrixVariableCases(Context &context,
7463*35238bceSAndroid Build Coastguard Worker                                                       const ResourceDefinition::Node::SharedPtr &parentStructure,
7464*35238bceSAndroid Build Coastguard Worker                                                       tcu::TestCaseGroup *targetGroup,
7465*35238bceSAndroid Build Coastguard Worker                                                       ProgramResourcePropFlags targetProp)
7466*35238bceSAndroid Build Coastguard Worker {
7467*35238bceSAndroid Build Coastguard Worker     // Basic aggregates
7468*35238bceSAndroid Build Coastguard Worker     generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup,
7469*35238bceSAndroid Build Coastguard Worker                                                    PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2,
7470*35238bceSAndroid Build Coastguard Worker                                                    "", 2);
7471*35238bceSAndroid Build Coastguard Worker 
7472*35238bceSAndroid Build Coastguard Worker     // Unsized array
7473*35238bceSAndroid Build Coastguard Worker     {
7474*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unsized(
7475*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
7476*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr variable(
7477*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
7478*35238bceSAndroid Build Coastguard Worker 
7479*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(new ResourceTestCase(
7480*35238bceSAndroid Build Coastguard Worker             context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp),
7481*35238bceSAndroid Build Coastguard Worker             "var_unsized_array"));
7482*35238bceSAndroid Build Coastguard Worker     }
7483*35238bceSAndroid Build Coastguard Worker }
7484*35238bceSAndroid Build Coastguard Worker 
7485*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateBufferVariableMatrixCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,bool extendedTypeCases)7486*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableMatrixCases(Context &context,
7487*35238bceSAndroid Build Coastguard Worker                                               const ResourceDefinition::Node::SharedPtr &parentStructure,
7488*35238bceSAndroid Build Coastguard Worker                                               tcu::TestCaseGroup *targetGroup, bool extendedTypeCases)
7489*35238bceSAndroid Build Coastguard Worker {
7490*35238bceSAndroid Build Coastguard Worker     // .types
7491*35238bceSAndroid Build Coastguard Worker     if (extendedTypeCases)
7492*35238bceSAndroid Build Coastguard Worker     {
7493*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "types", "Types");
7494*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7495*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
7496*35238bceSAndroid Build Coastguard Worker     }
7497*35238bceSAndroid Build Coastguard Worker 
7498*35238bceSAndroid Build Coastguard Worker     // .no_qualifier
7499*35238bceSAndroid Build Coastguard Worker     {
7500*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
7501*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7502*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
7503*35238bceSAndroid Build Coastguard Worker     }
7504*35238bceSAndroid Build Coastguard Worker 
7505*35238bceSAndroid Build Coastguard Worker     // .column_major
7506*35238bceSAndroid Build Coastguard Worker     {
7507*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(
7508*35238bceSAndroid Build Coastguard Worker             parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
7509*35238bceSAndroid Build Coastguard Worker 
7510*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
7511*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7512*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
7513*35238bceSAndroid Build Coastguard Worker     }
7514*35238bceSAndroid Build Coastguard Worker 
7515*35238bceSAndroid Build Coastguard Worker     // .row_major
7516*35238bceSAndroid Build Coastguard Worker     {
7517*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(
7518*35238bceSAndroid Build Coastguard Worker             parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
7519*35238bceSAndroid Build Coastguard Worker 
7520*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
7521*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7522*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
7523*35238bceSAndroid Build Coastguard Worker     }
7524*35238bceSAndroid Build Coastguard Worker }
7525*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableNameLengthCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup)7526*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableNameLengthCases(Context &context,
7527*35238bceSAndroid Build Coastguard Worker                                                   const ResourceDefinition::Node::SharedPtr &parentStructure,
7528*35238bceSAndroid Build Coastguard Worker                                                   tcu::TestCaseGroup *targetGroup)
7529*35238bceSAndroid Build Coastguard Worker {
7530*35238bceSAndroid Build Coastguard Worker     // .sized
7531*35238bceSAndroid Build Coastguard Worker     {
7532*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
7533*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7534*35238bceSAndroid Build Coastguard Worker 
7535*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup,
7536*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMINTERFACE_BUFFER_VARIABLE,
7537*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
7538*35238bceSAndroid Build Coastguard Worker     }
7539*35238bceSAndroid Build Coastguard Worker 
7540*35238bceSAndroid Build Coastguard Worker     // .unsized
7541*35238bceSAndroid Build Coastguard Worker     {
7542*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unsized(
7543*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
7544*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
7545*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7546*35238bceSAndroid Build Coastguard Worker 
7547*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE,
7548*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
7549*35238bceSAndroid Build Coastguard Worker     }
7550*35238bceSAndroid Build Coastguard Worker }
7551*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableOffsetCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup)7552*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableOffsetCases(Context &context,
7553*35238bceSAndroid Build Coastguard Worker                                               const ResourceDefinition::Node::SharedPtr &parentStructure,
7554*35238bceSAndroid Build Coastguard Worker                                               tcu::TestCaseGroup *targetGroup)
7555*35238bceSAndroid Build Coastguard Worker {
7556*35238bceSAndroid Build Coastguard Worker     // .sized
7557*35238bceSAndroid Build Coastguard Worker     {
7558*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
7559*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7560*35238bceSAndroid Build Coastguard Worker 
7561*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup,
7562*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET,
7563*35238bceSAndroid Build Coastguard Worker                                                        glu::TYPE_FLOAT, "", 3);
7564*35238bceSAndroid Build Coastguard Worker     }
7565*35238bceSAndroid Build Coastguard Worker 
7566*35238bceSAndroid Build Coastguard Worker     // .unsized
7567*35238bceSAndroid Build Coastguard Worker     {
7568*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unsized(
7569*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
7570*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
7571*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7572*35238bceSAndroid Build Coastguard Worker 
7573*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE,
7574*35238bceSAndroid Build Coastguard Worker                                                        PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
7575*35238bceSAndroid Build Coastguard Worker     }
7576*35238bceSAndroid Build Coastguard Worker }
7577*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableReferencedByBlockContents(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,int expandLevel)7578*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableReferencedByBlockContents(Context &context,
7579*35238bceSAndroid Build Coastguard Worker                                                             const ResourceDefinition::Node::SharedPtr &parentStructure,
7580*35238bceSAndroid Build Coastguard Worker                                                             tcu::TestCaseGroup *targetGroup, int expandLevel)
7581*35238bceSAndroid Build Coastguard Worker {
7582*35238bceSAndroid Build Coastguard Worker     DE_UNREF(expandLevel);
7583*35238bceSAndroid Build Coastguard Worker 
7584*35238bceSAndroid Build Coastguard Worker     const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_BUFFER_VARIABLE,
7585*35238bceSAndroid Build Coastguard Worker                                                      PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
7586*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(parentStructure));
7587*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr storage(
7588*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7589*35238bceSAndroid Build Coastguard Worker     const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
7590*35238bceSAndroid Build Coastguard Worker 
7591*35238bceSAndroid Build Coastguard Worker     // .named_block
7592*35238bceSAndroid Build Coastguard Worker     {
7593*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(storage, true));
7594*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
7595*35238bceSAndroid Build Coastguard Worker 
7596*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7597*35238bceSAndroid Build Coastguard Worker 
7598*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
7599*35238bceSAndroid Build Coastguard Worker     }
7600*35238bceSAndroid Build Coastguard Worker 
7601*35238bceSAndroid Build Coastguard Worker     // .unnamed_block
7602*35238bceSAndroid Build Coastguard Worker     {
7603*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(storage, false));
7604*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
7605*35238bceSAndroid Build Coastguard Worker 
7606*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7607*35238bceSAndroid Build Coastguard Worker 
7608*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
7609*35238bceSAndroid Build Coastguard Worker     }
7610*35238bceSAndroid Build Coastguard Worker 
7611*35238bceSAndroid Build Coastguard Worker     // .block_array
7612*35238bceSAndroid Build Coastguard Worker     {
7613*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(storage));
7614*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr buffer(new ResourceDefinition::InterfaceBlock(arrayElement, true));
7615*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
7616*35238bceSAndroid Build Coastguard Worker 
7617*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7618*35238bceSAndroid Build Coastguard Worker 
7619*35238bceSAndroid Build Coastguard Worker         generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
7620*35238bceSAndroid Build Coastguard Worker     }
7621*35238bceSAndroid Build Coastguard Worker }
7622*35238bceSAndroid Build Coastguard Worker 
7623*35238bceSAndroid Build Coastguard Worker template <ProgramResourcePropFlags TargetProp>
generateBufferVariableTopLevelCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup)7624*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableTopLevelCases(Context &context,
7625*35238bceSAndroid Build Coastguard Worker                                                 const ResourceDefinition::Node::SharedPtr &parentStructure,
7626*35238bceSAndroid Build Coastguard Worker                                                 tcu::TestCaseGroup *targetGroup)
7627*35238bceSAndroid Build Coastguard Worker {
7628*35238bceSAndroid Build Coastguard Worker     // basic and aggregate types
7629*35238bceSAndroid Build Coastguard Worker     generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup,
7630*35238bceSAndroid Build Coastguard Worker                                                    PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4,
7631*35238bceSAndroid Build Coastguard Worker                                                    "", 3);
7632*35238bceSAndroid Build Coastguard Worker 
7633*35238bceSAndroid Build Coastguard Worker     // basic and aggregate types in an unsized array
7634*35238bceSAndroid Build Coastguard Worker     {
7635*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr unsized(
7636*35238bceSAndroid Build Coastguard Worker             new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
7637*35238bceSAndroid Build Coastguard Worker 
7638*35238bceSAndroid Build Coastguard Worker         generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE,
7639*35238bceSAndroid Build Coastguard Worker                                                        TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
7640*35238bceSAndroid Build Coastguard Worker     }
7641*35238bceSAndroid Build Coastguard Worker }
7642*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableTypeBasicTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,int expandLevel)7643*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableTypeBasicTypeCases(Context &context,
7644*35238bceSAndroid Build Coastguard Worker                                                      const ResourceDefinition::Node::SharedPtr &parentStructure,
7645*35238bceSAndroid Build Coastguard Worker                                                      tcu::TestCaseGroup *targetGroup, int expandLevel)
7646*35238bceSAndroid Build Coastguard Worker {
7647*35238bceSAndroid Build Coastguard Worker     static const struct
7648*35238bceSAndroid Build Coastguard Worker     {
7649*35238bceSAndroid Build Coastguard Worker         int level;
7650*35238bceSAndroid Build Coastguard Worker         glu::DataType dataType;
7651*35238bceSAndroid Build Coastguard Worker     } variableTypes[] = {
7652*35238bceSAndroid Build Coastguard Worker         {0, glu::TYPE_FLOAT},        {1, glu::TYPE_INT},          {1, glu::TYPE_UINT},
7653*35238bceSAndroid Build Coastguard Worker         {1, glu::TYPE_BOOL},
7654*35238bceSAndroid Build Coastguard Worker 
7655*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_FLOAT_VEC2},   {1, glu::TYPE_FLOAT_VEC3},   {1, glu::TYPE_FLOAT_VEC4},
7656*35238bceSAndroid Build Coastguard Worker 
7657*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_INT_VEC2},     {2, glu::TYPE_INT_VEC3},     {3, glu::TYPE_INT_VEC4},
7658*35238bceSAndroid Build Coastguard Worker 
7659*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_UINT_VEC2},    {2, glu::TYPE_UINT_VEC3},    {3, glu::TYPE_UINT_VEC4},
7660*35238bceSAndroid Build Coastguard Worker 
7661*35238bceSAndroid Build Coastguard Worker         {3, glu::TYPE_BOOL_VEC2},    {2, glu::TYPE_BOOL_VEC3},    {3, glu::TYPE_BOOL_VEC4},
7662*35238bceSAndroid Build Coastguard Worker 
7663*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT2},   {3, glu::TYPE_FLOAT_MAT2X3}, {3, glu::TYPE_FLOAT_MAT2X4},
7664*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT3X2}, {2, glu::TYPE_FLOAT_MAT3},   {3, glu::TYPE_FLOAT_MAT3X4},
7665*35238bceSAndroid Build Coastguard Worker         {2, glu::TYPE_FLOAT_MAT4X2}, {3, glu::TYPE_FLOAT_MAT4X3}, {2, glu::TYPE_FLOAT_MAT4},
7666*35238bceSAndroid Build Coastguard Worker     };
7667*35238bceSAndroid Build Coastguard Worker 
7668*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
7669*35238bceSAndroid Build Coastguard Worker     {
7670*35238bceSAndroid Build Coastguard Worker         if (variableTypes[ndx].level <= expandLevel)
7671*35238bceSAndroid Build Coastguard Worker         {
7672*35238bceSAndroid Build Coastguard Worker             const ResourceDefinition::Node::SharedPtr variable(
7673*35238bceSAndroid Build Coastguard Worker                 new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
7674*35238bceSAndroid Build Coastguard Worker             targetGroup->addChild(new ResourceTestCase(
7675*35238bceSAndroid Build Coastguard Worker                 context, variable,
7676*35238bceSAndroid Build Coastguard Worker                 ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
7677*35238bceSAndroid Build Coastguard Worker         }
7678*35238bceSAndroid Build Coastguard Worker     }
7679*35238bceSAndroid Build Coastguard Worker }
7680*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableTypeCases(Context & context,const ResourceDefinition::Node::SharedPtr & parentStructure,tcu::TestCaseGroup * targetGroup,int depth=3)7681*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableTypeCases(Context &context,
7682*35238bceSAndroid Build Coastguard Worker                                             const ResourceDefinition::Node::SharedPtr &parentStructure,
7683*35238bceSAndroid Build Coastguard Worker                                             tcu::TestCaseGroup *targetGroup, int depth = 3)
7684*35238bceSAndroid Build Coastguard Worker {
7685*35238bceSAndroid Build Coastguard Worker     // .basic_type
7686*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
7687*35238bceSAndroid Build Coastguard Worker     {
7688*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
7689*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7690*35238bceSAndroid Build Coastguard Worker         generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
7691*35238bceSAndroid Build Coastguard Worker     }
7692*35238bceSAndroid Build Coastguard Worker     else
7693*35238bceSAndroid Build Coastguard Worker     {
7694*35238bceSAndroid Build Coastguard Worker         // flatten bottom-level
7695*35238bceSAndroid Build Coastguard Worker         generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
7696*35238bceSAndroid Build Coastguard Worker     }
7697*35238bceSAndroid Build Coastguard Worker 
7698*35238bceSAndroid Build Coastguard Worker     // .array
7699*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
7700*35238bceSAndroid Build Coastguard Worker     {
7701*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
7702*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "array", "Arrays");
7703*35238bceSAndroid Build Coastguard Worker 
7704*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7705*35238bceSAndroid Build Coastguard Worker         generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth - 1);
7706*35238bceSAndroid Build Coastguard Worker     }
7707*35238bceSAndroid Build Coastguard Worker 
7708*35238bceSAndroid Build Coastguard Worker     // .struct
7709*35238bceSAndroid Build Coastguard Worker     if (depth > 0)
7710*35238bceSAndroid Build Coastguard Worker     {
7711*35238bceSAndroid Build Coastguard Worker         const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
7712*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(context, "struct", "Structs");
7713*35238bceSAndroid Build Coastguard Worker 
7714*35238bceSAndroid Build Coastguard Worker         targetGroup->addChild(blockGroup);
7715*35238bceSAndroid Build Coastguard Worker         generateBufferVariableTypeCases(context, structMember, blockGroup, depth - 1);
7716*35238bceSAndroid Build Coastguard Worker     }
7717*35238bceSAndroid Build Coastguard Worker }
7718*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableTypeBlock(Context & context,tcu::TestCaseGroup * targetGroup,glu::GLSLVersion glslVersion)7719*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableTypeBlock(Context &context, tcu::TestCaseGroup *targetGroup,
7720*35238bceSAndroid Build Coastguard Worker                                             glu::GLSLVersion glslVersion)
7721*35238bceSAndroid Build Coastguard Worker {
7722*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
7723*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader(
7724*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
7725*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
7726*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr buffer(
7727*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7728*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(buffer, true));
7729*35238bceSAndroid Build Coastguard Worker 
7730*35238bceSAndroid Build Coastguard Worker     generateBufferVariableTypeCases(context, block, targetGroup);
7731*35238bceSAndroid Build Coastguard Worker }
7732*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableRandomCase(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion,int index,bool onlyExtensionStages)7733*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableRandomCase(Context &context, tcu::TestCaseGroup *const targetGroup,
7734*35238bceSAndroid Build Coastguard Worker                                              glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
7735*35238bceSAndroid Build Coastguard Worker {
7736*35238bceSAndroid Build Coastguard Worker     de::Random rnd(index * 0x12345);
7737*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
7738*35238bceSAndroid Build Coastguard Worker     const glu::DataType type                         = generateRandomDataType(rnd, true);
7739*35238bceSAndroid Build Coastguard Worker     const glu::Layout layout                         = generateRandomVariableLayout(rnd, type, true);
7740*35238bceSAndroid Build Coastguard Worker     const bool namedBlock                            = rnd.getBool();
7741*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr defaultBlock(new ResourceDefinition::DefaultBlock(shader));
7742*35238bceSAndroid Build Coastguard Worker     const ResourceDefinition::Node::SharedPtr buffer(
7743*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
7744*35238bceSAndroid Build Coastguard Worker     ResourceDefinition::Node::SharedPtr currentStructure(
7745*35238bceSAndroid Build Coastguard Worker         new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
7746*35238bceSAndroid Build Coastguard Worker 
7747*35238bceSAndroid Build Coastguard Worker     if (namedBlock && rnd.getBool())
7748*35238bceSAndroid Build Coastguard Worker         currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
7749*35238bceSAndroid Build Coastguard Worker     currentStructure =
7750*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
7751*35238bceSAndroid Build Coastguard Worker 
7752*35238bceSAndroid Build Coastguard Worker     currentStructure =
7753*35238bceSAndroid Build Coastguard Worker         ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
7754*35238bceSAndroid Build Coastguard Worker     currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
7755*35238bceSAndroid Build Coastguard Worker 
7756*35238bceSAndroid Build Coastguard Worker     targetGroup->addChild(new ResourceTestCase(
7757*35238bceSAndroid Build Coastguard Worker         context, currentStructure,
7758*35238bceSAndroid Build Coastguard Worker         ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK),
7759*35238bceSAndroid Build Coastguard Worker         de::toString(index).c_str()));
7760*35238bceSAndroid Build Coastguard Worker }
7761*35238bceSAndroid Build Coastguard Worker 
generateBufferVariableRandomCases(Context & context,tcu::TestCaseGroup * const targetGroup,glu::GLSLVersion glslVersion)7762*35238bceSAndroid Build Coastguard Worker static void generateBufferVariableRandomCases(Context &context, tcu::TestCaseGroup *const targetGroup,
7763*35238bceSAndroid Build Coastguard Worker                                               glu::GLSLVersion glslVersion)
7764*35238bceSAndroid Build Coastguard Worker {
7765*35238bceSAndroid Build Coastguard Worker     const int numBasicCases   = 40;
7766*35238bceSAndroid Build Coastguard Worker     const int numTessGeoCases = 40;
7767*35238bceSAndroid Build Coastguard Worker 
7768*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numBasicCases; ++ndx)
7769*35238bceSAndroid Build Coastguard Worker         generateBufferVariableRandomCase(context, targetGroup, glslVersion, ndx, false);
7770*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
7771*35238bceSAndroid Build Coastguard Worker         generateBufferVariableRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
7772*35238bceSAndroid Build Coastguard Worker }
7773*35238bceSAndroid Build Coastguard Worker 
7774*35238bceSAndroid Build Coastguard Worker class BufferVariableTestGroup : public TestCaseGroup
7775*35238bceSAndroid Build Coastguard Worker {
7776*35238bceSAndroid Build Coastguard Worker public:
7777*35238bceSAndroid Build Coastguard Worker     BufferVariableTestGroup(Context &context);
7778*35238bceSAndroid Build Coastguard Worker     void init(void);
7779*35238bceSAndroid Build Coastguard Worker };
7780*35238bceSAndroid Build Coastguard Worker 
BufferVariableTestGroup(Context & context)7781*35238bceSAndroid Build Coastguard Worker BufferVariableTestGroup::BufferVariableTestGroup(Context &context)
7782*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "buffer_variable", "Buffer variable")
7783*35238bceSAndroid Build Coastguard Worker {
7784*35238bceSAndroid Build Coastguard Worker }
7785*35238bceSAndroid Build Coastguard Worker 
init(void)7786*35238bceSAndroid Build Coastguard Worker void BufferVariableTestGroup::init(void)
7787*35238bceSAndroid Build Coastguard Worker {
7788*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
7789*35238bceSAndroid Build Coastguard Worker 
7790*35238bceSAndroid Build Coastguard Worker     // .resource_list
7791*35238bceSAndroid Build Coastguard Worker     {
7792*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
7793*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7794*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion,
7795*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableResourceListBlockContentsProxy);
7796*35238bceSAndroid Build Coastguard Worker     }
7797*35238bceSAndroid Build Coastguard Worker 
7798*35238bceSAndroid Build Coastguard Worker     // .array_size
7799*35238bceSAndroid Build Coastguard Worker     {
7800*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
7801*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7802*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion,
7803*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
7804*35238bceSAndroid Build Coastguard Worker     }
7805*35238bceSAndroid Build Coastguard Worker 
7806*35238bceSAndroid Build Coastguard Worker     // .array_stride
7807*35238bceSAndroid Build Coastguard Worker     {
7808*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
7809*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7810*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion,
7811*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
7812*35238bceSAndroid Build Coastguard Worker     }
7813*35238bceSAndroid Build Coastguard Worker 
7814*35238bceSAndroid Build Coastguard Worker     // .block_index
7815*35238bceSAndroid Build Coastguard Worker     {
7816*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
7817*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7818*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBlockIndexCases(m_context, glslVersion, blockGroup);
7819*35238bceSAndroid Build Coastguard Worker     }
7820*35238bceSAndroid Build Coastguard Worker 
7821*35238bceSAndroid Build Coastguard Worker     // .is_row_major
7822*35238bceSAndroid Build Coastguard Worker     {
7823*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
7824*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7825*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion,
7826*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
7827*35238bceSAndroid Build Coastguard Worker     }
7828*35238bceSAndroid Build Coastguard Worker 
7829*35238bceSAndroid Build Coastguard Worker     // .matrix_stride
7830*35238bceSAndroid Build Coastguard Worker     {
7831*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
7832*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7833*35238bceSAndroid Build Coastguard Worker         generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion,
7834*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
7835*35238bceSAndroid Build Coastguard Worker     }
7836*35238bceSAndroid Build Coastguard Worker 
7837*35238bceSAndroid Build Coastguard Worker     // .name_length
7838*35238bceSAndroid Build Coastguard Worker     {
7839*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
7840*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7841*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion,
7842*35238bceSAndroid Build Coastguard Worker                                                generateBufferVariableNameLengthCases);
7843*35238bceSAndroid Build Coastguard Worker     }
7844*35238bceSAndroid Build Coastguard Worker 
7845*35238bceSAndroid Build Coastguard Worker     // .offset
7846*35238bceSAndroid Build Coastguard Worker     {
7847*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
7848*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7849*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableOffsetCases);
7850*35238bceSAndroid Build Coastguard Worker     }
7851*35238bceSAndroid Build Coastguard Worker 
7852*35238bceSAndroid Build Coastguard Worker     // .referenced_by
7853*35238bceSAndroid Build Coastguard Worker     {
7854*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
7855*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7856*35238bceSAndroid Build Coastguard Worker         generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion,
7857*35238bceSAndroid Build Coastguard Worker                                              generateBufferVariableReferencedByBlockContents);
7858*35238bceSAndroid Build Coastguard Worker     }
7859*35238bceSAndroid Build Coastguard Worker 
7860*35238bceSAndroid Build Coastguard Worker     // .top_level_array_size
7861*35238bceSAndroid Build Coastguard Worker     {
7862*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
7863*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
7864*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7865*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(
7866*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion,
7867*35238bceSAndroid Build Coastguard Worker             generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
7868*35238bceSAndroid Build Coastguard Worker     }
7869*35238bceSAndroid Build Coastguard Worker 
7870*35238bceSAndroid Build Coastguard Worker     // .top_level_array_stride
7871*35238bceSAndroid Build Coastguard Worker     {
7872*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup =
7873*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
7874*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7875*35238bceSAndroid Build Coastguard Worker         generateBufferVariableBufferCaseBlocks(
7876*35238bceSAndroid Build Coastguard Worker             m_context, blockGroup, glslVersion,
7877*35238bceSAndroid Build Coastguard Worker             generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
7878*35238bceSAndroid Build Coastguard Worker     }
7879*35238bceSAndroid Build Coastguard Worker 
7880*35238bceSAndroid Build Coastguard Worker     // .type
7881*35238bceSAndroid Build Coastguard Worker     {
7882*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "type", "Type");
7883*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7884*35238bceSAndroid Build Coastguard Worker         generateBufferVariableTypeBlock(m_context, blockGroup, glslVersion);
7885*35238bceSAndroid Build Coastguard Worker     }
7886*35238bceSAndroid Build Coastguard Worker 
7887*35238bceSAndroid Build Coastguard Worker     // .random
7888*35238bceSAndroid Build Coastguard Worker     {
7889*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const blockGroup = new TestCaseGroup(m_context, "random", "Random");
7890*35238bceSAndroid Build Coastguard Worker         addChild(blockGroup);
7891*35238bceSAndroid Build Coastguard Worker         generateBufferVariableRandomCases(m_context, blockGroup, glslVersion);
7892*35238bceSAndroid Build Coastguard Worker     }
7893*35238bceSAndroid Build Coastguard Worker }
7894*35238bceSAndroid Build Coastguard Worker 
7895*35238bceSAndroid Build Coastguard Worker } // namespace
7896*35238bceSAndroid Build Coastguard Worker 
ProgramInterfaceQueryTests(Context & context,bool is_GL45)7897*35238bceSAndroid Build Coastguard Worker ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(Context &context, bool is_GL45)
7898*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7899*35238bceSAndroid Build Coastguard Worker     , m_isGL45(is_GL45)
7900*35238bceSAndroid Build Coastguard Worker {
7901*35238bceSAndroid Build Coastguard Worker }
7902*35238bceSAndroid Build Coastguard Worker 
~ProgramInterfaceQueryTests(void)7903*35238bceSAndroid Build Coastguard Worker ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
7904*35238bceSAndroid Build Coastguard Worker {
7905*35238bceSAndroid Build Coastguard Worker }
7906*35238bceSAndroid Build Coastguard Worker 
init(void)7907*35238bceSAndroid Build Coastguard Worker void ProgramInterfaceQueryTests::init(void)
7908*35238bceSAndroid Build Coastguard Worker {
7909*35238bceSAndroid Build Coastguard Worker     // Misc queries
7910*35238bceSAndroid Build Coastguard Worker 
7911*35238bceSAndroid Build Coastguard Worker     // .buffer_limited_query
7912*35238bceSAndroid Build Coastguard Worker     {
7913*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const group =
7914*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7915*35238bceSAndroid Build Coastguard Worker 
7916*35238bceSAndroid Build Coastguard Worker         addChild(group);
7917*35238bceSAndroid Build Coastguard Worker 
7918*35238bceSAndroid Build Coastguard Worker         group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query",
7919*35238bceSAndroid Build Coastguard Worker                                                         "Test GetProgramResourceName with too small a buffer"));
7920*35238bceSAndroid Build Coastguard Worker         group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query",
7921*35238bceSAndroid Build Coastguard Worker                                                          "Test GetProgramResourceiv with too small a buffer"));
7922*35238bceSAndroid Build Coastguard Worker     }
7923*35238bceSAndroid Build Coastguard Worker 
7924*35238bceSAndroid Build Coastguard Worker     // Interfaces
7925*35238bceSAndroid Build Coastguard Worker 
7926*35238bceSAndroid Build Coastguard Worker     // .uniform
7927*35238bceSAndroid Build Coastguard Worker     addChild(new UniformInterfaceTestGroup(m_context));
7928*35238bceSAndroid Build Coastguard Worker 
7929*35238bceSAndroid Build Coastguard Worker     // .uniform_block
7930*35238bceSAndroid Build Coastguard Worker     addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7931*35238bceSAndroid Build Coastguard Worker 
7932*35238bceSAndroid Build Coastguard Worker     // .atomic_counter_buffer
7933*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterTestGroup(m_context));
7934*35238bceSAndroid Build Coastguard Worker 
7935*35238bceSAndroid Build Coastguard Worker     // .program_input
7936*35238bceSAndroid Build Coastguard Worker     addChild(new ProgramInputTestGroup(m_context, m_isGL45));
7937*35238bceSAndroid Build Coastguard Worker 
7938*35238bceSAndroid Build Coastguard Worker     // .program_output
7939*35238bceSAndroid Build Coastguard Worker     addChild(new ProgramOutputTestGroup(m_context, m_isGL45));
7940*35238bceSAndroid Build Coastguard Worker 
7941*35238bceSAndroid Build Coastguard Worker     // .transform_feedback_varying
7942*35238bceSAndroid Build Coastguard Worker     addChild(new TransformFeedbackVaryingTestGroup(m_context));
7943*35238bceSAndroid Build Coastguard Worker 
7944*35238bceSAndroid Build Coastguard Worker     // .buffer_variable
7945*35238bceSAndroid Build Coastguard Worker     addChild(new BufferVariableTestGroup(m_context));
7946*35238bceSAndroid Build Coastguard Worker 
7947*35238bceSAndroid Build Coastguard Worker     // .shader_storage_block
7948*35238bceSAndroid Build Coastguard Worker     addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));
7949*35238bceSAndroid Build Coastguard Worker }
7950*35238bceSAndroid Build Coastguard Worker 
7951*35238bceSAndroid Build Coastguard Worker } // namespace Functional
7952*35238bceSAndroid Build Coastguard Worker } // namespace gles31
7953*35238bceSAndroid Build Coastguard Worker } // namespace deqp
7954