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 test case
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceQueryTestCase.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceDefinitionUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluVarTypeUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deString.h"
34*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deSTLUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker namespace deqp
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker namespace gles31
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace Functional
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker using ProgramInterfaceDefinition::VariablePathComponent;
47*35238bceSAndroid Build Coastguard Worker using ProgramInterfaceDefinition::VariableSearchFilter;
48*35238bceSAndroid Build Coastguard Worker
getProgramDefaultBlockInterfaceFromStorage(glu::Storage storage)49*35238bceSAndroid Build Coastguard Worker static glw::GLenum getProgramDefaultBlockInterfaceFromStorage(glu::Storage storage)
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker switch (storage)
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker case glu::STORAGE_IN:
54*35238bceSAndroid Build Coastguard Worker case glu::STORAGE_PATCH_IN:
55*35238bceSAndroid Build Coastguard Worker return GL_PROGRAM_INPUT;
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker case glu::STORAGE_OUT:
58*35238bceSAndroid Build Coastguard Worker case glu::STORAGE_PATCH_OUT:
59*35238bceSAndroid Build Coastguard Worker return GL_PROGRAM_OUTPUT;
60*35238bceSAndroid Build Coastguard Worker
61*35238bceSAndroid Build Coastguard Worker case glu::STORAGE_UNIFORM:
62*35238bceSAndroid Build Coastguard Worker return GL_UNIFORM;
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker default:
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 }
69*35238bceSAndroid Build Coastguard Worker
isBufferBackedInterfaceBlockStorage(glu::Storage storage)70*35238bceSAndroid Build Coastguard Worker static bool isBufferBackedInterfaceBlockStorage(glu::Storage storage)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker return storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM;
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker
getRequiredExtensionForStage(glu::ShaderType stage)75*35238bceSAndroid Build Coastguard Worker const char *getRequiredExtensionForStage(glu::ShaderType stage)
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker switch (stage)
78*35238bceSAndroid Build Coastguard Worker {
79*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_COMPUTE:
80*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
81*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
82*35238bceSAndroid Build Coastguard Worker return DE_NULL;
83*35238bceSAndroid Build Coastguard Worker
84*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
85*35238bceSAndroid Build Coastguard Worker return "GL_EXT_geometry_shader";
86*35238bceSAndroid Build Coastguard Worker
87*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
88*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
89*35238bceSAndroid Build Coastguard Worker return "GL_EXT_tessellation_shader";
90*35238bceSAndroid Build Coastguard Worker
91*35238bceSAndroid Build Coastguard Worker default:
92*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
93*35238bceSAndroid Build Coastguard Worker return DE_NULL;
94*35238bceSAndroid Build Coastguard Worker }
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker
getTypeSize(glu::DataType type)97*35238bceSAndroid Build Coastguard Worker static int getTypeSize(glu::DataType type)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker if (type == glu::TYPE_FLOAT)
100*35238bceSAndroid Build Coastguard Worker return 4;
101*35238bceSAndroid Build Coastguard Worker else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
102*35238bceSAndroid Build Coastguard Worker return 4;
103*35238bceSAndroid Build Coastguard Worker else if (type == glu::TYPE_BOOL)
104*35238bceSAndroid Build Coastguard Worker return 4; // uint
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
107*35238bceSAndroid Build Coastguard Worker return 0;
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker
getVarTypeSize(const glu::VarType & type)110*35238bceSAndroid Build Coastguard Worker static int getVarTypeSize(const glu::VarType &type)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker // return in basic machine units
115*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeScalarSize(type.getBasicType()) *
116*35238bceSAndroid Build Coastguard Worker getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker else if (type.isStructType())
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker int size = 0;
121*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
122*35238bceSAndroid Build Coastguard Worker size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
123*35238bceSAndroid Build Coastguard Worker return size;
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker // unsized arrays are handled as if they had only one element
128*35238bceSAndroid Build Coastguard Worker if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
129*35238bceSAndroid Build Coastguard Worker return getVarTypeSize(type.getElementType());
130*35238bceSAndroid Build Coastguard Worker else
131*35238bceSAndroid Build Coastguard Worker return type.getArraySize() * getVarTypeSize(type.getElementType());
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker else
134*35238bceSAndroid Build Coastguard Worker {
135*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
136*35238bceSAndroid Build Coastguard Worker return 0;
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker }
139*35238bceSAndroid Build Coastguard Worker
getMatrixOrderFromPath(const std::vector<VariablePathComponent> & path)140*35238bceSAndroid Build Coastguard Worker static glu::MatrixOrder getMatrixOrderFromPath(const std::vector<VariablePathComponent> &path)
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker glu::MatrixOrder order = glu::MATRIXORDER_LAST;
143*35238bceSAndroid Build Coastguard Worker
144*35238bceSAndroid Build Coastguard Worker // inherit majority
145*35238bceSAndroid Build Coastguard Worker for (int pathNdx = 0; pathNdx < (int)path.size(); ++pathNdx)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker glu::MatrixOrder matOrder;
148*35238bceSAndroid Build Coastguard Worker
149*35238bceSAndroid Build Coastguard Worker if (path[pathNdx].isInterfaceBlock())
150*35238bceSAndroid Build Coastguard Worker matOrder = path[pathNdx].getInterfaceBlock()->layout.matrixOrder;
151*35238bceSAndroid Build Coastguard Worker else if (path[pathNdx].isDeclaration())
152*35238bceSAndroid Build Coastguard Worker matOrder = path[pathNdx].getDeclaration()->layout.matrixOrder;
153*35238bceSAndroid Build Coastguard Worker else if (path[pathNdx].isVariableType())
154*35238bceSAndroid Build Coastguard Worker matOrder = glu::MATRIXORDER_LAST;
155*35238bceSAndroid Build Coastguard Worker else
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
158*35238bceSAndroid Build Coastguard Worker return glu::MATRIXORDER_LAST;
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker
161*35238bceSAndroid Build Coastguard Worker if (matOrder != glu::MATRIXORDER_LAST)
162*35238bceSAndroid Build Coastguard Worker order = matOrder;
163*35238bceSAndroid Build Coastguard Worker }
164*35238bceSAndroid Build Coastguard Worker
165*35238bceSAndroid Build Coastguard Worker return order;
166*35238bceSAndroid Build Coastguard Worker }
167*35238bceSAndroid Build Coastguard Worker
168*35238bceSAndroid Build Coastguard Worker class PropValidator
169*35238bceSAndroid Build Coastguard Worker {
170*35238bceSAndroid Build Coastguard Worker public:
171*35238bceSAndroid Build Coastguard Worker PropValidator(Context &context, ProgramResourcePropFlags validationProp, const char *requiredExtension);
172*35238bceSAndroid Build Coastguard Worker
173*35238bceSAndroid Build Coastguard Worker virtual std::string getHumanReadablePropertyString(glw::GLint propVal) const;
174*35238bceSAndroid Build Coastguard Worker virtual void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource,
175*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const = 0;
176*35238bceSAndroid Build Coastguard Worker
177*35238bceSAndroid Build Coastguard Worker bool isSupported(void) const;
178*35238bceSAndroid Build Coastguard Worker bool isSelected(uint32_t caseFlags) const;
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Worker protected:
181*35238bceSAndroid Build Coastguard Worker void setError(const std::string &err) const;
182*35238bceSAndroid Build Coastguard Worker
183*35238bceSAndroid Build Coastguard Worker tcu::TestContext &m_testCtx;
184*35238bceSAndroid Build Coastguard Worker const glu::RenderContext &m_renderContext;
185*35238bceSAndroid Build Coastguard Worker
186*35238bceSAndroid Build Coastguard Worker private:
187*35238bceSAndroid Build Coastguard Worker const glu::ContextInfo &m_contextInfo;
188*35238bceSAndroid Build Coastguard Worker const char *m_extension;
189*35238bceSAndroid Build Coastguard Worker const ProgramResourcePropFlags m_validationProp;
190*35238bceSAndroid Build Coastguard Worker };
191*35238bceSAndroid Build Coastguard Worker
PropValidator(Context & context,ProgramResourcePropFlags validationProp,const char * requiredExtension)192*35238bceSAndroid Build Coastguard Worker PropValidator::PropValidator(Context &context, ProgramResourcePropFlags validationProp, const char *requiredExtension)
193*35238bceSAndroid Build Coastguard Worker : m_testCtx(context.getTestContext())
194*35238bceSAndroid Build Coastguard Worker , m_renderContext(context.getRenderContext())
195*35238bceSAndroid Build Coastguard Worker , m_contextInfo(context.getContextInfo())
196*35238bceSAndroid Build Coastguard Worker , m_extension(requiredExtension)
197*35238bceSAndroid Build Coastguard Worker , m_validationProp(validationProp)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker }
200*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const201*35238bceSAndroid Build Coastguard Worker std::string PropValidator::getHumanReadablePropertyString(glw::GLint propVal) const
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker return de::toString(propVal);
204*35238bceSAndroid Build Coastguard Worker }
205*35238bceSAndroid Build Coastguard Worker
isSupported(void) const206*35238bceSAndroid Build Coastguard Worker bool PropValidator::isSupported(void) const
207*35238bceSAndroid Build Coastguard Worker {
208*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(m_renderContext.getType(), glu::ApiType::es(3, 2)) ||
209*35238bceSAndroid Build Coastguard Worker glu::contextSupports(m_renderContext.getType(), glu::ApiType::core(4, 5)))
210*35238bceSAndroid Build Coastguard Worker return true;
211*35238bceSAndroid Build Coastguard Worker return m_extension == DE_NULL || m_contextInfo.isExtensionSupported(m_extension);
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker
isSelected(uint32_t caseFlags) const214*35238bceSAndroid Build Coastguard Worker bool PropValidator::isSelected(uint32_t caseFlags) const
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker return (caseFlags & (uint32_t)m_validationProp) != 0;
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker
setError(const std::string & err) const219*35238bceSAndroid Build Coastguard Worker void PropValidator::setError(const std::string &err) const
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker // don't overwrite earlier errors
222*35238bceSAndroid Build Coastguard Worker if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
223*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, err.c_str());
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker class SingleVariableValidator : public PropValidator
227*35238bceSAndroid Build Coastguard Worker {
228*35238bceSAndroid Build Coastguard Worker public:
229*35238bceSAndroid Build Coastguard Worker SingleVariableValidator(Context &context, ProgramResourcePropFlags validationProp, glw::GLuint programID,
230*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter, const char *requiredExtension);
231*35238bceSAndroid Build Coastguard Worker
232*35238bceSAndroid Build Coastguard Worker void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource, glw::GLint propValue,
233*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
234*35238bceSAndroid Build Coastguard Worker virtual void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
235*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const = 0;
236*35238bceSAndroid Build Coastguard Worker virtual void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
237*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
238*35238bceSAndroid Build Coastguard Worker
239*35238bceSAndroid Build Coastguard Worker protected:
240*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter m_filter;
241*35238bceSAndroid Build Coastguard Worker const glw::GLuint m_programID;
242*35238bceSAndroid Build Coastguard Worker };
243*35238bceSAndroid Build Coastguard Worker
SingleVariableValidator(Context & context,ProgramResourcePropFlags validationProp,glw::GLuint programID,const VariableSearchFilter & filter,const char * requiredExtension)244*35238bceSAndroid Build Coastguard Worker SingleVariableValidator::SingleVariableValidator(Context &context, ProgramResourcePropFlags validationProp,
245*35238bceSAndroid Build Coastguard Worker glw::GLuint programID, const VariableSearchFilter &filter,
246*35238bceSAndroid Build Coastguard Worker const char *requiredExtension)
247*35238bceSAndroid Build Coastguard Worker : PropValidator(context, validationProp, requiredExtension)
248*35238bceSAndroid Build Coastguard Worker , m_filter(filter)
249*35238bceSAndroid Build Coastguard Worker , m_programID(programID)
250*35238bceSAndroid Build Coastguard Worker {
251*35238bceSAndroid Build Coastguard Worker }
252*35238bceSAndroid Build Coastguard Worker
validate(const ProgramInterfaceDefinition::Program * program,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const253*35238bceSAndroid Build Coastguard Worker void SingleVariableValidator::validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource,
254*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const
255*35238bceSAndroid Build Coastguard Worker {
256*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> path;
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker if (findProgramVariablePathByPathName(path, program, resource, m_filter))
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker const glu::VarType *variable = (path.back().isVariableType()) ? (path.back().getVariableType()) : (DE_NULL);
261*35238bceSAndroid Build Coastguard Worker
262*35238bceSAndroid Build Coastguard Worker if (!variable || !variable->isBasicType())
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource name \"" << resource
265*35238bceSAndroid Build Coastguard Worker << "\" refers to a non-basic type." << tcu::TestLog::EndMessage;
266*35238bceSAndroid Build Coastguard Worker setError("resource not basic type");
267*35238bceSAndroid Build Coastguard Worker }
268*35238bceSAndroid Build Coastguard Worker else
269*35238bceSAndroid Build Coastguard Worker validateSingleVariable(path, resource, propValue, implementationName);
270*35238bceSAndroid Build Coastguard Worker
271*35238bceSAndroid Build Coastguard Worker // finding matching variable in any shader is sufficient
272*35238bceSAndroid Build Coastguard Worker return;
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker else if (deStringBeginsWith(resource.c_str(), "gl_"))
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker // special case for builtins
277*35238bceSAndroid Build Coastguard Worker validateBuiltinVariable(resource, propValue, implementationName);
278*35238bceSAndroid Build Coastguard Worker return;
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker
281*35238bceSAndroid Build Coastguard Worker // we are only supplied good names, generated by ourselves
282*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
283*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError("Resource name consistency error");
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const286*35238bceSAndroid Build Coastguard Worker void SingleVariableValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
287*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
290*35238bceSAndroid Build Coastguard Worker DE_UNREF(propValue);
291*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
292*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
293*35238bceSAndroid Build Coastguard Worker }
294*35238bceSAndroid Build Coastguard Worker
295*35238bceSAndroid Build Coastguard Worker class SingleBlockValidator : public PropValidator
296*35238bceSAndroid Build Coastguard Worker {
297*35238bceSAndroid Build Coastguard Worker public:
298*35238bceSAndroid Build Coastguard Worker SingleBlockValidator(Context &context, ProgramResourcePropFlags validationProp, glw::GLuint programID,
299*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter, const char *requiredExtension);
300*35238bceSAndroid Build Coastguard Worker
301*35238bceSAndroid Build Coastguard Worker void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource, glw::GLint propValue,
302*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
303*35238bceSAndroid Build Coastguard Worker virtual void validateSingleBlock(const glu::InterfaceBlock &block, const std::vector<int> &instanceIndex,
304*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
305*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const = 0;
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker protected:
308*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter m_filter;
309*35238bceSAndroid Build Coastguard Worker const glw::GLuint m_programID;
310*35238bceSAndroid Build Coastguard Worker };
311*35238bceSAndroid Build Coastguard Worker
SingleBlockValidator(Context & context,ProgramResourcePropFlags validationProp,glw::GLuint programID,const VariableSearchFilter & filter,const char * requiredExtension)312*35238bceSAndroid Build Coastguard Worker SingleBlockValidator::SingleBlockValidator(Context &context, ProgramResourcePropFlags validationProp,
313*35238bceSAndroid Build Coastguard Worker glw::GLuint programID, const VariableSearchFilter &filter,
314*35238bceSAndroid Build Coastguard Worker const char *requiredExtension)
315*35238bceSAndroid Build Coastguard Worker : PropValidator(context, validationProp, requiredExtension)
316*35238bceSAndroid Build Coastguard Worker , m_filter(filter)
317*35238bceSAndroid Build Coastguard Worker , m_programID(programID)
318*35238bceSAndroid Build Coastguard Worker {
319*35238bceSAndroid Build Coastguard Worker }
320*35238bceSAndroid Build Coastguard Worker
validate(const ProgramInterfaceDefinition::Program * program,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const321*35238bceSAndroid Build Coastguard Worker void SingleBlockValidator::validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource,
322*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const
323*35238bceSAndroid Build Coastguard Worker {
324*35238bceSAndroid Build Coastguard Worker glu::VarTokenizer tokenizer(resource.c_str());
325*35238bceSAndroid Build Coastguard Worker const std::string blockName = tokenizer.getIdentifier();
326*35238bceSAndroid Build Coastguard Worker std::vector<int> instanceIndex;
327*35238bceSAndroid Build Coastguard Worker
328*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
329*35238bceSAndroid Build Coastguard Worker
330*35238bceSAndroid Build Coastguard Worker // array index
331*35238bceSAndroid Build Coastguard Worker while (tokenizer.getToken() == glu::VarTokenizer::TOKEN_LEFT_BRACKET)
332*35238bceSAndroid Build Coastguard Worker {
333*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
334*35238bceSAndroid Build Coastguard Worker DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_NUMBER);
335*35238bceSAndroid Build Coastguard Worker
336*35238bceSAndroid Build Coastguard Worker instanceIndex.push_back(tokenizer.getNumber());
337*35238bceSAndroid Build Coastguard Worker
338*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
339*35238bceSAndroid Build Coastguard Worker DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_RIGHT_BRACKET);
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
342*35238bceSAndroid Build Coastguard Worker }
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker // no trailing garbage
345*35238bceSAndroid Build Coastguard Worker DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_END);
346*35238bceSAndroid Build Coastguard Worker
347*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
348*35238bceSAndroid Build Coastguard Worker {
349*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *const shader = program->getShaders()[shaderNdx];
350*35238bceSAndroid Build Coastguard Worker if (!m_filter.matchesFilter(shader))
351*35238bceSAndroid Build Coastguard Worker continue;
352*35238bceSAndroid Build Coastguard Worker
353*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block = shader->getDefaultBlock().interfaceBlocks[blockNdx];
356*35238bceSAndroid Build Coastguard Worker
357*35238bceSAndroid Build Coastguard Worker if (m_filter.matchesFilter(block) && block.interfaceName == blockName)
358*35238bceSAndroid Build Coastguard Worker {
359*35238bceSAndroid Build Coastguard Worker // dimensions match
360*35238bceSAndroid Build Coastguard Worker DE_ASSERT(instanceIndex.size() == block.dimensions.size());
361*35238bceSAndroid Build Coastguard Worker
362*35238bceSAndroid Build Coastguard Worker validateSingleBlock(block, instanceIndex, resource, propValue, implementationName);
363*35238bceSAndroid Build Coastguard Worker return;
364*35238bceSAndroid Build Coastguard Worker }
365*35238bceSAndroid Build Coastguard Worker }
366*35238bceSAndroid Build Coastguard Worker }
367*35238bceSAndroid Build Coastguard Worker
368*35238bceSAndroid Build Coastguard Worker // we are only supplied good names, generated by ourselves
369*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
370*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError("Resource name consistency error");
371*35238bceSAndroid Build Coastguard Worker }
372*35238bceSAndroid Build Coastguard Worker
373*35238bceSAndroid Build Coastguard Worker class TypeValidator : public SingleVariableValidator
374*35238bceSAndroid Build Coastguard Worker {
375*35238bceSAndroid Build Coastguard Worker public:
376*35238bceSAndroid Build Coastguard Worker TypeValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
377*35238bceSAndroid Build Coastguard Worker
378*35238bceSAndroid Build Coastguard Worker std::string getHumanReadablePropertyString(glw::GLint propVal) const;
379*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
380*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
381*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
382*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
383*35238bceSAndroid Build Coastguard Worker };
384*35238bceSAndroid Build Coastguard Worker
TypeValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)385*35238bceSAndroid Build Coastguard Worker TypeValidator::TypeValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
386*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TYPE, programID, filter, DE_NULL)
387*35238bceSAndroid Build Coastguard Worker {
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const390*35238bceSAndroid Build Coastguard Worker std::string TypeValidator::getHumanReadablePropertyString(glw::GLint propVal) const
391*35238bceSAndroid Build Coastguard Worker {
392*35238bceSAndroid Build Coastguard Worker return de::toString(glu::getShaderVarTypeStr(propVal));
393*35238bceSAndroid Build Coastguard Worker }
394*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const395*35238bceSAndroid Build Coastguard Worker void TypeValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
396*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const
397*35238bceSAndroid Build Coastguard Worker {
398*35238bceSAndroid Build Coastguard Worker const glu::VarType *variable = path.back().getVariableType();
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
401*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
402*35238bceSAndroid Build Coastguard Worker
403*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting "
404*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(variable->getBasicType()) << tcu::TestLog::EndMessage;
405*35238bceSAndroid Build Coastguard Worker
406*35238bceSAndroid Build Coastguard Worker if (variable->getBasicType() != glu::getDataTypeFromGLType(propValue))
407*35238bceSAndroid Build Coastguard Worker {
408*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got "
409*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
410*35238bceSAndroid Build Coastguard Worker setError("resource type invalid");
411*35238bceSAndroid Build Coastguard Worker }
412*35238bceSAndroid Build Coastguard Worker }
413*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const414*35238bceSAndroid Build Coastguard Worker void TypeValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
415*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
416*35238bceSAndroid Build Coastguard Worker {
417*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
418*35238bceSAndroid Build Coastguard Worker
419*35238bceSAndroid Build Coastguard Worker static const struct
420*35238bceSAndroid Build Coastguard Worker {
421*35238bceSAndroid Build Coastguard Worker const char *name;
422*35238bceSAndroid Build Coastguard Worker glu::DataType type;
423*35238bceSAndroid Build Coastguard Worker } builtins[] = {
424*35238bceSAndroid Build Coastguard Worker {"gl_Position", glu::TYPE_FLOAT_VEC4},
425*35238bceSAndroid Build Coastguard Worker {"gl_FragCoord", glu::TYPE_FLOAT_VEC4},
426*35238bceSAndroid Build Coastguard Worker {"gl_PerVertex.gl_Position", glu::TYPE_FLOAT_VEC4},
427*35238bceSAndroid Build Coastguard Worker {"gl_VertexID", glu::TYPE_INT},
428*35238bceSAndroid Build Coastguard Worker {"gl_InvocationID", glu::TYPE_INT},
429*35238bceSAndroid Build Coastguard Worker {"gl_NumWorkGroups", glu::TYPE_UINT_VEC3},
430*35238bceSAndroid Build Coastguard Worker {"gl_FragDepth", glu::TYPE_FLOAT},
431*35238bceSAndroid Build Coastguard Worker {"gl_TessLevelOuter[0]", glu::TYPE_FLOAT},
432*35238bceSAndroid Build Coastguard Worker {"gl_TessLevelInner[0]", glu::TYPE_FLOAT},
433*35238bceSAndroid Build Coastguard Worker };
434*35238bceSAndroid Build Coastguard Worker
435*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
436*35238bceSAndroid Build Coastguard Worker {
437*35238bceSAndroid Build Coastguard Worker if (resource == builtins[ndx].name)
438*35238bceSAndroid Build Coastguard Worker {
439*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting "
440*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(builtins[ndx].type) << tcu::TestLog::EndMessage;
441*35238bceSAndroid Build Coastguard Worker
442*35238bceSAndroid Build Coastguard Worker if (glu::getDataTypeFromGLType(propValue) != builtins[ndx].type)
443*35238bceSAndroid Build Coastguard Worker {
444*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got "
445*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue))
446*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
447*35238bceSAndroid Build Coastguard Worker setError("resource type invalid");
448*35238bceSAndroid Build Coastguard Worker }
449*35238bceSAndroid Build Coastguard Worker return;
450*35238bceSAndroid Build Coastguard Worker }
451*35238bceSAndroid Build Coastguard Worker }
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
454*35238bceSAndroid Build Coastguard Worker }
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker class ArraySizeValidator : public SingleVariableValidator
457*35238bceSAndroid Build Coastguard Worker {
458*35238bceSAndroid Build Coastguard Worker public:
459*35238bceSAndroid Build Coastguard Worker ArraySizeValidator(Context &context, glw::GLuint programID, int unsizedArraySize,
460*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter);
461*35238bceSAndroid Build Coastguard Worker
462*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
463*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
464*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
465*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
466*35238bceSAndroid Build Coastguard Worker
467*35238bceSAndroid Build Coastguard Worker private:
468*35238bceSAndroid Build Coastguard Worker const int m_unsizedArraySize;
469*35238bceSAndroid Build Coastguard Worker };
470*35238bceSAndroid Build Coastguard Worker
ArraySizeValidator(Context & context,glw::GLuint programID,int unsizedArraySize,const VariableSearchFilter & filter)471*35238bceSAndroid Build Coastguard Worker ArraySizeValidator::ArraySizeValidator(Context &context, glw::GLuint programID, int unsizedArraySize,
472*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
473*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ARRAY_SIZE, programID, filter, DE_NULL)
474*35238bceSAndroid Build Coastguard Worker , m_unsizedArraySize(unsizedArraySize)
475*35238bceSAndroid Build Coastguard Worker {
476*35238bceSAndroid Build Coastguard Worker }
477*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const478*35238bceSAndroid Build Coastguard Worker void ArraySizeValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
479*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
480*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
481*35238bceSAndroid Build Coastguard Worker {
482*35238bceSAndroid Build Coastguard Worker const VariablePathComponent nullComponent;
483*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &enclosingcomponent = (path.size() > 1) ? (path[path.size() - 2]) : (nullComponent);
484*35238bceSAndroid Build Coastguard Worker
485*35238bceSAndroid Build Coastguard Worker const bool isArray = enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();
486*35238bceSAndroid Build Coastguard Worker const bool inUnsizedArray =
487*35238bceSAndroid Build Coastguard Worker isArray && (enclosingcomponent.getVariableType()->getArraySize() == glu::VarType::UNSIZED_ARRAY);
488*35238bceSAndroid Build Coastguard Worker const int arraySize = (!isArray) ? (1) :
489*35238bceSAndroid Build Coastguard Worker (inUnsizedArray) ? (m_unsizedArraySize) :
490*35238bceSAndroid Build Coastguard Worker (enclosingcomponent.getVariableType()->getArraySize());
491*35238bceSAndroid Build Coastguard Worker
492*35238bceSAndroid Build Coastguard Worker DE_ASSERT(arraySize >= 0);
493*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
494*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
495*35238bceSAndroid Build Coastguard Worker
496*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize
497*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
498*35238bceSAndroid Build Coastguard Worker
499*35238bceSAndroid Build Coastguard Worker if (arraySize != propValue)
500*35238bceSAndroid Build Coastguard Worker {
501*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
502*35238bceSAndroid Build Coastguard Worker setError("resource array size invalid");
503*35238bceSAndroid Build Coastguard Worker }
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const506*35238bceSAndroid Build Coastguard Worker void ArraySizeValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
507*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
508*35238bceSAndroid Build Coastguard Worker {
509*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker static const struct
512*35238bceSAndroid Build Coastguard Worker {
513*35238bceSAndroid Build Coastguard Worker const char *name;
514*35238bceSAndroid Build Coastguard Worker int arraySize;
515*35238bceSAndroid Build Coastguard Worker } builtins[] = {
516*35238bceSAndroid Build Coastguard Worker {"gl_Position", 1}, {"gl_VertexID", 1}, {"gl_FragCoord", 1}, {"gl_PerVertex.gl_Position", 1},
517*35238bceSAndroid Build Coastguard Worker {"gl_InvocationID", 1}, {"gl_NumWorkGroups", 1}, {"gl_FragDepth", 1}, {"gl_TessLevelOuter[0]", 4},
518*35238bceSAndroid Build Coastguard Worker {"gl_TessLevelInner[0]", 2},
519*35238bceSAndroid Build Coastguard Worker };
520*35238bceSAndroid Build Coastguard Worker
521*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
522*35238bceSAndroid Build Coastguard Worker {
523*35238bceSAndroid Build Coastguard Worker if (resource == builtins[ndx].name)
524*35238bceSAndroid Build Coastguard Worker {
525*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << builtins[ndx].arraySize
526*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker if (propValue != builtins[ndx].arraySize)
529*35238bceSAndroid Build Coastguard Worker {
530*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
531*35238bceSAndroid Build Coastguard Worker setError("resource array size invalid");
532*35238bceSAndroid Build Coastguard Worker }
533*35238bceSAndroid Build Coastguard Worker return;
534*35238bceSAndroid Build Coastguard Worker }
535*35238bceSAndroid Build Coastguard Worker }
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
538*35238bceSAndroid Build Coastguard Worker }
539*35238bceSAndroid Build Coastguard Worker
540*35238bceSAndroid Build Coastguard Worker class ArrayStrideValidator : public SingleVariableValidator
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker public:
543*35238bceSAndroid Build Coastguard Worker ArrayStrideValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
544*35238bceSAndroid Build Coastguard Worker
545*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
546*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
547*35238bceSAndroid Build Coastguard Worker };
548*35238bceSAndroid Build Coastguard Worker
ArrayStrideValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)549*35238bceSAndroid Build Coastguard Worker ArrayStrideValidator::ArrayStrideValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
550*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ARRAY_STRIDE, programID, filter, DE_NULL)
551*35238bceSAndroid Build Coastguard Worker {
552*35238bceSAndroid Build Coastguard Worker }
553*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const554*35238bceSAndroid Build Coastguard Worker void ArrayStrideValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
555*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
556*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker const VariablePathComponent nullComponent;
559*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &component = path.back();
560*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &enclosingcomponent = (path.size() > 1) ? (path[path.size() - 2]) : (nullComponent);
561*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &firstComponent = path.front();
562*35238bceSAndroid Build Coastguard Worker
563*35238bceSAndroid Build Coastguard Worker const bool isBufferBlock = firstComponent.isInterfaceBlock() &&
564*35238bceSAndroid Build Coastguard Worker isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
565*35238bceSAndroid Build Coastguard Worker const bool isArray = enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();
566*35238bceSAndroid Build Coastguard Worker const bool isAtomicCounter = glu::isDataTypeAtomicCounter(
567*35238bceSAndroid Build Coastguard Worker component.getVariableType()
568*35238bceSAndroid Build Coastguard Worker ->getBasicType()); // atomic counters are buffer backed with a stride of 4 basic machine units
569*35238bceSAndroid Build Coastguard Worker
570*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
571*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
572*35238bceSAndroid Build Coastguard Worker
573*35238bceSAndroid Build Coastguard Worker // Layout tests will verify layouts of buffer backed arrays properly. Here we just check values are greater or equal to the element size
574*35238bceSAndroid Build Coastguard Worker if (isBufferBlock && isArray)
575*35238bceSAndroid Build Coastguard Worker {
576*35238bceSAndroid Build Coastguard Worker const int elementSize = glu::getDataTypeScalarSize(component.getVariableType()->getBasicType()) *
577*35238bceSAndroid Build Coastguard Worker getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType()));
578*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting greater or equal to "
579*35238bceSAndroid Build Coastguard Worker << elementSize << tcu::TestLog::EndMessage;
580*35238bceSAndroid Build Coastguard Worker
581*35238bceSAndroid Build Coastguard Worker if (propValue < elementSize)
582*35238bceSAndroid Build Coastguard Worker {
583*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
584*35238bceSAndroid Build Coastguard Worker setError("resource array stride invalid");
585*35238bceSAndroid Build Coastguard Worker }
586*35238bceSAndroid Build Coastguard Worker }
587*35238bceSAndroid Build Coastguard Worker else
588*35238bceSAndroid Build Coastguard Worker {
589*35238bceSAndroid Build Coastguard Worker // Atomics are buffer backed with stride of 4 even though they are not in an interface block
590*35238bceSAndroid Build Coastguard Worker const int arrayStride = (isAtomicCounter && isArray) ? (4) : (!isBufferBlock && !isAtomicCounter) ? (-1) : (0);
591*35238bceSAndroid Build Coastguard Worker
592*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting " << arrayStride
593*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
594*35238bceSAndroid Build Coastguard Worker
595*35238bceSAndroid Build Coastguard Worker if (arrayStride != propValue)
596*35238bceSAndroid Build Coastguard Worker {
597*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
598*35238bceSAndroid Build Coastguard Worker setError("resource array stride invalid");
599*35238bceSAndroid Build Coastguard Worker }
600*35238bceSAndroid Build Coastguard Worker }
601*35238bceSAndroid Build Coastguard Worker }
602*35238bceSAndroid Build Coastguard Worker
603*35238bceSAndroid Build Coastguard Worker class BlockIndexValidator : public SingleVariableValidator
604*35238bceSAndroid Build Coastguard Worker {
605*35238bceSAndroid Build Coastguard Worker public:
606*35238bceSAndroid Build Coastguard Worker BlockIndexValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
607*35238bceSAndroid Build Coastguard Worker
608*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
609*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
610*35238bceSAndroid Build Coastguard Worker };
611*35238bceSAndroid Build Coastguard Worker
BlockIndexValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)612*35238bceSAndroid Build Coastguard Worker BlockIndexValidator::BlockIndexValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
613*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_BLOCK_INDEX, programID, filter, DE_NULL)
614*35238bceSAndroid Build Coastguard Worker {
615*35238bceSAndroid Build Coastguard Worker }
616*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const617*35238bceSAndroid Build Coastguard Worker void BlockIndexValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
618*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
619*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
620*35238bceSAndroid Build Coastguard Worker {
621*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &firstComponent = path.front();
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
624*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker if (!firstComponent.isInterfaceBlock())
627*35238bceSAndroid Build Coastguard Worker {
628*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting -1"
629*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
630*35238bceSAndroid Build Coastguard Worker
631*35238bceSAndroid Build Coastguard Worker if (propValue != -1)
632*35238bceSAndroid Build Coastguard Worker {
633*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
634*35238bceSAndroid Build Coastguard Worker setError("resource block index invalid");
635*35238bceSAndroid Build Coastguard Worker }
636*35238bceSAndroid Build Coastguard Worker }
637*35238bceSAndroid Build Coastguard Worker else
638*35238bceSAndroid Build Coastguard Worker {
639*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting a valid block index"
640*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
641*35238bceSAndroid Build Coastguard Worker
642*35238bceSAndroid Build Coastguard Worker if (propValue == -1)
643*35238bceSAndroid Build Coastguard Worker {
644*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
645*35238bceSAndroid Build Coastguard Worker setError("resource block index invalid");
646*35238bceSAndroid Build Coastguard Worker }
647*35238bceSAndroid Build Coastguard Worker else
648*35238bceSAndroid Build Coastguard Worker {
649*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderContext.getFunctions();
650*35238bceSAndroid Build Coastguard Worker const glw::GLenum interface =
651*35238bceSAndroid Build Coastguard Worker (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM_BLOCK) :
652*35238bceSAndroid Build Coastguard Worker (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_BUFFER) ? (GL_SHADER_STORAGE_BLOCK) :
653*35238bceSAndroid Build Coastguard Worker (0);
654*35238bceSAndroid Build Coastguard Worker glw::GLint written = 0;
655*35238bceSAndroid Build Coastguard Worker std::vector<char> nameBuffer(firstComponent.getInterfaceBlock()->interfaceName.size() +
656*35238bceSAndroid Build Coastguard Worker 3 * firstComponent.getInterfaceBlock()->dimensions.size() + 2,
657*35238bceSAndroid Build Coastguard Worker '\0'); // +3 for appended "[N]", +1 for '\0' and +1 just for safety
658*35238bceSAndroid Build Coastguard Worker
659*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceName(m_programID, interface, propValue, (int)nameBuffer.size() - 1, &written,
660*35238bceSAndroid Build Coastguard Worker &nameBuffer[0]);
661*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query block name");
662*35238bceSAndroid Build Coastguard Worker TCU_CHECK(written < (int)nameBuffer.size());
663*35238bceSAndroid Build Coastguard Worker TCU_CHECK(nameBuffer.back() == '\0');
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker const std::string blockName(&nameBuffer[0], written);
667*35238bceSAndroid Build Coastguard Worker std::ostringstream expectedName;
668*35238bceSAndroid Build Coastguard Worker
669*35238bceSAndroid Build Coastguard Worker expectedName << firstComponent.getInterfaceBlock()->interfaceName;
670*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0; dimensionNdx < (int)firstComponent.getInterfaceBlock()->dimensions.size();
671*35238bceSAndroid Build Coastguard Worker ++dimensionNdx)
672*35238bceSAndroid Build Coastguard Worker expectedName << "[0]";
673*35238bceSAndroid Build Coastguard Worker
674*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Block name with index " << propValue << " is \""
675*35238bceSAndroid Build Coastguard Worker << blockName << "\"" << tcu::TestLog::EndMessage;
676*35238bceSAndroid Build Coastguard Worker if (blockName != expectedName.str())
677*35238bceSAndroid Build Coastguard Worker {
678*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, expected " << expectedName.str()
679*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
680*35238bceSAndroid Build Coastguard Worker setError("resource block index invalid");
681*35238bceSAndroid Build Coastguard Worker }
682*35238bceSAndroid Build Coastguard Worker }
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker }
685*35238bceSAndroid Build Coastguard Worker }
686*35238bceSAndroid Build Coastguard Worker
687*35238bceSAndroid Build Coastguard Worker class IsRowMajorValidator : public SingleVariableValidator
688*35238bceSAndroid Build Coastguard Worker {
689*35238bceSAndroid Build Coastguard Worker public:
690*35238bceSAndroid Build Coastguard Worker IsRowMajorValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
691*35238bceSAndroid Build Coastguard Worker
692*35238bceSAndroid Build Coastguard Worker std::string getHumanReadablePropertyString(glw::GLint propVal) const;
693*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
694*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
695*35238bceSAndroid Build Coastguard Worker };
696*35238bceSAndroid Build Coastguard Worker
IsRowMajorValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)697*35238bceSAndroid Build Coastguard Worker IsRowMajorValidator::IsRowMajorValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
698*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, programID, filter, DE_NULL)
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker }
701*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const702*35238bceSAndroid Build Coastguard Worker std::string IsRowMajorValidator::getHumanReadablePropertyString(glw::GLint propVal) const
703*35238bceSAndroid Build Coastguard Worker {
704*35238bceSAndroid Build Coastguard Worker return de::toString(glu::getBooleanStr(propVal));
705*35238bceSAndroid Build Coastguard Worker }
706*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const707*35238bceSAndroid Build Coastguard Worker void IsRowMajorValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
708*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
709*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
710*35238bceSAndroid Build Coastguard Worker {
711*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &component = path.back();
712*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &firstComponent = path.front();
713*35238bceSAndroid Build Coastguard Worker
714*35238bceSAndroid Build Coastguard Worker const bool isBufferBlock = firstComponent.isInterfaceBlock() &&
715*35238bceSAndroid Build Coastguard Worker isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
716*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(component.getVariableType()->getBasicType());
717*35238bceSAndroid Build Coastguard Worker const int expected =
718*35238bceSAndroid Build Coastguard Worker (isBufferBlock && isMatrix && getMatrixOrderFromPath(path) == glu::MATRIXORDER_ROW_MAJOR) ? (1) : (0);
719*35238bceSAndroid Build Coastguard Worker
720*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
721*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
722*35238bceSAndroid Build Coastguard Worker
723*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix order, expecting IS_ROW_MAJOR = " << expected
724*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
727*35238bceSAndroid Build Coastguard Worker {
728*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
729*35238bceSAndroid Build Coastguard Worker setError("resource matrix order invalid");
730*35238bceSAndroid Build Coastguard Worker }
731*35238bceSAndroid Build Coastguard Worker }
732*35238bceSAndroid Build Coastguard Worker
733*35238bceSAndroid Build Coastguard Worker class MatrixStrideValidator : public SingleVariableValidator
734*35238bceSAndroid Build Coastguard Worker {
735*35238bceSAndroid Build Coastguard Worker public:
736*35238bceSAndroid Build Coastguard Worker MatrixStrideValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
737*35238bceSAndroid Build Coastguard Worker
738*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
739*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
740*35238bceSAndroid Build Coastguard Worker };
741*35238bceSAndroid Build Coastguard Worker
MatrixStrideValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)742*35238bceSAndroid Build Coastguard Worker MatrixStrideValidator::MatrixStrideValidator(Context &context, glw::GLuint programID,
743*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
744*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_STRIDE, programID, filter, DE_NULL)
745*35238bceSAndroid Build Coastguard Worker {
746*35238bceSAndroid Build Coastguard Worker }
747*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const748*35238bceSAndroid Build Coastguard Worker void MatrixStrideValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
749*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
750*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
751*35238bceSAndroid Build Coastguard Worker {
752*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &component = path.back();
753*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &firstComponent = path.front();
754*35238bceSAndroid Build Coastguard Worker
755*35238bceSAndroid Build Coastguard Worker const bool isBufferBlock = firstComponent.isInterfaceBlock() &&
756*35238bceSAndroid Build Coastguard Worker isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
757*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(component.getVariableType()->getBasicType());
758*35238bceSAndroid Build Coastguard Worker
759*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
760*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
761*35238bceSAndroid Build Coastguard Worker
762*35238bceSAndroid Build Coastguard Worker // Layout tests will verify layouts of buffer backed arrays properly. Here we just check the stride is is greater or equal to the row/column size
763*35238bceSAndroid Build Coastguard Worker if (isBufferBlock && isMatrix)
764*35238bceSAndroid Build Coastguard Worker {
765*35238bceSAndroid Build Coastguard Worker const bool columnMajor = getMatrixOrderFromPath(path) != glu::MATRIXORDER_ROW_MAJOR;
766*35238bceSAndroid Build Coastguard Worker const int numMajorElements =
767*35238bceSAndroid Build Coastguard Worker (columnMajor) ? (glu::getDataTypeMatrixNumRows(component.getVariableType()->getBasicType())) :
768*35238bceSAndroid Build Coastguard Worker (glu::getDataTypeMatrixNumColumns(component.getVariableType()->getBasicType()));
769*35238bceSAndroid Build Coastguard Worker const int majorSize =
770*35238bceSAndroid Build Coastguard Worker numMajorElements * getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType()));
771*35238bceSAndroid Build Coastguard Worker
772*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting greater or equal to "
773*35238bceSAndroid Build Coastguard Worker << majorSize << tcu::TestLog::EndMessage;
774*35238bceSAndroid Build Coastguard Worker
775*35238bceSAndroid Build Coastguard Worker if (propValue < majorSize)
776*35238bceSAndroid Build Coastguard Worker {
777*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
778*35238bceSAndroid Build Coastguard Worker setError("resource matrix stride invalid");
779*35238bceSAndroid Build Coastguard Worker }
780*35238bceSAndroid Build Coastguard Worker }
781*35238bceSAndroid Build Coastguard Worker else
782*35238bceSAndroid Build Coastguard Worker {
783*35238bceSAndroid Build Coastguard Worker const int matrixStride =
784*35238bceSAndroid Build Coastguard Worker (!isBufferBlock && !glu::isDataTypeAtomicCounter(component.getVariableType()->getBasicType())) ? (-1) : (0);
785*35238bceSAndroid Build Coastguard Worker
786*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting " << matrixStride
787*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
788*35238bceSAndroid Build Coastguard Worker
789*35238bceSAndroid Build Coastguard Worker if (matrixStride != propValue)
790*35238bceSAndroid Build Coastguard Worker {
791*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
792*35238bceSAndroid Build Coastguard Worker setError("resource matrix stride invalid");
793*35238bceSAndroid Build Coastguard Worker }
794*35238bceSAndroid Build Coastguard Worker }
795*35238bceSAndroid Build Coastguard Worker }
796*35238bceSAndroid Build Coastguard Worker
797*35238bceSAndroid Build Coastguard Worker class AtomicCounterBufferIndexVerifier : public SingleVariableValidator
798*35238bceSAndroid Build Coastguard Worker {
799*35238bceSAndroid Build Coastguard Worker public:
800*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferIndexVerifier(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
801*35238bceSAndroid Build Coastguard Worker
802*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
803*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
804*35238bceSAndroid Build Coastguard Worker };
805*35238bceSAndroid Build Coastguard Worker
AtomicCounterBufferIndexVerifier(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)806*35238bceSAndroid Build Coastguard Worker AtomicCounterBufferIndexVerifier::AtomicCounterBufferIndexVerifier(Context &context, glw::GLuint programID,
807*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
808*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX, programID, filter, DE_NULL)
809*35238bceSAndroid Build Coastguard Worker {
810*35238bceSAndroid Build Coastguard Worker }
811*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const812*35238bceSAndroid Build Coastguard Worker void AtomicCounterBufferIndexVerifier::validateSingleVariable(const std::vector<VariablePathComponent> &path,
813*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
814*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
815*35238bceSAndroid Build Coastguard Worker {
816*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
817*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
818*35238bceSAndroid Build Coastguard Worker
819*35238bceSAndroid Build Coastguard Worker if (!glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType()))
820*35238bceSAndroid Build Coastguard Worker {
821*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting -1"
822*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
823*35238bceSAndroid Build Coastguard Worker
824*35238bceSAndroid Build Coastguard Worker if (propValue != -1)
825*35238bceSAndroid Build Coastguard Worker {
826*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
827*35238bceSAndroid Build Coastguard Worker setError("resource atomic counter buffer index invalid");
828*35238bceSAndroid Build Coastguard Worker }
829*35238bceSAndroid Build Coastguard Worker }
830*35238bceSAndroid Build Coastguard Worker else
831*35238bceSAndroid Build Coastguard Worker {
832*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting a valid index"
833*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
834*35238bceSAndroid Build Coastguard Worker
835*35238bceSAndroid Build Coastguard Worker if (propValue == -1)
836*35238bceSAndroid Build Coastguard Worker {
837*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
838*35238bceSAndroid Build Coastguard Worker setError("resource atomic counter buffer index invalid");
839*35238bceSAndroid Build Coastguard Worker }
840*35238bceSAndroid Build Coastguard Worker else
841*35238bceSAndroid Build Coastguard Worker {
842*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderContext.getFunctions();
843*35238bceSAndroid Build Coastguard Worker glw::GLint numActiveResources = 0;
844*35238bceSAndroid Build Coastguard Worker
845*35238bceSAndroid Build Coastguard Worker gl.getProgramInterfaceiv(m_programID, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
846*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(),
847*35238bceSAndroid Build Coastguard Worker "getProgramInterfaceiv(..., GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, ...)");
848*35238bceSAndroid Build Coastguard Worker
849*35238bceSAndroid Build Coastguard Worker if (propValue >= numActiveResources)
850*35238bceSAndroid Build Coastguard Worker {
851*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue
852*35238bceSAndroid Build Coastguard Worker << ", GL_ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
853*35238bceSAndroid Build Coastguard Worker setError("resource atomic counter buffer index invalid");
854*35238bceSAndroid Build Coastguard Worker }
855*35238bceSAndroid Build Coastguard Worker }
856*35238bceSAndroid Build Coastguard Worker }
857*35238bceSAndroid Build Coastguard Worker }
858*35238bceSAndroid Build Coastguard Worker
859*35238bceSAndroid Build Coastguard Worker class LocationValidator : public SingleVariableValidator
860*35238bceSAndroid Build Coastguard Worker {
861*35238bceSAndroid Build Coastguard Worker public:
862*35238bceSAndroid Build Coastguard Worker LocationValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
863*35238bceSAndroid Build Coastguard Worker
864*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
865*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
866*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
867*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
868*35238bceSAndroid Build Coastguard Worker };
869*35238bceSAndroid Build Coastguard Worker
LocationValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)870*35238bceSAndroid Build Coastguard Worker LocationValidator::LocationValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
871*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_LOCATION, programID, filter, DE_NULL)
872*35238bceSAndroid Build Coastguard Worker {
873*35238bceSAndroid Build Coastguard Worker }
874*35238bceSAndroid Build Coastguard Worker
getVariableLocationLength(const glu::VarType & type)875*35238bceSAndroid Build Coastguard Worker static int getVariableLocationLength(const glu::VarType &type)
876*35238bceSAndroid Build Coastguard Worker {
877*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
878*35238bceSAndroid Build Coastguard Worker {
879*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeMatrix(type.getBasicType()))
880*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeMatrixNumColumns(type.getBasicType());
881*35238bceSAndroid Build Coastguard Worker else
882*35238bceSAndroid Build Coastguard Worker return 1;
883*35238bceSAndroid Build Coastguard Worker }
884*35238bceSAndroid Build Coastguard Worker else if (type.isStructType())
885*35238bceSAndroid Build Coastguard Worker {
886*35238bceSAndroid Build Coastguard Worker int size = 0;
887*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
888*35238bceSAndroid Build Coastguard Worker size += getVariableLocationLength(type.getStructPtr()->getMember(ndx).getType());
889*35238bceSAndroid Build Coastguard Worker return size;
890*35238bceSAndroid Build Coastguard Worker }
891*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
892*35238bceSAndroid Build Coastguard Worker return type.getArraySize() * getVariableLocationLength(type.getElementType());
893*35238bceSAndroid Build Coastguard Worker else
894*35238bceSAndroid Build Coastguard Worker {
895*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
896*35238bceSAndroid Build Coastguard Worker return 0;
897*35238bceSAndroid Build Coastguard Worker }
898*35238bceSAndroid Build Coastguard Worker }
899*35238bceSAndroid Build Coastguard Worker
getIOSubVariableLocation(const std::vector<VariablePathComponent> & path,int startNdx,int currentLocation)900*35238bceSAndroid Build Coastguard Worker static int getIOSubVariableLocation(const std::vector<VariablePathComponent> &path, int startNdx, int currentLocation)
901*35238bceSAndroid Build Coastguard Worker {
902*35238bceSAndroid Build Coastguard Worker if (currentLocation == -1)
903*35238bceSAndroid Build Coastguard Worker return -1;
904*35238bceSAndroid Build Coastguard Worker
905*35238bceSAndroid Build Coastguard Worker if (path[startNdx].getVariableType()->isBasicType())
906*35238bceSAndroid Build Coastguard Worker return currentLocation;
907*35238bceSAndroid Build Coastguard Worker else if (path[startNdx].getVariableType()->isArrayType())
908*35238bceSAndroid Build Coastguard Worker return getIOSubVariableLocation(path, startNdx + 1, currentLocation);
909*35238bceSAndroid Build Coastguard Worker else if (path[startNdx].getVariableType()->isStructType())
910*35238bceSAndroid Build Coastguard Worker {
911*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < path[startNdx].getVariableType()->getStructPtr()->getNumMembers(); ++ndx)
912*35238bceSAndroid Build Coastguard Worker {
913*35238bceSAndroid Build Coastguard Worker if (&path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType() ==
914*35238bceSAndroid Build Coastguard Worker path[startNdx + 1].getVariableType())
915*35238bceSAndroid Build Coastguard Worker return getIOSubVariableLocation(path, startNdx + 1, currentLocation);
916*35238bceSAndroid Build Coastguard Worker
917*35238bceSAndroid Build Coastguard Worker if (currentLocation != -1)
918*35238bceSAndroid Build Coastguard Worker currentLocation += getVariableLocationLength(
919*35238bceSAndroid Build Coastguard Worker path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType());
920*35238bceSAndroid Build Coastguard Worker }
921*35238bceSAndroid Build Coastguard Worker
922*35238bceSAndroid Build Coastguard Worker // could not find member, never happens
923*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
924*35238bceSAndroid Build Coastguard Worker return -1;
925*35238bceSAndroid Build Coastguard Worker }
926*35238bceSAndroid Build Coastguard Worker else
927*35238bceSAndroid Build Coastguard Worker {
928*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
929*35238bceSAndroid Build Coastguard Worker return -1;
930*35238bceSAndroid Build Coastguard Worker }
931*35238bceSAndroid Build Coastguard Worker }
932*35238bceSAndroid Build Coastguard Worker
getIOBlockVariableLocation(const std::vector<VariablePathComponent> & path)933*35238bceSAndroid Build Coastguard Worker static int getIOBlockVariableLocation(const std::vector<VariablePathComponent> &path)
934*35238bceSAndroid Build Coastguard Worker {
935*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock *block = path.front().getInterfaceBlock();
936*35238bceSAndroid Build Coastguard Worker int currentLocation = block->layout.location;
937*35238bceSAndroid Build Coastguard Worker
938*35238bceSAndroid Build Coastguard Worker // Find the block member
939*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < (int)block->variables.size(); ++memberNdx)
940*35238bceSAndroid Build Coastguard Worker {
941*35238bceSAndroid Build Coastguard Worker if (block->variables[memberNdx].layout.location != -1)
942*35238bceSAndroid Build Coastguard Worker currentLocation = block->variables[memberNdx].layout.location;
943*35238bceSAndroid Build Coastguard Worker
944*35238bceSAndroid Build Coastguard Worker if (&block->variables[memberNdx] == path[1].getDeclaration())
945*35238bceSAndroid Build Coastguard Worker break;
946*35238bceSAndroid Build Coastguard Worker
947*35238bceSAndroid Build Coastguard Worker // unspecified + unspecified = unspecified
948*35238bceSAndroid Build Coastguard Worker if (currentLocation != -1)
949*35238bceSAndroid Build Coastguard Worker currentLocation += getVariableLocationLength(block->variables[memberNdx].varType);
950*35238bceSAndroid Build Coastguard Worker }
951*35238bceSAndroid Build Coastguard Worker
952*35238bceSAndroid Build Coastguard Worker // Find subtype location in the complex type
953*35238bceSAndroid Build Coastguard Worker return getIOSubVariableLocation(path, 2, currentLocation);
954*35238bceSAndroid Build Coastguard Worker }
955*35238bceSAndroid Build Coastguard Worker
getExplicitLocationFromPath(const std::vector<VariablePathComponent> & path)956*35238bceSAndroid Build Coastguard Worker static int getExplicitLocationFromPath(const std::vector<VariablePathComponent> &path)
957*35238bceSAndroid Build Coastguard Worker {
958*35238bceSAndroid Build Coastguard Worker const glu::VariableDeclaration *varDecl =
959*35238bceSAndroid Build Coastguard Worker (path[0].isInterfaceBlock()) ? (path[1].getDeclaration()) : (path[0].getDeclaration());
960*35238bceSAndroid Build Coastguard Worker
961*35238bceSAndroid Build Coastguard Worker if (path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM)
962*35238bceSAndroid Build Coastguard Worker {
963*35238bceSAndroid Build Coastguard Worker // inside uniform block
964*35238bceSAndroid Build Coastguard Worker return -1;
965*35238bceSAndroid Build Coastguard Worker }
966*35238bceSAndroid Build Coastguard Worker else if (path.front().isInterfaceBlock() && (path.front().getInterfaceBlock()->storage == glu::STORAGE_IN ||
967*35238bceSAndroid Build Coastguard Worker path.front().getInterfaceBlock()->storage == glu::STORAGE_OUT ||
968*35238bceSAndroid Build Coastguard Worker path.front().getInterfaceBlock()->storage == glu::STORAGE_PATCH_IN ||
969*35238bceSAndroid Build Coastguard Worker path.front().getInterfaceBlock()->storage == glu::STORAGE_PATCH_OUT))
970*35238bceSAndroid Build Coastguard Worker {
971*35238bceSAndroid Build Coastguard Worker // inside ioblock
972*35238bceSAndroid Build Coastguard Worker return getIOBlockVariableLocation(path);
973*35238bceSAndroid Build Coastguard Worker }
974*35238bceSAndroid Build Coastguard Worker else if (varDecl->storage == glu::STORAGE_UNIFORM)
975*35238bceSAndroid Build Coastguard Worker {
976*35238bceSAndroid Build Coastguard Worker // default block uniform
977*35238bceSAndroid Build Coastguard Worker return varDecl->layout.location;
978*35238bceSAndroid Build Coastguard Worker }
979*35238bceSAndroid Build Coastguard Worker else if (varDecl->storage == glu::STORAGE_IN || varDecl->storage == glu::STORAGE_OUT ||
980*35238bceSAndroid Build Coastguard Worker varDecl->storage == glu::STORAGE_PATCH_IN || varDecl->storage == glu::STORAGE_PATCH_OUT)
981*35238bceSAndroid Build Coastguard Worker {
982*35238bceSAndroid Build Coastguard Worker // default block input/output
983*35238bceSAndroid Build Coastguard Worker return getIOSubVariableLocation(path, 1, varDecl->layout.location);
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker else
986*35238bceSAndroid Build Coastguard Worker {
987*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
988*35238bceSAndroid Build Coastguard Worker return -1;
989*35238bceSAndroid Build Coastguard Worker }
990*35238bceSAndroid Build Coastguard Worker }
991*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const992*35238bceSAndroid Build Coastguard Worker void LocationValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
993*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
994*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
995*35238bceSAndroid Build Coastguard Worker {
996*35238bceSAndroid Build Coastguard Worker const bool isAtomicCounterUniform = glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType());
997*35238bceSAndroid Build Coastguard Worker const bool isUniformBlockVariable =
998*35238bceSAndroid Build Coastguard Worker path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM;
999*35238bceSAndroid Build Coastguard Worker const bool isVertexShader = m_filter.getShaderTypeBits() == (1u << glu::SHADERTYPE_VERTEX);
1000*35238bceSAndroid Build Coastguard Worker const bool isFragmentShader = m_filter.getShaderTypeBits() == (1u << glu::SHADERTYPE_FRAGMENT);
1001*35238bceSAndroid Build Coastguard Worker const glu::Storage storage = (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage) :
1002*35238bceSAndroid Build Coastguard Worker (path.front().getDeclaration()->storage);
1003*35238bceSAndroid Build Coastguard Worker const bool isInputVariable = (storage == glu::STORAGE_IN || storage == glu::STORAGE_PATCH_IN);
1004*35238bceSAndroid Build Coastguard Worker const bool isOutputVariable = (storage == glu::STORAGE_OUT || storage == glu::STORAGE_PATCH_OUT);
1005*35238bceSAndroid Build Coastguard Worker const int explicitLayoutLocation = getExplicitLocationFromPath(path);
1006*35238bceSAndroid Build Coastguard Worker
1007*35238bceSAndroid Build Coastguard Worker bool expectLocation;
1008*35238bceSAndroid Build Coastguard Worker std::string reasonStr;
1009*35238bceSAndroid Build Coastguard Worker
1010*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1011*35238bceSAndroid Build Coastguard Worker
1012*35238bceSAndroid Build Coastguard Worker if (isAtomicCounterUniform)
1013*35238bceSAndroid Build Coastguard Worker {
1014*35238bceSAndroid Build Coastguard Worker expectLocation = false;
1015*35238bceSAndroid Build Coastguard Worker reasonStr = "Atomic counter uniforms have effective location of -1";
1016*35238bceSAndroid Build Coastguard Worker }
1017*35238bceSAndroid Build Coastguard Worker else if (isUniformBlockVariable)
1018*35238bceSAndroid Build Coastguard Worker {
1019*35238bceSAndroid Build Coastguard Worker expectLocation = false;
1020*35238bceSAndroid Build Coastguard Worker reasonStr = "Uniform block variables have effective location of -1";
1021*35238bceSAndroid Build Coastguard Worker }
1022*35238bceSAndroid Build Coastguard Worker else if (isInputVariable && !isVertexShader && explicitLayoutLocation == -1)
1023*35238bceSAndroid Build Coastguard Worker {
1024*35238bceSAndroid Build Coastguard Worker expectLocation = false;
1025*35238bceSAndroid Build Coastguard Worker reasonStr = "Inputs (except for vertex shader inputs) not declared with a location layout qualifier have "
1026*35238bceSAndroid Build Coastguard Worker "effective location of -1";
1027*35238bceSAndroid Build Coastguard Worker }
1028*35238bceSAndroid Build Coastguard Worker else if (isOutputVariable && !isFragmentShader && explicitLayoutLocation == -1)
1029*35238bceSAndroid Build Coastguard Worker {
1030*35238bceSAndroid Build Coastguard Worker expectLocation = false;
1031*35238bceSAndroid Build Coastguard Worker reasonStr = "Outputs (except for fragment shader outputs) not declared with a location layout qualifier have "
1032*35238bceSAndroid Build Coastguard Worker "effective location of -1";
1033*35238bceSAndroid Build Coastguard Worker }
1034*35238bceSAndroid Build Coastguard Worker else
1035*35238bceSAndroid Build Coastguard Worker {
1036*35238bceSAndroid Build Coastguard Worker expectLocation = true;
1037*35238bceSAndroid Build Coastguard Worker }
1038*35238bceSAndroid Build Coastguard Worker
1039*35238bceSAndroid Build Coastguard Worker if (!expectLocation)
1040*35238bceSAndroid Build Coastguard Worker {
1041*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform location, expecting -1. (" << reasonStr << ")"
1042*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1043*35238bceSAndroid Build Coastguard Worker
1044*35238bceSAndroid Build Coastguard Worker if (propValue != -1)
1045*35238bceSAndroid Build Coastguard Worker {
1046*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1047*35238bceSAndroid Build Coastguard Worker setError("resource location invalid");
1048*35238bceSAndroid Build Coastguard Worker }
1049*35238bceSAndroid Build Coastguard Worker }
1050*35238bceSAndroid Build Coastguard Worker else
1051*35238bceSAndroid Build Coastguard Worker {
1052*35238bceSAndroid Build Coastguard Worker bool locationOk;
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker if (explicitLayoutLocation == -1)
1055*35238bceSAndroid Build Coastguard Worker {
1056*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting a valid location"
1057*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1058*35238bceSAndroid Build Coastguard Worker locationOk = (propValue != -1);
1059*35238bceSAndroid Build Coastguard Worker }
1060*35238bceSAndroid Build Coastguard Worker else
1061*35238bceSAndroid Build Coastguard Worker {
1062*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting " << explicitLayoutLocation
1063*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1064*35238bceSAndroid Build Coastguard Worker locationOk = (propValue == explicitLayoutLocation);
1065*35238bceSAndroid Build Coastguard Worker }
1066*35238bceSAndroid Build Coastguard Worker
1067*35238bceSAndroid Build Coastguard Worker if (!locationOk)
1068*35238bceSAndroid Build Coastguard Worker {
1069*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1070*35238bceSAndroid Build Coastguard Worker setError("resource location invalid");
1071*35238bceSAndroid Build Coastguard Worker }
1072*35238bceSAndroid Build Coastguard Worker else
1073*35238bceSAndroid Build Coastguard Worker {
1074*35238bceSAndroid Build Coastguard Worker const VariablePathComponent nullComponent;
1075*35238bceSAndroid Build Coastguard Worker const VariablePathComponent &enclosingcomponent =
1076*35238bceSAndroid Build Coastguard Worker (path.size() > 1) ? (path[path.size() - 2]) : (nullComponent);
1077*35238bceSAndroid Build Coastguard Worker const bool isArray =
1078*35238bceSAndroid Build Coastguard Worker enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();
1079*35238bceSAndroid Build Coastguard Worker
1080*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderContext.getFunctions();
1081*35238bceSAndroid Build Coastguard Worker const glw::GLenum interface = getProgramDefaultBlockInterfaceFromStorage(storage);
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1084*35238bceSAndroid Build Coastguard Worker << "Comparing location to the values returned by GetProgramResourceLocation"
1085*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1086*35238bceSAndroid Build Coastguard Worker
1087*35238bceSAndroid Build Coastguard Worker // Test all bottom-level array elements
1088*35238bceSAndroid Build Coastguard Worker if (isArray)
1089*35238bceSAndroid Build Coastguard Worker {
1090*35238bceSAndroid Build Coastguard Worker const std::string arrayResourceName =
1091*35238bceSAndroid Build Coastguard Worker (implementationName.size() > 3) ? (implementationName.substr(0, implementationName.size() - 3)) :
1092*35238bceSAndroid Build Coastguard Worker (""); // chop "[0]"
1093*35238bceSAndroid Build Coastguard Worker
1094*35238bceSAndroid Build Coastguard Worker for (int arrayElementNdx = 0; arrayElementNdx < enclosingcomponent.getVariableType()->getArraySize();
1095*35238bceSAndroid Build Coastguard Worker ++arrayElementNdx)
1096*35238bceSAndroid Build Coastguard Worker {
1097*35238bceSAndroid Build Coastguard Worker const std::string elementResourceName =
1098*35238bceSAndroid Build Coastguard Worker arrayResourceName + "[" + de::toString(arrayElementNdx) + "]";
1099*35238bceSAndroid Build Coastguard Worker const glw::GLint location =
1100*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceLocation(m_programID, interface, elementResourceName.c_str());
1101*35238bceSAndroid Build Coastguard Worker
1102*35238bceSAndroid Build Coastguard Worker if (location != propValue + arrayElementNdx)
1103*35238bceSAndroid Build Coastguard Worker {
1104*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1105*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << "\tError, getProgramResourceLocation (resource=\""
1106*35238bceSAndroid Build Coastguard Worker << elementResourceName << "\") returned location " << location << ", expected "
1107*35238bceSAndroid Build Coastguard Worker << (propValue + arrayElementNdx) << tcu::TestLog::EndMessage;
1108*35238bceSAndroid Build Coastguard Worker setError("resource location invalid");
1109*35238bceSAndroid Build Coastguard Worker }
1110*35238bceSAndroid Build Coastguard Worker else
1111*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tLocation of \"" << elementResourceName
1112*35238bceSAndroid Build Coastguard Worker << "\":\t" << location << tcu::TestLog::EndMessage;
1113*35238bceSAndroid Build Coastguard Worker }
1114*35238bceSAndroid Build Coastguard Worker }
1115*35238bceSAndroid Build Coastguard Worker else
1116*35238bceSAndroid Build Coastguard Worker {
1117*35238bceSAndroid Build Coastguard Worker const glw::GLint location =
1118*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceLocation(m_programID, interface, implementationName.c_str());
1119*35238bceSAndroid Build Coastguard Worker
1120*35238bceSAndroid Build Coastguard Worker if (location != propValue)
1121*35238bceSAndroid Build Coastguard Worker {
1122*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1123*35238bceSAndroid Build Coastguard Worker << "\tError, getProgramResourceLocation returned location " << location
1124*35238bceSAndroid Build Coastguard Worker << ", expected " << propValue << tcu::TestLog::EndMessage;
1125*35238bceSAndroid Build Coastguard Worker setError("resource location invalid");
1126*35238bceSAndroid Build Coastguard Worker }
1127*35238bceSAndroid Build Coastguard Worker }
1128*35238bceSAndroid Build Coastguard Worker }
1129*35238bceSAndroid Build Coastguard Worker }
1130*35238bceSAndroid Build Coastguard Worker }
1131*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1132*35238bceSAndroid Build Coastguard Worker void LocationValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1133*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1134*35238bceSAndroid Build Coastguard Worker {
1135*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1136*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1137*35238bceSAndroid Build Coastguard Worker
1138*35238bceSAndroid Build Coastguard Worker // built-ins have no location
1139*35238bceSAndroid Build Coastguard Worker
1140*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting -1" << tcu::TestLog::EndMessage;
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker if (propValue != -1)
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1145*35238bceSAndroid Build Coastguard Worker setError("resource location invalid");
1146*35238bceSAndroid Build Coastguard Worker }
1147*35238bceSAndroid Build Coastguard Worker }
1148*35238bceSAndroid Build Coastguard Worker
1149*35238bceSAndroid Build Coastguard Worker class VariableNameLengthValidator : public SingleVariableValidator
1150*35238bceSAndroid Build Coastguard Worker {
1151*35238bceSAndroid Build Coastguard Worker public:
1152*35238bceSAndroid Build Coastguard Worker VariableNameLengthValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
1153*35238bceSAndroid Build Coastguard Worker
1154*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1155*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1156*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1157*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1158*35238bceSAndroid Build Coastguard Worker void validateNameLength(const std::string &implementationName, glw::GLint propValue) const;
1159*35238bceSAndroid Build Coastguard Worker };
1160*35238bceSAndroid Build Coastguard Worker
VariableNameLengthValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)1161*35238bceSAndroid Build Coastguard Worker VariableNameLengthValidator::VariableNameLengthValidator(Context &context, glw::GLuint programID,
1162*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1163*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter, DE_NULL)
1164*35238bceSAndroid Build Coastguard Worker {
1165*35238bceSAndroid Build Coastguard Worker }
1166*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1167*35238bceSAndroid Build Coastguard Worker void VariableNameLengthValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1168*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1169*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1170*35238bceSAndroid Build Coastguard Worker {
1171*35238bceSAndroid Build Coastguard Worker DE_UNREF(path);
1172*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1173*35238bceSAndroid Build Coastguard Worker validateNameLength(implementationName, propValue);
1174*35238bceSAndroid Build Coastguard Worker }
1175*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1176*35238bceSAndroid Build Coastguard Worker void VariableNameLengthValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1177*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1178*35238bceSAndroid Build Coastguard Worker {
1179*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1180*35238bceSAndroid Build Coastguard Worker validateNameLength(implementationName, propValue);
1181*35238bceSAndroid Build Coastguard Worker }
1182*35238bceSAndroid Build Coastguard Worker
validateNameLength(const std::string & implementationName,glw::GLint propValue) const1183*35238bceSAndroid Build Coastguard Worker void VariableNameLengthValidator::validateNameLength(const std::string &implementationName, glw::GLint propValue) const
1184*35238bceSAndroid Build Coastguard Worker {
1185*35238bceSAndroid Build Coastguard Worker const int expected = (int)implementationName.length() + 1; // includes null byte
1186*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " ("
1187*35238bceSAndroid Build Coastguard Worker << (int)implementationName.length() << " for \"" << implementationName
1188*35238bceSAndroid Build Coastguard Worker << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;
1189*35238bceSAndroid Build Coastguard Worker
1190*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1191*35238bceSAndroid Build Coastguard Worker {
1192*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue
1193*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1194*35238bceSAndroid Build Coastguard Worker setError("name length invalid");
1195*35238bceSAndroid Build Coastguard Worker }
1196*35238bceSAndroid Build Coastguard Worker }
1197*35238bceSAndroid Build Coastguard Worker
1198*35238bceSAndroid Build Coastguard Worker class OffsetValidator : public SingleVariableValidator
1199*35238bceSAndroid Build Coastguard Worker {
1200*35238bceSAndroid Build Coastguard Worker public:
1201*35238bceSAndroid Build Coastguard Worker OffsetValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
1202*35238bceSAndroid Build Coastguard Worker
1203*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1204*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1205*35238bceSAndroid Build Coastguard Worker };
1206*35238bceSAndroid Build Coastguard Worker
OffsetValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)1207*35238bceSAndroid Build Coastguard Worker OffsetValidator::OffsetValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
1208*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_OFFSET, programID, filter, DE_NULL)
1209*35238bceSAndroid Build Coastguard Worker {
1210*35238bceSAndroid Build Coastguard Worker }
1211*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1212*35238bceSAndroid Build Coastguard Worker void OffsetValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1213*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1214*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1215*35238bceSAndroid Build Coastguard Worker {
1216*35238bceSAndroid Build Coastguard Worker const bool isAtomicCounterUniform = glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType());
1217*35238bceSAndroid Build Coastguard Worker const bool isBufferBackedBlockStorage =
1218*35238bceSAndroid Build Coastguard Worker path.front().isInterfaceBlock() &&
1219*35238bceSAndroid Build Coastguard Worker isBufferBackedInterfaceBlockStorage(path.front().getInterfaceBlock()->storage);
1220*35238bceSAndroid Build Coastguard Worker
1221*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1222*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1223*35238bceSAndroid Build Coastguard Worker
1224*35238bceSAndroid Build Coastguard Worker if (!isAtomicCounterUniform && !isBufferBackedBlockStorage)
1225*35238bceSAndroid Build Coastguard Worker {
1226*35238bceSAndroid Build Coastguard Worker // Not buffer backed
1227*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting -1" << tcu::TestLog::EndMessage;
1228*35238bceSAndroid Build Coastguard Worker
1229*35238bceSAndroid Build Coastguard Worker if (propValue != -1)
1230*35238bceSAndroid Build Coastguard Worker {
1231*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue
1232*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1233*35238bceSAndroid Build Coastguard Worker setError("offset invalid");
1234*35238bceSAndroid Build Coastguard Worker }
1235*35238bceSAndroid Build Coastguard Worker }
1236*35238bceSAndroid Build Coastguard Worker else
1237*35238bceSAndroid Build Coastguard Worker {
1238*35238bceSAndroid Build Coastguard Worker // Expect a valid offset
1239*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting a valid offset"
1240*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1241*35238bceSAndroid Build Coastguard Worker
1242*35238bceSAndroid Build Coastguard Worker if (propValue < 0)
1243*35238bceSAndroid Build Coastguard Worker {
1244*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue
1245*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1246*35238bceSAndroid Build Coastguard Worker setError("offset invalid");
1247*35238bceSAndroid Build Coastguard Worker }
1248*35238bceSAndroid Build Coastguard Worker }
1249*35238bceSAndroid Build Coastguard Worker }
1250*35238bceSAndroid Build Coastguard Worker
1251*35238bceSAndroid Build Coastguard Worker class VariableReferencedByShaderValidator : public PropValidator
1252*35238bceSAndroid Build Coastguard Worker {
1253*35238bceSAndroid Build Coastguard Worker public:
1254*35238bceSAndroid Build Coastguard Worker VariableReferencedByShaderValidator(Context &context, glu::ShaderType shaderType,
1255*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &searchFilter);
1256*35238bceSAndroid Build Coastguard Worker
1257*35238bceSAndroid Build Coastguard Worker std::string getHumanReadablePropertyString(glw::GLint propVal) const;
1258*35238bceSAndroid Build Coastguard Worker void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource, glw::GLint propValue,
1259*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1260*35238bceSAndroid Build Coastguard Worker
1261*35238bceSAndroid Build Coastguard Worker private:
1262*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter m_filter;
1263*35238bceSAndroid Build Coastguard Worker const glu::ShaderType m_shaderType;
1264*35238bceSAndroid Build Coastguard Worker };
1265*35238bceSAndroid Build Coastguard Worker
VariableReferencedByShaderValidator(Context & context,glu::ShaderType shaderType,const VariableSearchFilter & searchFilter)1266*35238bceSAndroid Build Coastguard Worker VariableReferencedByShaderValidator::VariableReferencedByShaderValidator(Context &context, glu::ShaderType shaderType,
1267*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &searchFilter)
1268*35238bceSAndroid Build Coastguard Worker : PropValidator(context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER, getRequiredExtensionForStage(shaderType))
1269*35238bceSAndroid Build Coastguard Worker , m_filter(VariableSearchFilter::logicalAnd(VariableSearchFilter::createShaderTypeFilter(shaderType), searchFilter))
1270*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
1271*35238bceSAndroid Build Coastguard Worker {
1272*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_shaderType < glu::SHADERTYPE_LAST);
1273*35238bceSAndroid Build Coastguard Worker }
1274*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const1275*35238bceSAndroid Build Coastguard Worker std::string VariableReferencedByShaderValidator::getHumanReadablePropertyString(glw::GLint propVal) const
1276*35238bceSAndroid Build Coastguard Worker {
1277*35238bceSAndroid Build Coastguard Worker return de::toString(glu::getBooleanStr(propVal));
1278*35238bceSAndroid Build Coastguard Worker }
1279*35238bceSAndroid Build Coastguard Worker
validate(const ProgramInterfaceDefinition::Program * program,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1280*35238bceSAndroid Build Coastguard Worker void VariableReferencedByShaderValidator::validate(const ProgramInterfaceDefinition::Program *program,
1281*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1282*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1283*35238bceSAndroid Build Coastguard Worker {
1284*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1285*35238bceSAndroid Build Coastguard Worker
1286*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> unusedPath;
1287*35238bceSAndroid Build Coastguard Worker const bool referencedByShader = findProgramVariablePathByPathName(unusedPath, program, resource, m_filter);
1288*35238bceSAndroid Build Coastguard Worker
1289*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying referenced by " << glu::getShaderTypeName(m_shaderType)
1290*35238bceSAndroid Build Coastguard Worker << " shader, expecting " << ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE"))
1291*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1292*35238bceSAndroid Build Coastguard Worker
1293*35238bceSAndroid Build Coastguard Worker if (propValue != ((referencedByShader) ? (1) : (0)))
1294*35238bceSAndroid Build Coastguard Worker {
1295*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_"
1296*35238bceSAndroid Build Coastguard Worker << glu::getShaderTypeName(m_shaderType) << ", got " << propValue << tcu::TestLog::EndMessage;
1297*35238bceSAndroid Build Coastguard Worker setError("referenced_by_" + std::string(glu::getShaderTypeName(m_shaderType)) + " invalid");
1298*35238bceSAndroid Build Coastguard Worker }
1299*35238bceSAndroid Build Coastguard Worker }
1300*35238bceSAndroid Build Coastguard Worker
1301*35238bceSAndroid Build Coastguard Worker class BlockNameLengthValidator : public SingleBlockValidator
1302*35238bceSAndroid Build Coastguard Worker {
1303*35238bceSAndroid Build Coastguard Worker public:
1304*35238bceSAndroid Build Coastguard Worker BlockNameLengthValidator(Context &context, const glw::GLuint programID, const VariableSearchFilter &filter);
1305*35238bceSAndroid Build Coastguard Worker
1306*35238bceSAndroid Build Coastguard Worker void validateSingleBlock(const glu::InterfaceBlock &block, const std::vector<int> &instanceIndex,
1307*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1308*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1309*35238bceSAndroid Build Coastguard Worker };
1310*35238bceSAndroid Build Coastguard Worker
BlockNameLengthValidator(Context & context,const glw::GLuint programID,const VariableSearchFilter & filter)1311*35238bceSAndroid Build Coastguard Worker BlockNameLengthValidator::BlockNameLengthValidator(Context &context, const glw::GLuint programID,
1312*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1313*35238bceSAndroid Build Coastguard Worker : SingleBlockValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter, DE_NULL)
1314*35238bceSAndroid Build Coastguard Worker {
1315*35238bceSAndroid Build Coastguard Worker }
1316*35238bceSAndroid Build Coastguard Worker
validateSingleBlock(const glu::InterfaceBlock & block,const std::vector<int> & instanceIndex,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1317*35238bceSAndroid Build Coastguard Worker void BlockNameLengthValidator::validateSingleBlock(const glu::InterfaceBlock &block,
1318*35238bceSAndroid Build Coastguard Worker const std::vector<int> &instanceIndex, const std::string &resource,
1319*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const
1320*35238bceSAndroid Build Coastguard Worker {
1321*35238bceSAndroid Build Coastguard Worker DE_UNREF(instanceIndex);
1322*35238bceSAndroid Build Coastguard Worker DE_UNREF(block);
1323*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1324*35238bceSAndroid Build Coastguard Worker
1325*35238bceSAndroid Build Coastguard Worker const int expected = (int)implementationName.length() + 1; // includes null byte
1326*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " ("
1327*35238bceSAndroid Build Coastguard Worker << (int)implementationName.length() << " for \"" << implementationName
1328*35238bceSAndroid Build Coastguard Worker << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;
1329*35238bceSAndroid Build Coastguard Worker
1330*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1331*35238bceSAndroid Build Coastguard Worker {
1332*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue
1333*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1334*35238bceSAndroid Build Coastguard Worker setError("name length invalid");
1335*35238bceSAndroid Build Coastguard Worker }
1336*35238bceSAndroid Build Coastguard Worker }
1337*35238bceSAndroid Build Coastguard Worker
1338*35238bceSAndroid Build Coastguard Worker class BufferBindingValidator : public SingleBlockValidator
1339*35238bceSAndroid Build Coastguard Worker {
1340*35238bceSAndroid Build Coastguard Worker public:
1341*35238bceSAndroid Build Coastguard Worker BufferBindingValidator(Context &context, const glw::GLuint programID, const VariableSearchFilter &filter);
1342*35238bceSAndroid Build Coastguard Worker
1343*35238bceSAndroid Build Coastguard Worker void validateSingleBlock(const glu::InterfaceBlock &block, const std::vector<int> &instanceIndex,
1344*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1345*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1346*35238bceSAndroid Build Coastguard Worker };
1347*35238bceSAndroid Build Coastguard Worker
BufferBindingValidator(Context & context,const glw::GLuint programID,const VariableSearchFilter & filter)1348*35238bceSAndroid Build Coastguard Worker BufferBindingValidator::BufferBindingValidator(Context &context, const glw::GLuint programID,
1349*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1350*35238bceSAndroid Build Coastguard Worker : SingleBlockValidator(context, PROGRAMRESOURCEPROP_BUFFER_BINDING, programID, filter, DE_NULL)
1351*35238bceSAndroid Build Coastguard Worker {
1352*35238bceSAndroid Build Coastguard Worker }
1353*35238bceSAndroid Build Coastguard Worker
validateSingleBlock(const glu::InterfaceBlock & block,const std::vector<int> & instanceIndex,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1354*35238bceSAndroid Build Coastguard Worker void BufferBindingValidator::validateSingleBlock(const glu::InterfaceBlock &block,
1355*35238bceSAndroid Build Coastguard Worker const std::vector<int> &instanceIndex, const std::string &resource,
1356*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const
1357*35238bceSAndroid Build Coastguard Worker {
1358*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1359*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1360*35238bceSAndroid Build Coastguard Worker
1361*35238bceSAndroid Build Coastguard Worker if (block.layout.binding != -1)
1362*35238bceSAndroid Build Coastguard Worker {
1363*35238bceSAndroid Build Coastguard Worker int flatIndex = 0;
1364*35238bceSAndroid Build Coastguard Worker int dimensionSize = 1;
1365*35238bceSAndroid Build Coastguard Worker
1366*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = (int)(block.dimensions.size()) - 1; dimensionNdx >= 0; --dimensionNdx)
1367*35238bceSAndroid Build Coastguard Worker {
1368*35238bceSAndroid Build Coastguard Worker flatIndex += dimensionSize * instanceIndex[dimensionNdx];
1369*35238bceSAndroid Build Coastguard Worker dimensionSize *= block.dimensions[dimensionNdx];
1370*35238bceSAndroid Build Coastguard Worker }
1371*35238bceSAndroid Build Coastguard Worker
1372*35238bceSAndroid Build Coastguard Worker const int expected = (block.dimensions.empty()) ? (block.layout.binding) : (block.layout.binding + flatIndex);
1373*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block binding, expecting " << expected
1374*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1375*35238bceSAndroid Build Coastguard Worker
1376*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1377*35238bceSAndroid Build Coastguard Worker {
1378*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue
1379*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1380*35238bceSAndroid Build Coastguard Worker setError("buffer binding invalid");
1381*35238bceSAndroid Build Coastguard Worker }
1382*35238bceSAndroid Build Coastguard Worker }
1383*35238bceSAndroid Build Coastguard Worker else
1384*35238bceSAndroid Build Coastguard Worker {
1385*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying buffer binding, expecting a valid binding"
1386*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1387*35238bceSAndroid Build Coastguard Worker
1388*35238bceSAndroid Build Coastguard Worker if (propValue < 0)
1389*35238bceSAndroid Build Coastguard Worker {
1390*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue
1391*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1392*35238bceSAndroid Build Coastguard Worker setError("buffer binding invalid");
1393*35238bceSAndroid Build Coastguard Worker }
1394*35238bceSAndroid Build Coastguard Worker }
1395*35238bceSAndroid Build Coastguard Worker }
1396*35238bceSAndroid Build Coastguard Worker
1397*35238bceSAndroid Build Coastguard Worker class BlockReferencedByShaderValidator : public PropValidator
1398*35238bceSAndroid Build Coastguard Worker {
1399*35238bceSAndroid Build Coastguard Worker public:
1400*35238bceSAndroid Build Coastguard Worker BlockReferencedByShaderValidator(Context &context, glu::ShaderType shaderType,
1401*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &searchFilter);
1402*35238bceSAndroid Build Coastguard Worker
1403*35238bceSAndroid Build Coastguard Worker std::string getHumanReadablePropertyString(glw::GLint propVal) const;
1404*35238bceSAndroid Build Coastguard Worker void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource, glw::GLint propValue,
1405*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1406*35238bceSAndroid Build Coastguard Worker
1407*35238bceSAndroid Build Coastguard Worker private:
1408*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter m_filter;
1409*35238bceSAndroid Build Coastguard Worker const glu::ShaderType m_shaderType;
1410*35238bceSAndroid Build Coastguard Worker };
1411*35238bceSAndroid Build Coastguard Worker
BlockReferencedByShaderValidator(Context & context,glu::ShaderType shaderType,const VariableSearchFilter & searchFilter)1412*35238bceSAndroid Build Coastguard Worker BlockReferencedByShaderValidator::BlockReferencedByShaderValidator(Context &context, glu::ShaderType shaderType,
1413*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &searchFilter)
1414*35238bceSAndroid Build Coastguard Worker : PropValidator(context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER, getRequiredExtensionForStage(shaderType))
1415*35238bceSAndroid Build Coastguard Worker , m_filter(VariableSearchFilter::logicalAnd(VariableSearchFilter::createShaderTypeFilter(shaderType), searchFilter))
1416*35238bceSAndroid Build Coastguard Worker , m_shaderType(shaderType)
1417*35238bceSAndroid Build Coastguard Worker {
1418*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_shaderType < glu::SHADERTYPE_LAST);
1419*35238bceSAndroid Build Coastguard Worker }
1420*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const1421*35238bceSAndroid Build Coastguard Worker std::string BlockReferencedByShaderValidator::getHumanReadablePropertyString(glw::GLint propVal) const
1422*35238bceSAndroid Build Coastguard Worker {
1423*35238bceSAndroid Build Coastguard Worker return de::toString(glu::getBooleanStr(propVal));
1424*35238bceSAndroid Build Coastguard Worker }
1425*35238bceSAndroid Build Coastguard Worker
validate(const ProgramInterfaceDefinition::Program * program,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1426*35238bceSAndroid Build Coastguard Worker void BlockReferencedByShaderValidator::validate(const ProgramInterfaceDefinition::Program *program,
1427*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1428*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1429*35238bceSAndroid Build Coastguard Worker {
1430*35238bceSAndroid Build Coastguard Worker const std::string blockName = glu::parseVariableName(resource.c_str());
1431*35238bceSAndroid Build Coastguard Worker bool referencedByShader = false;
1432*35238bceSAndroid Build Coastguard Worker
1433*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1434*35238bceSAndroid Build Coastguard Worker
1435*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1436*35238bceSAndroid Build Coastguard Worker {
1437*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *const shader = program->getShaders()[shaderNdx];
1438*35238bceSAndroid Build Coastguard Worker if (!m_filter.matchesFilter(shader))
1439*35238bceSAndroid Build Coastguard Worker continue;
1440*35238bceSAndroid Build Coastguard Worker
1441*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
1442*35238bceSAndroid Build Coastguard Worker {
1443*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block = shader->getDefaultBlock().interfaceBlocks[blockNdx];
1444*35238bceSAndroid Build Coastguard Worker
1445*35238bceSAndroid Build Coastguard Worker if (m_filter.matchesFilter(block) && block.interfaceName == blockName)
1446*35238bceSAndroid Build Coastguard Worker referencedByShader = true;
1447*35238bceSAndroid Build Coastguard Worker }
1448*35238bceSAndroid Build Coastguard Worker }
1449*35238bceSAndroid Build Coastguard Worker
1450*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying referenced by " << glu::getShaderTypeName(m_shaderType)
1451*35238bceSAndroid Build Coastguard Worker << " shader, expecting " << ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE"))
1452*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1453*35238bceSAndroid Build Coastguard Worker
1454*35238bceSAndroid Build Coastguard Worker if (propValue != ((referencedByShader) ? (1) : (0)))
1455*35238bceSAndroid Build Coastguard Worker {
1456*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_"
1457*35238bceSAndroid Build Coastguard Worker << glu::getShaderTypeName(m_shaderType) << ", got " << propValue << tcu::TestLog::EndMessage;
1458*35238bceSAndroid Build Coastguard Worker setError("referenced_by_" + std::string(glu::getShaderTypeName(m_shaderType)) + " invalid");
1459*35238bceSAndroid Build Coastguard Worker }
1460*35238bceSAndroid Build Coastguard Worker }
1461*35238bceSAndroid Build Coastguard Worker
1462*35238bceSAndroid Build Coastguard Worker class TopLevelArraySizeValidator : public SingleVariableValidator
1463*35238bceSAndroid Build Coastguard Worker {
1464*35238bceSAndroid Build Coastguard Worker public:
1465*35238bceSAndroid Build Coastguard Worker TopLevelArraySizeValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
1466*35238bceSAndroid Build Coastguard Worker
1467*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1468*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1469*35238bceSAndroid Build Coastguard Worker };
1470*35238bceSAndroid Build Coastguard Worker
TopLevelArraySizeValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)1471*35238bceSAndroid Build Coastguard Worker TopLevelArraySizeValidator::TopLevelArraySizeValidator(Context &context, glw::GLuint programID,
1472*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1473*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE, programID, filter, DE_NULL)
1474*35238bceSAndroid Build Coastguard Worker {
1475*35238bceSAndroid Build Coastguard Worker }
1476*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1477*35238bceSAndroid Build Coastguard Worker void TopLevelArraySizeValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1478*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1479*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1480*35238bceSAndroid Build Coastguard Worker {
1481*35238bceSAndroid Build Coastguard Worker int expected;
1482*35238bceSAndroid Build Coastguard Worker std::string reason;
1483*35238bceSAndroid Build Coastguard Worker
1484*35238bceSAndroid Build Coastguard Worker DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER);
1485*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1486*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1487*35238bceSAndroid Build Coastguard Worker
1488*35238bceSAndroid Build Coastguard Worker if (!path[1].getDeclaration()->varType.isArrayType())
1489*35238bceSAndroid Build Coastguard Worker {
1490*35238bceSAndroid Build Coastguard Worker expected = 1;
1491*35238bceSAndroid Build Coastguard Worker reason = "Top-level block member is not an array";
1492*35238bceSAndroid Build Coastguard Worker }
1493*35238bceSAndroid Build Coastguard Worker else if (path[1].getDeclaration()->varType.getElementType().isBasicType())
1494*35238bceSAndroid Build Coastguard Worker {
1495*35238bceSAndroid Build Coastguard Worker expected = 1;
1496*35238bceSAndroid Build Coastguard Worker reason = "Top-level block member is not an array of an aggregate type";
1497*35238bceSAndroid Build Coastguard Worker }
1498*35238bceSAndroid Build Coastguard Worker else if (path[1].getDeclaration()->varType.getArraySize() == glu::VarType::UNSIZED_ARRAY)
1499*35238bceSAndroid Build Coastguard Worker {
1500*35238bceSAndroid Build Coastguard Worker expected = 0;
1501*35238bceSAndroid Build Coastguard Worker reason = "Top-level block member is an unsized top-level array";
1502*35238bceSAndroid Build Coastguard Worker }
1503*35238bceSAndroid Build Coastguard Worker else
1504*35238bceSAndroid Build Coastguard Worker {
1505*35238bceSAndroid Build Coastguard Worker expected = path[1].getDeclaration()->varType.getArraySize();
1506*35238bceSAndroid Build Coastguard Worker reason = "Top-level block member is a sized top-level array";
1507*35238bceSAndroid Build Coastguard Worker }
1508*35238bceSAndroid Build Coastguard Worker
1509*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array size, expecting " << expected << ". ("
1510*35238bceSAndroid Build Coastguard Worker << reason << ")." << tcu::TestLog::EndMessage;
1511*35238bceSAndroid Build Coastguard Worker
1512*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1513*35238bceSAndroid Build Coastguard Worker {
1514*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array size, got " << propValue
1515*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1516*35238bceSAndroid Build Coastguard Worker setError("top level array size invalid");
1517*35238bceSAndroid Build Coastguard Worker }
1518*35238bceSAndroid Build Coastguard Worker }
1519*35238bceSAndroid Build Coastguard Worker
1520*35238bceSAndroid Build Coastguard Worker class TopLevelArrayStrideValidator : public SingleVariableValidator
1521*35238bceSAndroid Build Coastguard Worker {
1522*35238bceSAndroid Build Coastguard Worker public:
1523*35238bceSAndroid Build Coastguard Worker TopLevelArrayStrideValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
1524*35238bceSAndroid Build Coastguard Worker
1525*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1526*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1527*35238bceSAndroid Build Coastguard Worker };
1528*35238bceSAndroid Build Coastguard Worker
TopLevelArrayStrideValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)1529*35238bceSAndroid Build Coastguard Worker TopLevelArrayStrideValidator::TopLevelArrayStrideValidator(Context &context, glw::GLuint programID,
1530*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1531*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE, programID, filter, DE_NULL)
1532*35238bceSAndroid Build Coastguard Worker {
1533*35238bceSAndroid Build Coastguard Worker }
1534*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1535*35238bceSAndroid Build Coastguard Worker void TopLevelArrayStrideValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1536*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1537*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1538*35238bceSAndroid Build Coastguard Worker {
1539*35238bceSAndroid Build Coastguard Worker DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER);
1540*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1541*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1542*35238bceSAndroid Build Coastguard Worker
1543*35238bceSAndroid Build Coastguard Worker if (!path[1].getDeclaration()->varType.isArrayType())
1544*35238bceSAndroid Build Coastguard Worker {
1545*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1546*35238bceSAndroid Build Coastguard Worker << "Verifying top level array stride, expecting 0. (Top-level block member is not an array)."
1547*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1548*35238bceSAndroid Build Coastguard Worker
1549*35238bceSAndroid Build Coastguard Worker if (propValue != 0)
1550*35238bceSAndroid Build Coastguard Worker {
1551*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue
1552*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1553*35238bceSAndroid Build Coastguard Worker setError("top level array stride invalid");
1554*35238bceSAndroid Build Coastguard Worker }
1555*35238bceSAndroid Build Coastguard Worker }
1556*35238bceSAndroid Build Coastguard Worker else if (path[1].getDeclaration()->varType.getElementType().isBasicType())
1557*35238bceSAndroid Build Coastguard Worker {
1558*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1559*35238bceSAndroid Build Coastguard Worker << "Verifying top level array stride, expecting 0. (Top-level block member is not an array "
1560*35238bceSAndroid Build Coastguard Worker "of an aggregate type)."
1561*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1562*35238bceSAndroid Build Coastguard Worker
1563*35238bceSAndroid Build Coastguard Worker if (propValue != 0)
1564*35238bceSAndroid Build Coastguard Worker {
1565*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue
1566*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1567*35238bceSAndroid Build Coastguard Worker setError("top level array stride invalid");
1568*35238bceSAndroid Build Coastguard Worker }
1569*35238bceSAndroid Build Coastguard Worker }
1570*35238bceSAndroid Build Coastguard Worker else
1571*35238bceSAndroid Build Coastguard Worker {
1572*35238bceSAndroid Build Coastguard Worker const int minimumStride = getVarTypeSize(path[1].getDeclaration()->varType.getElementType());
1573*35238bceSAndroid Build Coastguard Worker
1574*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1575*35238bceSAndroid Build Coastguard Worker << "Verifying top level array stride, expecting greater or equal to " << minimumStride << "."
1576*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1577*35238bceSAndroid Build Coastguard Worker
1578*35238bceSAndroid Build Coastguard Worker if (propValue < minimumStride)
1579*35238bceSAndroid Build Coastguard Worker {
1580*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array stride, got " << propValue
1581*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1582*35238bceSAndroid Build Coastguard Worker setError("top level array stride invalid");
1583*35238bceSAndroid Build Coastguard Worker }
1584*35238bceSAndroid Build Coastguard Worker }
1585*35238bceSAndroid Build Coastguard Worker }
1586*35238bceSAndroid Build Coastguard Worker
1587*35238bceSAndroid Build Coastguard Worker class TransformFeedbackResourceValidator : public PropValidator
1588*35238bceSAndroid Build Coastguard Worker {
1589*35238bceSAndroid Build Coastguard Worker public:
1590*35238bceSAndroid Build Coastguard Worker TransformFeedbackResourceValidator(Context &context, ProgramResourcePropFlags validationProp);
1591*35238bceSAndroid Build Coastguard Worker
1592*35238bceSAndroid Build Coastguard Worker void validate(const ProgramInterfaceDefinition::Program *program, const std::string &resource, glw::GLint propValue,
1593*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1594*35238bceSAndroid Build Coastguard Worker
1595*35238bceSAndroid Build Coastguard Worker private:
1596*35238bceSAndroid Build Coastguard Worker virtual void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1597*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const = 0;
1598*35238bceSAndroid Build Coastguard Worker virtual void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1599*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const = 0;
1600*35238bceSAndroid Build Coastguard Worker };
1601*35238bceSAndroid Build Coastguard Worker
TransformFeedbackResourceValidator(Context & context,ProgramResourcePropFlags validationProp)1602*35238bceSAndroid Build Coastguard Worker TransformFeedbackResourceValidator::TransformFeedbackResourceValidator(Context &context,
1603*35238bceSAndroid Build Coastguard Worker ProgramResourcePropFlags validationProp)
1604*35238bceSAndroid Build Coastguard Worker : PropValidator(context, validationProp, DE_NULL)
1605*35238bceSAndroid Build Coastguard Worker {
1606*35238bceSAndroid Build Coastguard Worker }
1607*35238bceSAndroid Build Coastguard Worker
validate(const ProgramInterfaceDefinition::Program * program,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1608*35238bceSAndroid Build Coastguard Worker void TransformFeedbackResourceValidator::validate(const ProgramInterfaceDefinition::Program *program,
1609*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1610*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1611*35238bceSAndroid Build Coastguard Worker {
1612*35238bceSAndroid Build Coastguard Worker if (deStringBeginsWith(resource.c_str(), "gl_"))
1613*35238bceSAndroid Build Coastguard Worker {
1614*35238bceSAndroid Build Coastguard Worker validateBuiltinVariable(resource, propValue, implementationName);
1615*35238bceSAndroid Build Coastguard Worker }
1616*35238bceSAndroid Build Coastguard Worker else
1617*35238bceSAndroid Build Coastguard Worker {
1618*35238bceSAndroid Build Coastguard Worker // Check resource name is a xfb output. (quick check)
1619*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
1620*35238bceSAndroid Build Coastguard Worker bool generatorFound = false;
1621*35238bceSAndroid Build Coastguard Worker
1622*35238bceSAndroid Build Coastguard Worker // Check the resource name is a valid transform feedback resource and find the name generating resource
1623*35238bceSAndroid Build Coastguard Worker for (int varyingNdx = 0; varyingNdx < (int)program->getTransformFeedbackVaryings().size(); ++varyingNdx)
1624*35238bceSAndroid Build Coastguard Worker {
1625*35238bceSAndroid Build Coastguard Worker const std::string varyingName = program->getTransformFeedbackVaryings()[varyingNdx];
1626*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> path;
1627*35238bceSAndroid Build Coastguard Worker std::vector<std::string> resources;
1628*35238bceSAndroid Build Coastguard Worker
1629*35238bceSAndroid Build Coastguard Worker if (!findProgramVariablePathByPathName(path, program, varyingName,
1630*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createShaderTypeStorageFilter(
1631*35238bceSAndroid Build Coastguard Worker getProgramTransformFeedbackStage(program), glu::STORAGE_OUT)))
1632*35238bceSAndroid Build Coastguard Worker {
1633*35238bceSAndroid Build Coastguard Worker // program does not contain feedback varying, not valid program
1634*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1635*35238bceSAndroid Build Coastguard Worker return;
1636*35238bceSAndroid Build Coastguard Worker }
1637*35238bceSAndroid Build Coastguard Worker
1638*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, varyingName, *path.back().getVariableType(),
1639*35238bceSAndroid Build Coastguard Worker RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE);
1640*35238bceSAndroid Build Coastguard Worker
1641*35238bceSAndroid Build Coastguard Worker if (de::contains(resources.begin(), resources.end(), resource))
1642*35238bceSAndroid Build Coastguard Worker {
1643*35238bceSAndroid Build Coastguard Worker generatorFound = true;
1644*35238bceSAndroid Build Coastguard Worker break;
1645*35238bceSAndroid Build Coastguard Worker }
1646*35238bceSAndroid Build Coastguard Worker }
1647*35238bceSAndroid Build Coastguard Worker
1648*35238bceSAndroid Build Coastguard Worker // resource name was not found, should never happen
1649*35238bceSAndroid Build Coastguard Worker DE_ASSERT(generatorFound);
1650*35238bceSAndroid Build Coastguard Worker DE_UNREF(generatorFound);
1651*35238bceSAndroid Build Coastguard Worker #endif
1652*35238bceSAndroid Build Coastguard Worker
1653*35238bceSAndroid Build Coastguard Worker // verify resource
1654*35238bceSAndroid Build Coastguard Worker {
1655*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> path;
1656*35238bceSAndroid Build Coastguard Worker
1657*35238bceSAndroid Build Coastguard Worker if (!findProgramVariablePathByPathName(path, program, resource,
1658*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createShaderTypeStorageFilter(
1659*35238bceSAndroid Build Coastguard Worker getProgramTransformFeedbackStage(program), glu::STORAGE_OUT)))
1660*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1661*35238bceSAndroid Build Coastguard Worker
1662*35238bceSAndroid Build Coastguard Worker validateSingleVariable(path, resource, propValue, implementationName);
1663*35238bceSAndroid Build Coastguard Worker }
1664*35238bceSAndroid Build Coastguard Worker }
1665*35238bceSAndroid Build Coastguard Worker }
1666*35238bceSAndroid Build Coastguard Worker
1667*35238bceSAndroid Build Coastguard Worker class TransformFeedbackArraySizeValidator : public TransformFeedbackResourceValidator
1668*35238bceSAndroid Build Coastguard Worker {
1669*35238bceSAndroid Build Coastguard Worker public:
1670*35238bceSAndroid Build Coastguard Worker TransformFeedbackArraySizeValidator(Context &context);
1671*35238bceSAndroid Build Coastguard Worker
1672*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1673*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1674*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1675*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1676*35238bceSAndroid Build Coastguard Worker };
1677*35238bceSAndroid Build Coastguard Worker
TransformFeedbackArraySizeValidator(Context & context)1678*35238bceSAndroid Build Coastguard Worker TransformFeedbackArraySizeValidator::TransformFeedbackArraySizeValidator(Context &context)
1679*35238bceSAndroid Build Coastguard Worker : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_ARRAY_SIZE)
1680*35238bceSAndroid Build Coastguard Worker {
1681*35238bceSAndroid Build Coastguard Worker }
1682*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1683*35238bceSAndroid Build Coastguard Worker void TransformFeedbackArraySizeValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1684*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1685*35238bceSAndroid Build Coastguard Worker {
1686*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1687*35238bceSAndroid Build Coastguard Worker
1688*35238bceSAndroid Build Coastguard Worker int arraySize = 0;
1689*35238bceSAndroid Build Coastguard Worker
1690*35238bceSAndroid Build Coastguard Worker if (resource == "gl_Position")
1691*35238bceSAndroid Build Coastguard Worker arraySize = 1;
1692*35238bceSAndroid Build Coastguard Worker else
1693*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1694*35238bceSAndroid Build Coastguard Worker
1695*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize
1696*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1697*35238bceSAndroid Build Coastguard Worker if (arraySize != propValue)
1698*35238bceSAndroid Build Coastguard Worker {
1699*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1700*35238bceSAndroid Build Coastguard Worker setError("resource array size invalid");
1701*35238bceSAndroid Build Coastguard Worker }
1702*35238bceSAndroid Build Coastguard Worker }
1703*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1704*35238bceSAndroid Build Coastguard Worker void TransformFeedbackArraySizeValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1705*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1706*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1707*35238bceSAndroid Build Coastguard Worker {
1708*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1709*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1710*35238bceSAndroid Build Coastguard Worker
1711*35238bceSAndroid Build Coastguard Worker const int arraySize =
1712*35238bceSAndroid Build Coastguard Worker (path.back().getVariableType()->isArrayType()) ? (path.back().getVariableType()->getArraySize()) : (1);
1713*35238bceSAndroid Build Coastguard Worker
1714*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize
1715*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1716*35238bceSAndroid Build Coastguard Worker if (arraySize != propValue)
1717*35238bceSAndroid Build Coastguard Worker {
1718*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1719*35238bceSAndroid Build Coastguard Worker setError("resource array size invalid");
1720*35238bceSAndroid Build Coastguard Worker }
1721*35238bceSAndroid Build Coastguard Worker }
1722*35238bceSAndroid Build Coastguard Worker
1723*35238bceSAndroid Build Coastguard Worker class TransformFeedbackNameLengthValidator : public TransformFeedbackResourceValidator
1724*35238bceSAndroid Build Coastguard Worker {
1725*35238bceSAndroid Build Coastguard Worker public:
1726*35238bceSAndroid Build Coastguard Worker TransformFeedbackNameLengthValidator(Context &context);
1727*35238bceSAndroid Build Coastguard Worker
1728*35238bceSAndroid Build Coastguard Worker private:
1729*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1730*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1731*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1732*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1733*35238bceSAndroid Build Coastguard Worker void validateVariable(const std::string &implementationName, glw::GLint propValue) const;
1734*35238bceSAndroid Build Coastguard Worker };
1735*35238bceSAndroid Build Coastguard Worker
TransformFeedbackNameLengthValidator(Context & context)1736*35238bceSAndroid Build Coastguard Worker TransformFeedbackNameLengthValidator::TransformFeedbackNameLengthValidator(Context &context)
1737*35238bceSAndroid Build Coastguard Worker : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH)
1738*35238bceSAndroid Build Coastguard Worker {
1739*35238bceSAndroid Build Coastguard Worker }
1740*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1741*35238bceSAndroid Build Coastguard Worker void TransformFeedbackNameLengthValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1742*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1743*35238bceSAndroid Build Coastguard Worker {
1744*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1745*35238bceSAndroid Build Coastguard Worker validateVariable(implementationName, propValue);
1746*35238bceSAndroid Build Coastguard Worker }
1747*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1748*35238bceSAndroid Build Coastguard Worker void TransformFeedbackNameLengthValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1749*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1750*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1751*35238bceSAndroid Build Coastguard Worker {
1752*35238bceSAndroid Build Coastguard Worker DE_UNREF(path);
1753*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1754*35238bceSAndroid Build Coastguard Worker validateVariable(implementationName, propValue);
1755*35238bceSAndroid Build Coastguard Worker }
1756*35238bceSAndroid Build Coastguard Worker
validateVariable(const std::string & implementationName,glw::GLint propValue) const1757*35238bceSAndroid Build Coastguard Worker void TransformFeedbackNameLengthValidator::validateVariable(const std::string &implementationName,
1758*35238bceSAndroid Build Coastguard Worker glw::GLint propValue) const
1759*35238bceSAndroid Build Coastguard Worker {
1760*35238bceSAndroid Build Coastguard Worker const int expected = (int)implementationName.length() + 1; // includes null byte
1761*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " ("
1762*35238bceSAndroid Build Coastguard Worker << (int)implementationName.length() << " for \"" << implementationName
1763*35238bceSAndroid Build Coastguard Worker << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;
1764*35238bceSAndroid Build Coastguard Worker
1765*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1766*35238bceSAndroid Build Coastguard Worker {
1767*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue
1768*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1769*35238bceSAndroid Build Coastguard Worker setError("name length invalid");
1770*35238bceSAndroid Build Coastguard Worker }
1771*35238bceSAndroid Build Coastguard Worker }
1772*35238bceSAndroid Build Coastguard Worker
1773*35238bceSAndroid Build Coastguard Worker class TransformFeedbackTypeValidator : public TransformFeedbackResourceValidator
1774*35238bceSAndroid Build Coastguard Worker {
1775*35238bceSAndroid Build Coastguard Worker public:
1776*35238bceSAndroid Build Coastguard Worker TransformFeedbackTypeValidator(Context &context);
1777*35238bceSAndroid Build Coastguard Worker
1778*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1779*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1780*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1781*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1782*35238bceSAndroid Build Coastguard Worker };
1783*35238bceSAndroid Build Coastguard Worker
TransformFeedbackTypeValidator(Context & context)1784*35238bceSAndroid Build Coastguard Worker TransformFeedbackTypeValidator::TransformFeedbackTypeValidator(Context &context)
1785*35238bceSAndroid Build Coastguard Worker : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_TYPE)
1786*35238bceSAndroid Build Coastguard Worker {
1787*35238bceSAndroid Build Coastguard Worker }
1788*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1789*35238bceSAndroid Build Coastguard Worker void TransformFeedbackTypeValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1790*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1791*35238bceSAndroid Build Coastguard Worker {
1792*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1793*35238bceSAndroid Build Coastguard Worker
1794*35238bceSAndroid Build Coastguard Worker glu::DataType varType = glu::TYPE_INVALID;
1795*35238bceSAndroid Build Coastguard Worker
1796*35238bceSAndroid Build Coastguard Worker if (resource == "gl_Position")
1797*35238bceSAndroid Build Coastguard Worker varType = glu::TYPE_FLOAT_VEC4;
1798*35238bceSAndroid Build Coastguard Worker else
1799*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1800*35238bceSAndroid Build Coastguard Worker
1801*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(varType)
1802*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1803*35238bceSAndroid Build Coastguard Worker if (glu::getDataTypeFromGLType(propValue) != varType)
1804*35238bceSAndroid Build Coastguard Worker {
1805*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got "
1806*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
1807*35238bceSAndroid Build Coastguard Worker setError("resource type invalid");
1808*35238bceSAndroid Build Coastguard Worker }
1809*35238bceSAndroid Build Coastguard Worker return;
1810*35238bceSAndroid Build Coastguard Worker }
1811*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1812*35238bceSAndroid Build Coastguard Worker void TransformFeedbackTypeValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1813*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1814*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1815*35238bceSAndroid Build Coastguard Worker {
1816*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1817*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1818*35238bceSAndroid Build Coastguard Worker
1819*35238bceSAndroid Build Coastguard Worker // Unlike other interfaces, xfb program interface uses just variable name to refer to arrays of basic types. (Others use "variable[0]")
1820*35238bceSAndroid Build Coastguard Worker // Thus we might end up querying a type for an array. In this case, return the type of an array element.
1821*35238bceSAndroid Build Coastguard Worker const glu::VarType &variable = *path.back().getVariableType();
1822*35238bceSAndroid Build Coastguard Worker const glu::VarType &elementType = (variable.isArrayType()) ? (variable.getElementType()) : (variable);
1823*35238bceSAndroid Build Coastguard Worker
1824*35238bceSAndroid Build Coastguard Worker DE_ASSERT(elementType.isBasicType());
1825*35238bceSAndroid Build Coastguard Worker
1826*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting "
1827*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(elementType.getBasicType()) << tcu::TestLog::EndMessage;
1828*35238bceSAndroid Build Coastguard Worker if (elementType.getBasicType() != glu::getDataTypeFromGLType(propValue))
1829*35238bceSAndroid Build Coastguard Worker {
1830*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got "
1831*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
1832*35238bceSAndroid Build Coastguard Worker setError("resource type invalid");
1833*35238bceSAndroid Build Coastguard Worker }
1834*35238bceSAndroid Build Coastguard Worker }
1835*35238bceSAndroid Build Coastguard Worker
1836*35238bceSAndroid Build Coastguard Worker class PerPatchValidator : public SingleVariableValidator
1837*35238bceSAndroid Build Coastguard Worker {
1838*35238bceSAndroid Build Coastguard Worker public:
1839*35238bceSAndroid Build Coastguard Worker PerPatchValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter);
1840*35238bceSAndroid Build Coastguard Worker
1841*35238bceSAndroid Build Coastguard Worker std::string getHumanReadablePropertyString(glw::GLint propVal) const;
1842*35238bceSAndroid Build Coastguard Worker void validateSingleVariable(const std::vector<VariablePathComponent> &path, const std::string &resource,
1843*35238bceSAndroid Build Coastguard Worker glw::GLint propValue, const std::string &implementationName) const;
1844*35238bceSAndroid Build Coastguard Worker void validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1845*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const;
1846*35238bceSAndroid Build Coastguard Worker };
1847*35238bceSAndroid Build Coastguard Worker
PerPatchValidator(Context & context,glw::GLuint programID,const VariableSearchFilter & filter)1848*35238bceSAndroid Build Coastguard Worker PerPatchValidator::PerPatchValidator(Context &context, glw::GLuint programID, const VariableSearchFilter &filter)
1849*35238bceSAndroid Build Coastguard Worker : SingleVariableValidator(context, PROGRAMRESOURCEPROP_IS_PER_PATCH, programID, filter,
1850*35238bceSAndroid Build Coastguard Worker "GL_EXT_tessellation_shader")
1851*35238bceSAndroid Build Coastguard Worker {
1852*35238bceSAndroid Build Coastguard Worker }
1853*35238bceSAndroid Build Coastguard Worker
getHumanReadablePropertyString(glw::GLint propVal) const1854*35238bceSAndroid Build Coastguard Worker std::string PerPatchValidator::getHumanReadablePropertyString(glw::GLint propVal) const
1855*35238bceSAndroid Build Coastguard Worker {
1856*35238bceSAndroid Build Coastguard Worker return de::toString(glu::getBooleanStr(propVal));
1857*35238bceSAndroid Build Coastguard Worker }
1858*35238bceSAndroid Build Coastguard Worker
validateSingleVariable(const std::vector<VariablePathComponent> & path,const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1859*35238bceSAndroid Build Coastguard Worker void PerPatchValidator::validateSingleVariable(const std::vector<VariablePathComponent> &path,
1860*35238bceSAndroid Build Coastguard Worker const std::string &resource, glw::GLint propValue,
1861*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1862*35238bceSAndroid Build Coastguard Worker {
1863*35238bceSAndroid Build Coastguard Worker const glu::Storage storage = (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage) :
1864*35238bceSAndroid Build Coastguard Worker (path.front().getDeclaration()->storage);
1865*35238bceSAndroid Build Coastguard Worker const int expected = (storage == glu::STORAGE_PATCH_IN || storage == glu::STORAGE_PATCH_OUT) ? (1) : (0);
1866*35238bceSAndroid Build Coastguard Worker
1867*35238bceSAndroid Build Coastguard Worker DE_UNREF(resource);
1868*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1869*35238bceSAndroid Build Coastguard Worker
1870*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying if is per patch, expecting IS_PER_PATCH = " << expected
1871*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1872*35238bceSAndroid Build Coastguard Worker
1873*35238bceSAndroid Build Coastguard Worker if (propValue != expected)
1874*35238bceSAndroid Build Coastguard Worker {
1875*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1876*35238bceSAndroid Build Coastguard Worker setError("resource is per patch invalid");
1877*35238bceSAndroid Build Coastguard Worker }
1878*35238bceSAndroid Build Coastguard Worker }
1879*35238bceSAndroid Build Coastguard Worker
validateBuiltinVariable(const std::string & resource,glw::GLint propValue,const std::string & implementationName) const1880*35238bceSAndroid Build Coastguard Worker void PerPatchValidator::validateBuiltinVariable(const std::string &resource, glw::GLint propValue,
1881*35238bceSAndroid Build Coastguard Worker const std::string &implementationName) const
1882*35238bceSAndroid Build Coastguard Worker {
1883*35238bceSAndroid Build Coastguard Worker DE_UNREF(implementationName);
1884*35238bceSAndroid Build Coastguard Worker
1885*35238bceSAndroid Build Coastguard Worker static const struct
1886*35238bceSAndroid Build Coastguard Worker {
1887*35238bceSAndroid Build Coastguard Worker const char *name;
1888*35238bceSAndroid Build Coastguard Worker int isPerPatch;
1889*35238bceSAndroid Build Coastguard Worker } builtins[] = {
1890*35238bceSAndroid Build Coastguard Worker {"gl_Position", 0}, {"gl_PerVertex.gl_Position", 0}, {"gl_InvocationID", 0},
1891*35238bceSAndroid Build Coastguard Worker {"gl_TessLevelOuter[0]", 1}, {"gl_TessLevelInner[0]", 1},
1892*35238bceSAndroid Build Coastguard Worker };
1893*35238bceSAndroid Build Coastguard Worker
1894*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
1895*35238bceSAndroid Build Coastguard Worker {
1896*35238bceSAndroid Build Coastguard Worker if (resource == builtins[ndx].name)
1897*35238bceSAndroid Build Coastguard Worker {
1898*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1899*35238bceSAndroid Build Coastguard Worker << "Verifying if is per patch, expecting IS_PER_PATCH = " << builtins[ndx].isPerPatch
1900*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1901*35238bceSAndroid Build Coastguard Worker
1902*35238bceSAndroid Build Coastguard Worker if (propValue != builtins[ndx].isPerPatch)
1903*35238bceSAndroid Build Coastguard Worker {
1904*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
1905*35238bceSAndroid Build Coastguard Worker setError("resource is per patch invalid");
1906*35238bceSAndroid Build Coastguard Worker }
1907*35238bceSAndroid Build Coastguard Worker return;
1908*35238bceSAndroid Build Coastguard Worker }
1909*35238bceSAndroid Build Coastguard Worker }
1910*35238bceSAndroid Build Coastguard Worker
1911*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1912*35238bceSAndroid Build Coastguard Worker }
1913*35238bceSAndroid Build Coastguard Worker
1914*35238bceSAndroid Build Coastguard Worker } // namespace
1915*35238bceSAndroid Build Coastguard Worker
ProgramResourceQueryTestTarget(ProgramInterface interface_,uint32_t propFlags_)1916*35238bceSAndroid Build Coastguard Worker ProgramResourceQueryTestTarget::ProgramResourceQueryTestTarget(ProgramInterface interface_, uint32_t propFlags_)
1917*35238bceSAndroid Build Coastguard Worker : interface(interface_)
1918*35238bceSAndroid Build Coastguard Worker , propFlags(propFlags_)
1919*35238bceSAndroid Build Coastguard Worker {
1920*35238bceSAndroid Build Coastguard Worker switch (interface)
1921*35238bceSAndroid Build Coastguard Worker {
1922*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
1923*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK) == propFlags);
1924*35238bceSAndroid Build Coastguard Worker break;
1925*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
1926*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_BLOCK_INTERFACE_MASK) == propFlags);
1927*35238bceSAndroid Build Coastguard Worker break;
1928*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
1929*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_SHADER_STORAGE_BLOCK_MASK) == propFlags);
1930*35238bceSAndroid Build Coastguard Worker break;
1931*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
1932*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_INPUT_MASK) == propFlags);
1933*35238bceSAndroid Build Coastguard Worker break;
1934*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
1935*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_OUTPUT_MASK) == propFlags);
1936*35238bceSAndroid Build Coastguard Worker break;
1937*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
1938*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK) == propFlags);
1939*35238bceSAndroid Build Coastguard Worker break;
1940*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
1941*35238bceSAndroid Build Coastguard Worker DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_TRANSFORM_FEEDBACK_VARYING_MASK) == propFlags);
1942*35238bceSAndroid Build Coastguard Worker break;
1943*35238bceSAndroid Build Coastguard Worker
1944*35238bceSAndroid Build Coastguard Worker default:
1945*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1946*35238bceSAndroid Build Coastguard Worker }
1947*35238bceSAndroid Build Coastguard Worker }
1948*35238bceSAndroid Build Coastguard Worker
ProgramInterfaceQueryTestCase(Context & context,const char * name,const char * description,ProgramResourceQueryTestTarget queryTarget)1949*35238bceSAndroid Build Coastguard Worker ProgramInterfaceQueryTestCase::ProgramInterfaceQueryTestCase(Context &context, const char *name,
1950*35238bceSAndroid Build Coastguard Worker const char *description,
1951*35238bceSAndroid Build Coastguard Worker ProgramResourceQueryTestTarget queryTarget)
1952*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
1953*35238bceSAndroid Build Coastguard Worker , m_queryTarget(queryTarget)
1954*35238bceSAndroid Build Coastguard Worker {
1955*35238bceSAndroid Build Coastguard Worker }
1956*35238bceSAndroid Build Coastguard Worker
~ProgramInterfaceQueryTestCase(void)1957*35238bceSAndroid Build Coastguard Worker ProgramInterfaceQueryTestCase::~ProgramInterfaceQueryTestCase(void)
1958*35238bceSAndroid Build Coastguard Worker {
1959*35238bceSAndroid Build Coastguard Worker }
1960*35238bceSAndroid Build Coastguard Worker
getTargetInterface(void) const1961*35238bceSAndroid Build Coastguard Worker ProgramInterface ProgramInterfaceQueryTestCase::getTargetInterface(void) const
1962*35238bceSAndroid Build Coastguard Worker {
1963*35238bceSAndroid Build Coastguard Worker return m_queryTarget.interface;
1964*35238bceSAndroid Build Coastguard Worker }
1965*35238bceSAndroid Build Coastguard Worker
getGLInterfaceEnumValue(ProgramInterface interface)1966*35238bceSAndroid Build Coastguard Worker static glw::GLenum getGLInterfaceEnumValue(ProgramInterface interface)
1967*35238bceSAndroid Build Coastguard Worker {
1968*35238bceSAndroid Build Coastguard Worker switch (interface)
1969*35238bceSAndroid Build Coastguard Worker {
1970*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
1971*35238bceSAndroid Build Coastguard Worker return GL_UNIFORM;
1972*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
1973*35238bceSAndroid Build Coastguard Worker return GL_UNIFORM_BLOCK;
1974*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:
1975*35238bceSAndroid Build Coastguard Worker return GL_ATOMIC_COUNTER_BUFFER;
1976*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
1977*35238bceSAndroid Build Coastguard Worker return GL_PROGRAM_INPUT;
1978*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
1979*35238bceSAndroid Build Coastguard Worker return GL_PROGRAM_OUTPUT;
1980*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
1981*35238bceSAndroid Build Coastguard Worker return GL_TRANSFORM_FEEDBACK_VARYING;
1982*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
1983*35238bceSAndroid Build Coastguard Worker return GL_BUFFER_VARIABLE;
1984*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
1985*35238bceSAndroid Build Coastguard Worker return GL_SHADER_STORAGE_BLOCK;
1986*35238bceSAndroid Build Coastguard Worker default:
1987*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1988*35238bceSAndroid Build Coastguard Worker return 0;
1989*35238bceSAndroid Build Coastguard Worker }
1990*35238bceSAndroid Build Coastguard Worker }
1991*35238bceSAndroid Build Coastguard Worker
isInterfaceBlockInterfaceName(const ProgramInterfaceDefinition::Program * program,ProgramInterface interface,const std::string & blockInterfaceName)1992*35238bceSAndroid Build Coastguard Worker static bool isInterfaceBlockInterfaceName(const ProgramInterfaceDefinition::Program *program,
1993*35238bceSAndroid Build Coastguard Worker ProgramInterface interface, const std::string &blockInterfaceName)
1994*35238bceSAndroid Build Coastguard Worker {
1995*35238bceSAndroid Build Coastguard Worker uint32_t validStorageBits;
1996*35238bceSAndroid Build Coastguard Worker uint32_t searchStageBits;
1997*35238bceSAndroid Build Coastguard Worker
1998*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(glu::STORAGE_LAST < 32);
1999*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(glu::SHADERTYPE_LAST < 32);
2000*35238bceSAndroid Build Coastguard Worker
2001*35238bceSAndroid Build Coastguard Worker switch (interface)
2002*35238bceSAndroid Build Coastguard Worker {
2003*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
2004*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
2005*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:
2006*35238bceSAndroid Build Coastguard Worker return false;
2007*35238bceSAndroid Build Coastguard Worker
2008*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
2009*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_IN) | (1u << glu::STORAGE_PATCH_IN);
2010*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << program->getFirstStage());
2011*35238bceSAndroid Build Coastguard Worker break;
2012*35238bceSAndroid Build Coastguard Worker
2013*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
2014*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_OUT) | (1u << glu::STORAGE_PATCH_OUT);
2015*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << program->getLastStage());
2016*35238bceSAndroid Build Coastguard Worker break;
2017*35238bceSAndroid Build Coastguard Worker
2018*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
2019*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_OUT);
2020*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << getProgramTransformFeedbackStage(program));
2021*35238bceSAndroid Build Coastguard Worker break;
2022*35238bceSAndroid Build Coastguard Worker
2023*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
2024*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_UNIFORM);
2025*35238bceSAndroid Build Coastguard Worker searchStageBits = 0xFFFFFFFFu;
2026*35238bceSAndroid Build Coastguard Worker break;
2027*35238bceSAndroid Build Coastguard Worker
2028*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
2029*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_BUFFER);
2030*35238bceSAndroid Build Coastguard Worker searchStageBits = 0xFFFFFFFFu;
2031*35238bceSAndroid Build Coastguard Worker break;
2032*35238bceSAndroid Build Coastguard Worker
2033*35238bceSAndroid Build Coastguard Worker default:
2034*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2035*35238bceSAndroid Build Coastguard Worker return false;
2036*35238bceSAndroid Build Coastguard Worker }
2037*35238bceSAndroid Build Coastguard Worker
2038*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
2039*35238bceSAndroid Build Coastguard Worker {
2040*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *const shader = program->getShaders()[shaderNdx];
2041*35238bceSAndroid Build Coastguard Worker if (((1u << shader->getType()) & searchStageBits) == 0)
2042*35238bceSAndroid Build Coastguard Worker continue;
2043*35238bceSAndroid Build Coastguard Worker
2044*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
2045*35238bceSAndroid Build Coastguard Worker {
2046*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block = shader->getDefaultBlock().interfaceBlocks[blockNdx];
2047*35238bceSAndroid Build Coastguard Worker
2048*35238bceSAndroid Build Coastguard Worker if (((1u << block.storage) & validStorageBits) == 0)
2049*35238bceSAndroid Build Coastguard Worker continue;
2050*35238bceSAndroid Build Coastguard Worker
2051*35238bceSAndroid Build Coastguard Worker if (block.interfaceName == blockInterfaceName)
2052*35238bceSAndroid Build Coastguard Worker return true;
2053*35238bceSAndroid Build Coastguard Worker }
2054*35238bceSAndroid Build Coastguard Worker }
2055*35238bceSAndroid Build Coastguard Worker return false;
2056*35238bceSAndroid Build Coastguard Worker }
2057*35238bceSAndroid Build Coastguard Worker
getInterfaceBlockInteraceNameByMember(const ProgramInterfaceDefinition::Program * program,ProgramInterface interface,const std::string & memberName)2058*35238bceSAndroid Build Coastguard Worker static std::string getInterfaceBlockInteraceNameByMember(const ProgramInterfaceDefinition::Program *program,
2059*35238bceSAndroid Build Coastguard Worker ProgramInterface interface, const std::string &memberName)
2060*35238bceSAndroid Build Coastguard Worker {
2061*35238bceSAndroid Build Coastguard Worker uint32_t validStorageBits;
2062*35238bceSAndroid Build Coastguard Worker uint32_t searchStageBits;
2063*35238bceSAndroid Build Coastguard Worker
2064*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(glu::STORAGE_LAST < 32);
2065*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(glu::SHADERTYPE_LAST < 32);
2066*35238bceSAndroid Build Coastguard Worker
2067*35238bceSAndroid Build Coastguard Worker switch (interface)
2068*35238bceSAndroid Build Coastguard Worker {
2069*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
2070*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
2071*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:
2072*35238bceSAndroid Build Coastguard Worker return "";
2073*35238bceSAndroid Build Coastguard Worker
2074*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
2075*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_IN) | (1u << glu::STORAGE_PATCH_IN);
2076*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << program->getFirstStage());
2077*35238bceSAndroid Build Coastguard Worker break;
2078*35238bceSAndroid Build Coastguard Worker
2079*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
2080*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_OUT) | (1u << glu::STORAGE_PATCH_OUT);
2081*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << program->getLastStage());
2082*35238bceSAndroid Build Coastguard Worker break;
2083*35238bceSAndroid Build Coastguard Worker
2084*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
2085*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_OUT);
2086*35238bceSAndroid Build Coastguard Worker searchStageBits = (1u << getProgramTransformFeedbackStage(program));
2087*35238bceSAndroid Build Coastguard Worker break;
2088*35238bceSAndroid Build Coastguard Worker
2089*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
2090*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_UNIFORM);
2091*35238bceSAndroid Build Coastguard Worker searchStageBits = 0xFFFFFFFFu;
2092*35238bceSAndroid Build Coastguard Worker break;
2093*35238bceSAndroid Build Coastguard Worker
2094*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
2095*35238bceSAndroid Build Coastguard Worker validStorageBits = (1u << glu::STORAGE_BUFFER);
2096*35238bceSAndroid Build Coastguard Worker searchStageBits = 0xFFFFFFFFu;
2097*35238bceSAndroid Build Coastguard Worker break;
2098*35238bceSAndroid Build Coastguard Worker
2099*35238bceSAndroid Build Coastguard Worker default:
2100*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2101*35238bceSAndroid Build Coastguard Worker return "";
2102*35238bceSAndroid Build Coastguard Worker }
2103*35238bceSAndroid Build Coastguard Worker
2104*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
2105*35238bceSAndroid Build Coastguard Worker {
2106*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *const shader = program->getShaders()[shaderNdx];
2107*35238bceSAndroid Build Coastguard Worker if (((1u << shader->getType()) & searchStageBits) == 0)
2108*35238bceSAndroid Build Coastguard Worker continue;
2109*35238bceSAndroid Build Coastguard Worker
2110*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
2111*35238bceSAndroid Build Coastguard Worker {
2112*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block = shader->getDefaultBlock().interfaceBlocks[blockNdx];
2113*35238bceSAndroid Build Coastguard Worker
2114*35238bceSAndroid Build Coastguard Worker if (((1u << block.storage) & validStorageBits) == 0)
2115*35238bceSAndroid Build Coastguard Worker continue;
2116*35238bceSAndroid Build Coastguard Worker
2117*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)block.variables.size(); ++varNdx)
2118*35238bceSAndroid Build Coastguard Worker {
2119*35238bceSAndroid Build Coastguard Worker if (block.variables[varNdx].name == memberName)
2120*35238bceSAndroid Build Coastguard Worker return block.interfaceName;
2121*35238bceSAndroid Build Coastguard Worker }
2122*35238bceSAndroid Build Coastguard Worker }
2123*35238bceSAndroid Build Coastguard Worker }
2124*35238bceSAndroid Build Coastguard Worker return "";
2125*35238bceSAndroid Build Coastguard Worker }
2126*35238bceSAndroid Build Coastguard Worker
queryAndValidateProps(tcu::TestContext & testCtx,const glw::Functions & gl,glw::GLuint programID,ProgramInterface interface,const char * targetResourceName,const ProgramInterfaceDefinition::Program * programDefinition,const std::vector<glw::GLenum> & props,const std::vector<const PropValidator * > & validators)2127*35238bceSAndroid Build Coastguard Worker static void queryAndValidateProps(tcu::TestContext &testCtx, const glw::Functions &gl, glw::GLuint programID,
2128*35238bceSAndroid Build Coastguard Worker ProgramInterface interface, const char *targetResourceName,
2129*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *programDefinition,
2130*35238bceSAndroid Build Coastguard Worker const std::vector<glw::GLenum> &props,
2131*35238bceSAndroid Build Coastguard Worker const std::vector<const PropValidator *> &validators)
2132*35238bceSAndroid Build Coastguard Worker {
2133*35238bceSAndroid Build Coastguard Worker const glw::GLenum glInterface = getGLInterfaceEnumValue(interface);
2134*35238bceSAndroid Build Coastguard Worker std::string implementationResourceName = targetResourceName;
2135*35238bceSAndroid Build Coastguard Worker glw::GLuint resourceNdx;
2136*35238bceSAndroid Build Coastguard Worker glw::GLint written = -1;
2137*35238bceSAndroid Build Coastguard Worker
2138*35238bceSAndroid Build Coastguard Worker // prefill result buffer with an invalid value. -1 might be valid sometimes, avoid it. Make buffer one larger
2139*35238bceSAndroid Build Coastguard Worker // to allow detection of too many return values
2140*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLint> propValues(props.size() + 1, -2);
2141*35238bceSAndroid Build Coastguard Worker
2142*35238bceSAndroid Build Coastguard Worker DE_ASSERT(props.size() == validators.size());
2143*35238bceSAndroid Build Coastguard Worker
2144*35238bceSAndroid Build Coastguard Worker // query
2145*35238bceSAndroid Build Coastguard Worker
2146*35238bceSAndroid Build Coastguard Worker resourceNdx = gl.getProgramResourceIndex(programID, glInterface, targetResourceName);
2147*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index");
2148*35238bceSAndroid Build Coastguard Worker
2149*35238bceSAndroid Build Coastguard Worker if (resourceNdx == GL_INVALID_INDEX)
2150*35238bceSAndroid Build Coastguard Worker {
2151*35238bceSAndroid Build Coastguard Worker static const struct
2152*35238bceSAndroid Build Coastguard Worker {
2153*35238bceSAndroid Build Coastguard Worker bool removeTrailingArray; // convert from "target[0]" -> "target"
2154*35238bceSAndroid Build Coastguard Worker bool removeTrailingMember; // convert from "target.member" -> "target"
2155*35238bceSAndroid Build Coastguard Worker bool removeIOBlock; // convert from "InterfaceName.target" -> "target"
2156*35238bceSAndroid Build Coastguard Worker bool addIOBlock; // convert from "target" -> "InterfaceName.target"
2157*35238bceSAndroid Build Coastguard Worker bool addIOBlockArray; // convert from "target" -> "InterfaceName[0].target"
2158*35238bceSAndroid Build Coastguard Worker } recoveryStrategies[] = {
2159*35238bceSAndroid Build Coastguard Worker // try one patch
2160*35238bceSAndroid Build Coastguard Worker {true, false, false, false, false},
2161*35238bceSAndroid Build Coastguard Worker {false, true, false, false, false},
2162*35238bceSAndroid Build Coastguard Worker {false, false, true, false, false},
2163*35238bceSAndroid Build Coastguard Worker {false, false, false, true, false},
2164*35238bceSAndroid Build Coastguard Worker {false, false, false, false, true},
2165*35238bceSAndroid Build Coastguard Worker // patch both ends
2166*35238bceSAndroid Build Coastguard Worker {true, false, true, false, false},
2167*35238bceSAndroid Build Coastguard Worker {true, false, false, true, false},
2168*35238bceSAndroid Build Coastguard Worker {true, false, false, false, true},
2169*35238bceSAndroid Build Coastguard Worker {false, true, true, false, false},
2170*35238bceSAndroid Build Coastguard Worker {false, true, false, true, false},
2171*35238bceSAndroid Build Coastguard Worker {false, true, false, false, true},
2172*35238bceSAndroid Build Coastguard Worker };
2173*35238bceSAndroid Build Coastguard Worker
2174*35238bceSAndroid Build Coastguard Worker // The resource name generation in the GL implementations is very commonly broken. Try to
2175*35238bceSAndroid Build Coastguard Worker // keep the tests producing useful data even in these cases by attempting to recover from
2176*35238bceSAndroid Build Coastguard Worker // common naming bugs. Set test result to failure even if recovery succeeded to signal
2177*35238bceSAndroid Build Coastguard Worker // incorrect name generation.
2178*35238bceSAndroid Build Coastguard Worker
2179*35238bceSAndroid Build Coastguard Worker testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceIndex returned GL_INVALID_INDEX for \""
2180*35238bceSAndroid Build Coastguard Worker << targetResourceName << "\"" << tcu::TestLog::EndMessage;
2181*35238bceSAndroid Build Coastguard Worker testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
2182*35238bceSAndroid Build Coastguard Worker
2183*35238bceSAndroid Build Coastguard Worker for (int strategyNdx = 0; strategyNdx < DE_LENGTH_OF_ARRAY(recoveryStrategies); ++strategyNdx)
2184*35238bceSAndroid Build Coastguard Worker {
2185*35238bceSAndroid Build Coastguard Worker const std::string resourceName = std::string(targetResourceName);
2186*35238bceSAndroid Build Coastguard Worker const size_t rootNameEnd = resourceName.find_first_of(".[");
2187*35238bceSAndroid Build Coastguard Worker const std::string rootName = resourceName.substr(0, rootNameEnd);
2188*35238bceSAndroid Build Coastguard Worker std::string simplifiedResourceName;
2189*35238bceSAndroid Build Coastguard Worker
2190*35238bceSAndroid Build Coastguard Worker if (recoveryStrategies[strategyNdx].removeTrailingArray)
2191*35238bceSAndroid Build Coastguard Worker {
2192*35238bceSAndroid Build Coastguard Worker if (de::endsWith(resourceName, "[0]"))
2193*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = resourceName.substr(0, resourceName.length() - 3);
2194*35238bceSAndroid Build Coastguard Worker else
2195*35238bceSAndroid Build Coastguard Worker continue;
2196*35238bceSAndroid Build Coastguard Worker }
2197*35238bceSAndroid Build Coastguard Worker
2198*35238bceSAndroid Build Coastguard Worker if (recoveryStrategies[strategyNdx].removeTrailingMember)
2199*35238bceSAndroid Build Coastguard Worker {
2200*35238bceSAndroid Build Coastguard Worker const size_t lastMember = resourceName.find_last_of('.');
2201*35238bceSAndroid Build Coastguard Worker if (lastMember != std::string::npos)
2202*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = resourceName.substr(0, lastMember);
2203*35238bceSAndroid Build Coastguard Worker else
2204*35238bceSAndroid Build Coastguard Worker continue;
2205*35238bceSAndroid Build Coastguard Worker }
2206*35238bceSAndroid Build Coastguard Worker
2207*35238bceSAndroid Build Coastguard Worker if (recoveryStrategies[strategyNdx].removeIOBlock)
2208*35238bceSAndroid Build Coastguard Worker {
2209*35238bceSAndroid Build Coastguard Worker if (deStringBeginsWith(resourceName.c_str(), "gl_PerVertex."))
2210*35238bceSAndroid Build Coastguard Worker {
2211*35238bceSAndroid Build Coastguard Worker // builtin interface bock, remove block name
2212*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = resourceName.substr(13);
2213*35238bceSAndroid Build Coastguard Worker }
2214*35238bceSAndroid Build Coastguard Worker else if (isInterfaceBlockInterfaceName(programDefinition, interface, rootName))
2215*35238bceSAndroid Build Coastguard Worker {
2216*35238bceSAndroid Build Coastguard Worker // user-defined inteface block, remove name
2217*35238bceSAndroid Build Coastguard Worker const size_t accessorEnd = resourceName.find('.'); // includes potential array accessor
2218*35238bceSAndroid Build Coastguard Worker
2219*35238bceSAndroid Build Coastguard Worker if (accessorEnd != std::string::npos)
2220*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = resourceName.substr(0, accessorEnd + 1);
2221*35238bceSAndroid Build Coastguard Worker else
2222*35238bceSAndroid Build Coastguard Worker continue;
2223*35238bceSAndroid Build Coastguard Worker }
2224*35238bceSAndroid Build Coastguard Worker else
2225*35238bceSAndroid Build Coastguard Worker {
2226*35238bceSAndroid Build Coastguard Worker // recovery not applicable
2227*35238bceSAndroid Build Coastguard Worker continue;
2228*35238bceSAndroid Build Coastguard Worker }
2229*35238bceSAndroid Build Coastguard Worker }
2230*35238bceSAndroid Build Coastguard Worker
2231*35238bceSAndroid Build Coastguard Worker if (recoveryStrategies[strategyNdx].addIOBlock || recoveryStrategies[strategyNdx].addIOBlockArray)
2232*35238bceSAndroid Build Coastguard Worker {
2233*35238bceSAndroid Build Coastguard Worker const std::string arrayAccessor = (recoveryStrategies[strategyNdx].addIOBlockArray) ? ("[0]") : ("");
2234*35238bceSAndroid Build Coastguard Worker
2235*35238bceSAndroid Build Coastguard Worker if (deStringBeginsWith(resourceName.c_str(), "gl_") && resourceName.find('.') == std::string::npos)
2236*35238bceSAndroid Build Coastguard Worker {
2237*35238bceSAndroid Build Coastguard Worker // free builtin variable, add block name
2238*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = "gl_PerVertex" + arrayAccessor + "." + resourceName;
2239*35238bceSAndroid Build Coastguard Worker }
2240*35238bceSAndroid Build Coastguard Worker else
2241*35238bceSAndroid Build Coastguard Worker {
2242*35238bceSAndroid Build Coastguard Worker const std::string interafaceName =
2243*35238bceSAndroid Build Coastguard Worker getInterfaceBlockInteraceNameByMember(programDefinition, interface, rootName);
2244*35238bceSAndroid Build Coastguard Worker
2245*35238bceSAndroid Build Coastguard Worker if (!interafaceName.empty())
2246*35238bceSAndroid Build Coastguard Worker {
2247*35238bceSAndroid Build Coastguard Worker // free user variable, add block name
2248*35238bceSAndroid Build Coastguard Worker simplifiedResourceName = interafaceName + arrayAccessor + "." + resourceName;
2249*35238bceSAndroid Build Coastguard Worker }
2250*35238bceSAndroid Build Coastguard Worker else
2251*35238bceSAndroid Build Coastguard Worker {
2252*35238bceSAndroid Build Coastguard Worker // recovery not applicable
2253*35238bceSAndroid Build Coastguard Worker continue;
2254*35238bceSAndroid Build Coastguard Worker }
2255*35238bceSAndroid Build Coastguard Worker }
2256*35238bceSAndroid Build Coastguard Worker }
2257*35238bceSAndroid Build Coastguard Worker
2258*35238bceSAndroid Build Coastguard Worker if (simplifiedResourceName.empty())
2259*35238bceSAndroid Build Coastguard Worker continue;
2260*35238bceSAndroid Build Coastguard Worker
2261*35238bceSAndroid Build Coastguard Worker resourceNdx = gl.getProgramResourceIndex(programID, glInterface, simplifiedResourceName.c_str());
2262*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index");
2263*35238bceSAndroid Build Coastguard Worker
2264*35238bceSAndroid Build Coastguard Worker // recovery succeeded
2265*35238bceSAndroid Build Coastguard Worker if (resourceNdx != GL_INVALID_INDEX)
2266*35238bceSAndroid Build Coastguard Worker {
2267*35238bceSAndroid Build Coastguard Worker implementationResourceName = simplifiedResourceName;
2268*35238bceSAndroid Build Coastguard Worker testCtx.getLog() << tcu::TestLog::Message
2269*35238bceSAndroid Build Coastguard Worker << "\tResource not found, continuing anyway using index obtained for resource \""
2270*35238bceSAndroid Build Coastguard Worker << simplifiedResourceName << "\"" << tcu::TestLog::EndMessage;
2271*35238bceSAndroid Build Coastguard Worker break;
2272*35238bceSAndroid Build Coastguard Worker }
2273*35238bceSAndroid Build Coastguard Worker }
2274*35238bceSAndroid Build Coastguard Worker
2275*35238bceSAndroid Build Coastguard Worker if (resourceNdx == GL_INVALID_INDEX)
2276*35238bceSAndroid Build Coastguard Worker return;
2277*35238bceSAndroid Build Coastguard Worker }
2278*35238bceSAndroid Build Coastguard Worker
2279*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceiv(programID, glInterface, resourceNdx, (int)props.size(), &props[0], (int)propValues.size(),
2280*35238bceSAndroid Build Coastguard Worker &written, &propValues[0]);
2281*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "get props");
2282*35238bceSAndroid Build Coastguard Worker
2283*35238bceSAndroid Build Coastguard Worker if (written != (int)props.size())
2284*35238bceSAndroid Build Coastguard Worker {
2285*35238bceSAndroid Build Coastguard Worker testCtx.getLog() << tcu::TestLog::Message
2286*35238bceSAndroid Build Coastguard Worker << "getProgramResourceiv returned unexpected number of values, expected " << (int)props.size()
2287*35238bceSAndroid Build Coastguard Worker << ", got " << written << tcu::TestLog::EndMessage;
2288*35238bceSAndroid Build Coastguard Worker testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values");
2289*35238bceSAndroid Build Coastguard Worker return;
2290*35238bceSAndroid Build Coastguard Worker }
2291*35238bceSAndroid Build Coastguard Worker
2292*35238bceSAndroid Build Coastguard Worker if (propValues.back() != -2)
2293*35238bceSAndroid Build Coastguard Worker {
2294*35238bceSAndroid Build Coastguard Worker testCtx.getLog() << tcu::TestLog::Message
2295*35238bceSAndroid Build Coastguard Worker << "getProgramResourceiv post write buffer guard value was modified, too many return values"
2296*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2297*35238bceSAndroid Build Coastguard Worker testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values");
2298*35238bceSAndroid Build Coastguard Worker return;
2299*35238bceSAndroid Build Coastguard Worker }
2300*35238bceSAndroid Build Coastguard Worker propValues.pop_back();
2301*35238bceSAndroid Build Coastguard Worker DE_ASSERT(validators.size() == propValues.size());
2302*35238bceSAndroid Build Coastguard Worker
2303*35238bceSAndroid Build Coastguard Worker // log
2304*35238bceSAndroid Build Coastguard Worker
2305*35238bceSAndroid Build Coastguard Worker {
2306*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder message(&testCtx.getLog());
2307*35238bceSAndroid Build Coastguard Worker message << "For resource index " << resourceNdx << " (\"" << targetResourceName
2308*35238bceSAndroid Build Coastguard Worker << "\") got following properties:\n";
2309*35238bceSAndroid Build Coastguard Worker
2310*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx)
2311*35238bceSAndroid Build Coastguard Worker message << "\t" << glu::getProgramResourcePropertyName(props[propNdx]) << ":\t"
2312*35238bceSAndroid Build Coastguard Worker << validators[propNdx]->getHumanReadablePropertyString(propValues[propNdx]) << "\n";
2313*35238bceSAndroid Build Coastguard Worker
2314*35238bceSAndroid Build Coastguard Worker message << tcu::TestLog::EndMessage;
2315*35238bceSAndroid Build Coastguard Worker }
2316*35238bceSAndroid Build Coastguard Worker
2317*35238bceSAndroid Build Coastguard Worker // validate
2318*35238bceSAndroid Build Coastguard Worker
2319*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx)
2320*35238bceSAndroid Build Coastguard Worker validators[propNdx]->validate(programDefinition, targetResourceName, propValues[propNdx],
2321*35238bceSAndroid Build Coastguard Worker implementationResourceName);
2322*35238bceSAndroid Build Coastguard Worker }
2323*35238bceSAndroid Build Coastguard Worker
getAndCheckProgramDefinition(void)2324*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *ProgramInterfaceQueryTestCase::getAndCheckProgramDefinition(void)
2325*35238bceSAndroid Build Coastguard Worker {
2326*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *programDefinition = getProgramDefinition();
2327*35238bceSAndroid Build Coastguard Worker DE_ASSERT(programDefinition->isValid());
2328*35238bceSAndroid Build Coastguard Worker
2329*35238bceSAndroid Build Coastguard Worker auto type = m_context.getRenderContext().getType();
2330*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(type, glu::ApiType::es(3, 2)) || glu::contextSupports(type, glu::ApiType::core(4, 5)))
2331*35238bceSAndroid Build Coastguard Worker {
2332*35238bceSAndroid Build Coastguard Worker return programDefinition;
2333*35238bceSAndroid Build Coastguard Worker }
2334*35238bceSAndroid Build Coastguard Worker
2335*35238bceSAndroid Build Coastguard Worker if (programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2336*35238bceSAndroid Build Coastguard Worker programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2337*35238bceSAndroid Build Coastguard Worker {
2338*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2339*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2340*35238bceSAndroid Build Coastguard Worker }
2341*35238bceSAndroid Build Coastguard Worker
2342*35238bceSAndroid Build Coastguard Worker // Testing IS_PER_PATCH as a part of a larger set is ok, since the extension is checked
2343*35238bceSAndroid Build Coastguard Worker // before query. However, we don't want IS_PER_PATCH-specific tests to become noop and pass.
2344*35238bceSAndroid Build Coastguard Worker if (m_queryTarget.propFlags == PROGRAMRESOURCEPROP_IS_PER_PATCH)
2345*35238bceSAndroid Build Coastguard Worker {
2346*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2347*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2348*35238bceSAndroid Build Coastguard Worker }
2349*35238bceSAndroid Build Coastguard Worker
2350*35238bceSAndroid Build Coastguard Worker if (programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY))
2351*35238bceSAndroid Build Coastguard Worker {
2352*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2353*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2354*35238bceSAndroid Build Coastguard Worker }
2355*35238bceSAndroid Build Coastguard Worker
2356*35238bceSAndroid Build Coastguard Worker if (programContainsIOBlocks(programDefinition))
2357*35238bceSAndroid Build Coastguard Worker {
2358*35238bceSAndroid Build Coastguard Worker if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
2359*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
2360*35238bceSAndroid Build Coastguard Worker }
2361*35238bceSAndroid Build Coastguard Worker
2362*35238bceSAndroid Build Coastguard Worker return programDefinition;
2363*35238bceSAndroid Build Coastguard Worker }
2364*35238bceSAndroid Build Coastguard Worker
getMaxPatchVertices(void)2365*35238bceSAndroid Build Coastguard Worker int ProgramInterfaceQueryTestCase::getMaxPatchVertices(void)
2366*35238bceSAndroid Build Coastguard Worker {
2367*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2368*35238bceSAndroid Build Coastguard Worker glw::GLint maxPatchVertices = 0;
2369*35238bceSAndroid Build Coastguard Worker
2370*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
2371*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_MAX_PATCH_VERTICES)");
2372*35238bceSAndroid Build Coastguard Worker return maxPatchVertices;
2373*35238bceSAndroid Build Coastguard Worker }
2374*35238bceSAndroid Build Coastguard Worker
iterate(void)2375*35238bceSAndroid Build Coastguard Worker ProgramInterfaceQueryTestCase::IterateResult ProgramInterfaceQueryTestCase::iterate(void)
2376*35238bceSAndroid Build Coastguard Worker {
2377*35238bceSAndroid Build Coastguard Worker struct TestProperty
2378*35238bceSAndroid Build Coastguard Worker {
2379*35238bceSAndroid Build Coastguard Worker glw::GLenum prop;
2380*35238bceSAndroid Build Coastguard Worker const PropValidator *validator;
2381*35238bceSAndroid Build Coastguard Worker };
2382*35238bceSAndroid Build Coastguard Worker
2383*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *programDefinition = getAndCheckProgramDefinition();
2384*35238bceSAndroid Build Coastguard Worker const std::vector<std::string> targetResources = getQueryTargetResources();
2385*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(programDefinition));
2386*35238bceSAndroid Build Coastguard Worker
2387*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2388*35238bceSAndroid Build Coastguard Worker
2389*35238bceSAndroid Build Coastguard Worker // Log program
2390*35238bceSAndroid Build Coastguard Worker {
2391*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
2392*35238bceSAndroid Build Coastguard Worker
2393*35238bceSAndroid Build Coastguard Worker // Feedback varyings
2394*35238bceSAndroid Build Coastguard Worker if (!programDefinition->getTransformFeedbackVaryings().empty())
2395*35238bceSAndroid Build Coastguard Worker {
2396*35238bceSAndroid Build Coastguard Worker tcu::MessageBuilder builder(&m_testCtx.getLog());
2397*35238bceSAndroid Build Coastguard Worker builder << "Transform feedback varyings: {";
2398*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
2399*35238bceSAndroid Build Coastguard Worker {
2400*35238bceSAndroid Build Coastguard Worker if (ndx)
2401*35238bceSAndroid Build Coastguard Worker builder << ", ";
2402*35238bceSAndroid Build Coastguard Worker builder << "\"" << programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
2403*35238bceSAndroid Build Coastguard Worker }
2404*35238bceSAndroid Build Coastguard Worker builder << "}" << tcu::TestLog::EndMessage;
2405*35238bceSAndroid Build Coastguard Worker }
2406*35238bceSAndroid Build Coastguard Worker
2407*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << program;
2408*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
2409*35238bceSAndroid Build Coastguard Worker {
2410*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
2411*35238bceSAndroid Build Coastguard Worker << "Program build failed, checking if program exceeded implementation limits"
2412*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2413*35238bceSAndroid Build Coastguard Worker checkProgramResourceUsage(programDefinition, m_context.getRenderContext().getFunctions(),
2414*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog());
2415*35238bceSAndroid Build Coastguard Worker
2416*35238bceSAndroid Build Coastguard Worker // within limits
2417*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2418*35238bceSAndroid Build Coastguard Worker }
2419*35238bceSAndroid Build Coastguard Worker }
2420*35238bceSAndroid Build Coastguard Worker
2421*35238bceSAndroid Build Coastguard Worker // Check interface props
2422*35238bceSAndroid Build Coastguard Worker
2423*35238bceSAndroid Build Coastguard Worker switch (m_queryTarget.interface)
2424*35238bceSAndroid Build Coastguard Worker {
2425*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
2426*35238bceSAndroid Build Coastguard Worker {
2427*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter uniformFilter = VariableSearchFilter::createStorageFilter(glu::STORAGE_UNIFORM);
2428*35238bceSAndroid Build Coastguard Worker
2429*35238bceSAndroid Build Coastguard Worker const TypeValidator typeValidator(m_context, program.getProgram(), uniformFilter);
2430*35238bceSAndroid Build Coastguard Worker const ArraySizeValidator arraySizeValidator(m_context, program.getProgram(), -1, uniformFilter);
2431*35238bceSAndroid Build Coastguard Worker const ArrayStrideValidator arrayStrideValidator(m_context, program.getProgram(), uniformFilter);
2432*35238bceSAndroid Build Coastguard Worker const BlockIndexValidator blockIndexValidator(m_context, program.getProgram(), uniformFilter);
2433*35238bceSAndroid Build Coastguard Worker const IsRowMajorValidator isRowMajorValidator(m_context, program.getProgram(), uniformFilter);
2434*35238bceSAndroid Build Coastguard Worker const MatrixStrideValidator matrixStrideValidator(m_context, program.getProgram(), uniformFilter);
2435*35238bceSAndroid Build Coastguard Worker const AtomicCounterBufferIndexVerifier atomicCounterBufferIndexVerifier(m_context, program.getProgram(),
2436*35238bceSAndroid Build Coastguard Worker uniformFilter);
2437*35238bceSAndroid Build Coastguard Worker const LocationValidator locationValidator(m_context, program.getProgram(), uniformFilter);
2438*35238bceSAndroid Build Coastguard Worker const VariableNameLengthValidator nameLengthValidator(m_context, program.getProgram(), uniformFilter);
2439*35238bceSAndroid Build Coastguard Worker const OffsetValidator offsetVerifier(m_context, program.getProgram(), uniformFilter);
2440*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByVertexVerifier(m_context, glu::SHADERTYPE_VERTEX,
2441*35238bceSAndroid Build Coastguard Worker uniformFilter);
2442*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByFragmentVerifier(m_context, glu::SHADERTYPE_FRAGMENT,
2443*35238bceSAndroid Build Coastguard Worker uniformFilter);
2444*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByComputeVerifier(m_context, glu::SHADERTYPE_COMPUTE,
2445*35238bceSAndroid Build Coastguard Worker uniformFilter);
2446*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByGeometryVerifier(m_context, glu::SHADERTYPE_GEOMETRY,
2447*35238bceSAndroid Build Coastguard Worker uniformFilter);
2448*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessControlVerifier(
2449*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_CONTROL, uniformFilter);
2450*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessEvaluationVerifier(
2451*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION, uniformFilter);
2452*35238bceSAndroid Build Coastguard Worker
2453*35238bceSAndroid Build Coastguard Worker const TestProperty allProperties[] = {
2454*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_SIZE, &arraySizeValidator},
2455*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_STRIDE, &arrayStrideValidator},
2456*35238bceSAndroid Build Coastguard Worker {GL_ATOMIC_COUNTER_BUFFER_INDEX, &atomicCounterBufferIndexVerifier},
2457*35238bceSAndroid Build Coastguard Worker {GL_BLOCK_INDEX, &blockIndexValidator},
2458*35238bceSAndroid Build Coastguard Worker {GL_IS_ROW_MAJOR, &isRowMajorValidator},
2459*35238bceSAndroid Build Coastguard Worker {GL_LOCATION, &locationValidator},
2460*35238bceSAndroid Build Coastguard Worker {GL_MATRIX_STRIDE, &matrixStrideValidator},
2461*35238bceSAndroid Build Coastguard Worker {GL_NAME_LENGTH, &nameLengthValidator},
2462*35238bceSAndroid Build Coastguard Worker {GL_OFFSET, &offsetVerifier},
2463*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier},
2464*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier},
2465*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier},
2466*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_GEOMETRY_SHADER, &referencedByGeometryVerifier},
2467*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_CONTROL_SHADER, &referencedByTessControlVerifier},
2468*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, &referencedByTessEvaluationVerifier},
2469*35238bceSAndroid Build Coastguard Worker {GL_TYPE, &typeValidator},
2470*35238bceSAndroid Build Coastguard Worker };
2471*35238bceSAndroid Build Coastguard Worker
2472*35238bceSAndroid Build Coastguard Worker for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
2473*35238bceSAndroid Build Coastguard Worker {
2474*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "UniformResource",
2475*35238bceSAndroid Build Coastguard Worker "Uniform resource \"" + targetResources[targetResourceNdx] + "\"");
2476*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2477*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLenum> props;
2478*35238bceSAndroid Build Coastguard Worker std::vector<const PropValidator *> validators;
2479*35238bceSAndroid Build Coastguard Worker
2480*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
2481*35238bceSAndroid Build Coastguard Worker {
2482*35238bceSAndroid Build Coastguard Worker if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
2483*35238bceSAndroid Build Coastguard Worker allProperties[propNdx].validator->isSupported())
2484*35238bceSAndroid Build Coastguard Worker {
2485*35238bceSAndroid Build Coastguard Worker props.push_back(allProperties[propNdx].prop);
2486*35238bceSAndroid Build Coastguard Worker validators.push_back(allProperties[propNdx].validator);
2487*35238bceSAndroid Build Coastguard Worker }
2488*35238bceSAndroid Build Coastguard Worker }
2489*35238bceSAndroid Build Coastguard Worker
2490*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!props.empty());
2491*35238bceSAndroid Build Coastguard Worker
2492*35238bceSAndroid Build Coastguard Worker queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface,
2493*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
2494*35238bceSAndroid Build Coastguard Worker }
2495*35238bceSAndroid Build Coastguard Worker
2496*35238bceSAndroid Build Coastguard Worker break;
2497*35238bceSAndroid Build Coastguard Worker }
2498*35238bceSAndroid Build Coastguard Worker
2499*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
2500*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
2501*35238bceSAndroid Build Coastguard Worker {
2502*35238bceSAndroid Build Coastguard Worker const glu::Storage storage = (m_queryTarget.interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ?
2503*35238bceSAndroid Build Coastguard Worker (glu::STORAGE_UNIFORM) :
2504*35238bceSAndroid Build Coastguard Worker (glu::STORAGE_BUFFER);
2505*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter blockFilter = VariableSearchFilter::createStorageFilter(storage);
2506*35238bceSAndroid Build Coastguard Worker
2507*35238bceSAndroid Build Coastguard Worker const BlockNameLengthValidator nameLengthValidator(m_context, program.getProgram(), blockFilter);
2508*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByVertexVerifier(m_context, glu::SHADERTYPE_VERTEX,
2509*35238bceSAndroid Build Coastguard Worker blockFilter);
2510*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByFragmentVerifier(m_context, glu::SHADERTYPE_FRAGMENT,
2511*35238bceSAndroid Build Coastguard Worker blockFilter);
2512*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByComputeVerifier(m_context, glu::SHADERTYPE_COMPUTE,
2513*35238bceSAndroid Build Coastguard Worker blockFilter);
2514*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByGeometryVerifier(m_context, glu::SHADERTYPE_GEOMETRY,
2515*35238bceSAndroid Build Coastguard Worker blockFilter);
2516*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByTessControlVerifier(
2517*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_CONTROL, blockFilter);
2518*35238bceSAndroid Build Coastguard Worker const BlockReferencedByShaderValidator referencedByTessEvaluationVerifier(
2519*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION, blockFilter);
2520*35238bceSAndroid Build Coastguard Worker const BufferBindingValidator bufferBindingValidator(m_context, program.getProgram(), blockFilter);
2521*35238bceSAndroid Build Coastguard Worker
2522*35238bceSAndroid Build Coastguard Worker const TestProperty allProperties[] = {
2523*35238bceSAndroid Build Coastguard Worker {GL_NAME_LENGTH, &nameLengthValidator},
2524*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier},
2525*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier},
2526*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier},
2527*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_GEOMETRY_SHADER, &referencedByGeometryVerifier},
2528*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_CONTROL_SHADER, &referencedByTessControlVerifier},
2529*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, &referencedByTessEvaluationVerifier},
2530*35238bceSAndroid Build Coastguard Worker {GL_BUFFER_BINDING, &bufferBindingValidator},
2531*35238bceSAndroid Build Coastguard Worker };
2532*35238bceSAndroid Build Coastguard Worker
2533*35238bceSAndroid Build Coastguard Worker for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
2534*35238bceSAndroid Build Coastguard Worker {
2535*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "BlockResource",
2536*35238bceSAndroid Build Coastguard Worker "Interface block \"" + targetResources[targetResourceNdx] + "\"");
2537*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2538*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLenum> props;
2539*35238bceSAndroid Build Coastguard Worker std::vector<const PropValidator *> validators;
2540*35238bceSAndroid Build Coastguard Worker
2541*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
2542*35238bceSAndroid Build Coastguard Worker {
2543*35238bceSAndroid Build Coastguard Worker if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
2544*35238bceSAndroid Build Coastguard Worker allProperties[propNdx].validator->isSupported())
2545*35238bceSAndroid Build Coastguard Worker {
2546*35238bceSAndroid Build Coastguard Worker props.push_back(allProperties[propNdx].prop);
2547*35238bceSAndroid Build Coastguard Worker validators.push_back(allProperties[propNdx].validator);
2548*35238bceSAndroid Build Coastguard Worker }
2549*35238bceSAndroid Build Coastguard Worker }
2550*35238bceSAndroid Build Coastguard Worker
2551*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!props.empty());
2552*35238bceSAndroid Build Coastguard Worker
2553*35238bceSAndroid Build Coastguard Worker queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface,
2554*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
2555*35238bceSAndroid Build Coastguard Worker }
2556*35238bceSAndroid Build Coastguard Worker
2557*35238bceSAndroid Build Coastguard Worker break;
2558*35238bceSAndroid Build Coastguard Worker }
2559*35238bceSAndroid Build Coastguard Worker
2560*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
2561*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
2562*35238bceSAndroid Build Coastguard Worker {
2563*35238bceSAndroid Build Coastguard Worker const bool isInputCase = (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT);
2564*35238bceSAndroid Build Coastguard Worker const glu::Storage varyingStorage = (isInputCase) ? (glu::STORAGE_IN) : (glu::STORAGE_OUT);
2565*35238bceSAndroid Build Coastguard Worker const glu::Storage patchStorage = (isInputCase) ? (glu::STORAGE_PATCH_IN) : (glu::STORAGE_PATCH_OUT);
2566*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType =
2567*35238bceSAndroid Build Coastguard Worker (isInputCase) ? (programDefinition->getFirstStage()) : (programDefinition->getLastStage());
2568*35238bceSAndroid Build Coastguard Worker const int unsizedArraySize =
2569*35238bceSAndroid Build Coastguard Worker (isInputCase && shaderType == glu::SHADERTYPE_GEOMETRY) ?
2570*35238bceSAndroid Build Coastguard Worker (1) // input points
2571*35238bceSAndroid Build Coastguard Worker :
2572*35238bceSAndroid Build Coastguard Worker (isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ?
2573*35238bceSAndroid Build Coastguard Worker (getMaxPatchVertices()) // input batch size
2574*35238bceSAndroid Build Coastguard Worker :
2575*35238bceSAndroid Build Coastguard Worker (!isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ?
2576*35238bceSAndroid Build Coastguard Worker (programDefinition->getTessellationNumOutputPatchVertices()) // output batch size
2577*35238bceSAndroid Build Coastguard Worker :
2578*35238bceSAndroid Build Coastguard Worker (isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION) ?
2579*35238bceSAndroid Build Coastguard Worker (getMaxPatchVertices()) // input batch size
2580*35238bceSAndroid Build Coastguard Worker :
2581*35238bceSAndroid Build Coastguard Worker (-1);
2582*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter variableFilter = VariableSearchFilter::logicalAnd(
2583*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createShaderTypeFilter(shaderType),
2584*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::logicalOr(VariableSearchFilter::createStorageFilter(varyingStorage),
2585*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createStorageFilter(patchStorage)));
2586*35238bceSAndroid Build Coastguard Worker
2587*35238bceSAndroid Build Coastguard Worker const TypeValidator typeValidator(m_context, program.getProgram(), variableFilter);
2588*35238bceSAndroid Build Coastguard Worker const ArraySizeValidator arraySizeValidator(m_context, program.getProgram(), unsizedArraySize, variableFilter);
2589*35238bceSAndroid Build Coastguard Worker const LocationValidator locationValidator(m_context, program.getProgram(), variableFilter);
2590*35238bceSAndroid Build Coastguard Worker const VariableNameLengthValidator nameLengthValidator(m_context, program.getProgram(), variableFilter);
2591*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByVertexVerifier(m_context, glu::SHADERTYPE_VERTEX,
2592*35238bceSAndroid Build Coastguard Worker variableFilter);
2593*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByFragmentVerifier(m_context, glu::SHADERTYPE_FRAGMENT,
2594*35238bceSAndroid Build Coastguard Worker variableFilter);
2595*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByComputeVerifier(m_context, glu::SHADERTYPE_COMPUTE,
2596*35238bceSAndroid Build Coastguard Worker variableFilter);
2597*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByGeometryVerifier(m_context, glu::SHADERTYPE_GEOMETRY,
2598*35238bceSAndroid Build Coastguard Worker variableFilter);
2599*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessControlVerifier(
2600*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_CONTROL, variableFilter);
2601*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessEvaluationVerifier(
2602*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION, variableFilter);
2603*35238bceSAndroid Build Coastguard Worker const PerPatchValidator perPatchValidator(m_context, program.getProgram(), variableFilter);
2604*35238bceSAndroid Build Coastguard Worker
2605*35238bceSAndroid Build Coastguard Worker const TestProperty allProperties[] = {
2606*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_SIZE, &arraySizeValidator},
2607*35238bceSAndroid Build Coastguard Worker {GL_LOCATION, &locationValidator},
2608*35238bceSAndroid Build Coastguard Worker {GL_NAME_LENGTH, &nameLengthValidator},
2609*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier},
2610*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier},
2611*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier},
2612*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_GEOMETRY_SHADER, &referencedByGeometryVerifier},
2613*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_CONTROL_SHADER, &referencedByTessControlVerifier},
2614*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, &referencedByTessEvaluationVerifier},
2615*35238bceSAndroid Build Coastguard Worker {GL_TYPE, &typeValidator},
2616*35238bceSAndroid Build Coastguard Worker {GL_IS_PER_PATCH, &perPatchValidator},
2617*35238bceSAndroid Build Coastguard Worker };
2618*35238bceSAndroid Build Coastguard Worker
2619*35238bceSAndroid Build Coastguard Worker for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
2620*35238bceSAndroid Build Coastguard Worker {
2621*35238bceSAndroid Build Coastguard Worker const std::string resourceInterfaceName =
2622*35238bceSAndroid Build Coastguard Worker (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? ("Input") : ("Output");
2623*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "BlockResource",
2624*35238bceSAndroid Build Coastguard Worker resourceInterfaceName + " resource \"" +
2625*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx] + "\"");
2626*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2627*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLenum> props;
2628*35238bceSAndroid Build Coastguard Worker std::vector<const PropValidator *> validators;
2629*35238bceSAndroid Build Coastguard Worker
2630*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
2631*35238bceSAndroid Build Coastguard Worker {
2632*35238bceSAndroid Build Coastguard Worker if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
2633*35238bceSAndroid Build Coastguard Worker allProperties[propNdx].validator->isSupported())
2634*35238bceSAndroid Build Coastguard Worker {
2635*35238bceSAndroid Build Coastguard Worker props.push_back(allProperties[propNdx].prop);
2636*35238bceSAndroid Build Coastguard Worker validators.push_back(allProperties[propNdx].validator);
2637*35238bceSAndroid Build Coastguard Worker }
2638*35238bceSAndroid Build Coastguard Worker }
2639*35238bceSAndroid Build Coastguard Worker
2640*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!props.empty());
2641*35238bceSAndroid Build Coastguard Worker
2642*35238bceSAndroid Build Coastguard Worker queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface,
2643*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
2644*35238bceSAndroid Build Coastguard Worker }
2645*35238bceSAndroid Build Coastguard Worker
2646*35238bceSAndroid Build Coastguard Worker break;
2647*35238bceSAndroid Build Coastguard Worker }
2648*35238bceSAndroid Build Coastguard Worker
2649*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
2650*35238bceSAndroid Build Coastguard Worker {
2651*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter variableFilter = VariableSearchFilter::createStorageFilter(glu::STORAGE_BUFFER);
2652*35238bceSAndroid Build Coastguard Worker
2653*35238bceSAndroid Build Coastguard Worker const TypeValidator typeValidator(m_context, program.getProgram(), variableFilter);
2654*35238bceSAndroid Build Coastguard Worker const ArraySizeValidator arraySizeValidator(m_context, program.getProgram(), 0, variableFilter);
2655*35238bceSAndroid Build Coastguard Worker const ArrayStrideValidator arrayStrideValidator(m_context, program.getProgram(), variableFilter);
2656*35238bceSAndroid Build Coastguard Worker const BlockIndexValidator blockIndexValidator(m_context, program.getProgram(), variableFilter);
2657*35238bceSAndroid Build Coastguard Worker const IsRowMajorValidator isRowMajorValidator(m_context, program.getProgram(), variableFilter);
2658*35238bceSAndroid Build Coastguard Worker const MatrixStrideValidator matrixStrideValidator(m_context, program.getProgram(), variableFilter);
2659*35238bceSAndroid Build Coastguard Worker const OffsetValidator offsetValidator(m_context, program.getProgram(), variableFilter);
2660*35238bceSAndroid Build Coastguard Worker const VariableNameLengthValidator nameLengthValidator(m_context, program.getProgram(), variableFilter);
2661*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByVertexVerifier(m_context, glu::SHADERTYPE_VERTEX,
2662*35238bceSAndroid Build Coastguard Worker variableFilter);
2663*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByFragmentVerifier(m_context, glu::SHADERTYPE_FRAGMENT,
2664*35238bceSAndroid Build Coastguard Worker variableFilter);
2665*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByComputeVerifier(m_context, glu::SHADERTYPE_COMPUTE,
2666*35238bceSAndroid Build Coastguard Worker variableFilter);
2667*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByGeometryVerifier(m_context, glu::SHADERTYPE_GEOMETRY,
2668*35238bceSAndroid Build Coastguard Worker variableFilter);
2669*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessControlVerifier(
2670*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_CONTROL, variableFilter);
2671*35238bceSAndroid Build Coastguard Worker const VariableReferencedByShaderValidator referencedByTessEvaluationVerifier(
2672*35238bceSAndroid Build Coastguard Worker m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION, variableFilter);
2673*35238bceSAndroid Build Coastguard Worker const TopLevelArraySizeValidator topLevelArraySizeValidator(m_context, program.getProgram(), variableFilter);
2674*35238bceSAndroid Build Coastguard Worker const TopLevelArrayStrideValidator topLevelArrayStrideValidator(m_context, program.getProgram(),
2675*35238bceSAndroid Build Coastguard Worker variableFilter);
2676*35238bceSAndroid Build Coastguard Worker
2677*35238bceSAndroid Build Coastguard Worker const TestProperty allProperties[] = {
2678*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_SIZE, &arraySizeValidator},
2679*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_STRIDE, &arrayStrideValidator},
2680*35238bceSAndroid Build Coastguard Worker {GL_BLOCK_INDEX, &blockIndexValidator},
2681*35238bceSAndroid Build Coastguard Worker {GL_IS_ROW_MAJOR, &isRowMajorValidator},
2682*35238bceSAndroid Build Coastguard Worker {GL_MATRIX_STRIDE, &matrixStrideValidator},
2683*35238bceSAndroid Build Coastguard Worker {GL_NAME_LENGTH, &nameLengthValidator},
2684*35238bceSAndroid Build Coastguard Worker {GL_OFFSET, &offsetValidator},
2685*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier},
2686*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier},
2687*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier},
2688*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_GEOMETRY_SHADER, &referencedByGeometryVerifier},
2689*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_CONTROL_SHADER, &referencedByTessControlVerifier},
2690*35238bceSAndroid Build Coastguard Worker {GL_REFERENCED_BY_TESS_EVALUATION_SHADER, &referencedByTessEvaluationVerifier},
2691*35238bceSAndroid Build Coastguard Worker {GL_TOP_LEVEL_ARRAY_SIZE, &topLevelArraySizeValidator},
2692*35238bceSAndroid Build Coastguard Worker {GL_TOP_LEVEL_ARRAY_STRIDE, &topLevelArrayStrideValidator},
2693*35238bceSAndroid Build Coastguard Worker {GL_TYPE, &typeValidator},
2694*35238bceSAndroid Build Coastguard Worker };
2695*35238bceSAndroid Build Coastguard Worker
2696*35238bceSAndroid Build Coastguard Worker for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
2697*35238bceSAndroid Build Coastguard Worker {
2698*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "BufferVariableResource",
2699*35238bceSAndroid Build Coastguard Worker "Buffer variable \"" + targetResources[targetResourceNdx] + "\"");
2700*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2701*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLenum> props;
2702*35238bceSAndroid Build Coastguard Worker std::vector<const PropValidator *> validators;
2703*35238bceSAndroid Build Coastguard Worker
2704*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
2705*35238bceSAndroid Build Coastguard Worker {
2706*35238bceSAndroid Build Coastguard Worker if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
2707*35238bceSAndroid Build Coastguard Worker allProperties[propNdx].validator->isSupported())
2708*35238bceSAndroid Build Coastguard Worker {
2709*35238bceSAndroid Build Coastguard Worker props.push_back(allProperties[propNdx].prop);
2710*35238bceSAndroid Build Coastguard Worker validators.push_back(allProperties[propNdx].validator);
2711*35238bceSAndroid Build Coastguard Worker }
2712*35238bceSAndroid Build Coastguard Worker }
2713*35238bceSAndroid Build Coastguard Worker
2714*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!props.empty());
2715*35238bceSAndroid Build Coastguard Worker
2716*35238bceSAndroid Build Coastguard Worker queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface,
2717*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
2718*35238bceSAndroid Build Coastguard Worker }
2719*35238bceSAndroid Build Coastguard Worker
2720*35238bceSAndroid Build Coastguard Worker break;
2721*35238bceSAndroid Build Coastguard Worker }
2722*35238bceSAndroid Build Coastguard Worker
2723*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
2724*35238bceSAndroid Build Coastguard Worker {
2725*35238bceSAndroid Build Coastguard Worker const TransformFeedbackTypeValidator typeValidator(m_context);
2726*35238bceSAndroid Build Coastguard Worker const TransformFeedbackArraySizeValidator arraySizeValidator(m_context);
2727*35238bceSAndroid Build Coastguard Worker const TransformFeedbackNameLengthValidator nameLengthValidator(m_context);
2728*35238bceSAndroid Build Coastguard Worker
2729*35238bceSAndroid Build Coastguard Worker const TestProperty allProperties[] = {
2730*35238bceSAndroid Build Coastguard Worker {GL_ARRAY_SIZE, &arraySizeValidator},
2731*35238bceSAndroid Build Coastguard Worker {GL_NAME_LENGTH, &nameLengthValidator},
2732*35238bceSAndroid Build Coastguard Worker {GL_TYPE, &typeValidator},
2733*35238bceSAndroid Build Coastguard Worker };
2734*35238bceSAndroid Build Coastguard Worker
2735*35238bceSAndroid Build Coastguard Worker for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
2736*35238bceSAndroid Build Coastguard Worker {
2737*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "XFBVariableResource",
2738*35238bceSAndroid Build Coastguard Worker "Transform feedback varying \"" + targetResources[targetResourceNdx] +
2739*35238bceSAndroid Build Coastguard Worker "\"");
2740*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2741*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLenum> props;
2742*35238bceSAndroid Build Coastguard Worker std::vector<const PropValidator *> validators;
2743*35238bceSAndroid Build Coastguard Worker
2744*35238bceSAndroid Build Coastguard Worker for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
2745*35238bceSAndroid Build Coastguard Worker {
2746*35238bceSAndroid Build Coastguard Worker if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
2747*35238bceSAndroid Build Coastguard Worker allProperties[propNdx].validator->isSupported())
2748*35238bceSAndroid Build Coastguard Worker {
2749*35238bceSAndroid Build Coastguard Worker props.push_back(allProperties[propNdx].prop);
2750*35238bceSAndroid Build Coastguard Worker validators.push_back(allProperties[propNdx].validator);
2751*35238bceSAndroid Build Coastguard Worker }
2752*35238bceSAndroid Build Coastguard Worker }
2753*35238bceSAndroid Build Coastguard Worker
2754*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!props.empty());
2755*35238bceSAndroid Build Coastguard Worker
2756*35238bceSAndroid Build Coastguard Worker queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface,
2757*35238bceSAndroid Build Coastguard Worker targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
2758*35238bceSAndroid Build Coastguard Worker }
2759*35238bceSAndroid Build Coastguard Worker
2760*35238bceSAndroid Build Coastguard Worker break;
2761*35238bceSAndroid Build Coastguard Worker }
2762*35238bceSAndroid Build Coastguard Worker
2763*35238bceSAndroid Build Coastguard Worker default:
2764*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2765*35238bceSAndroid Build Coastguard Worker }
2766*35238bceSAndroid Build Coastguard Worker
2767*35238bceSAndroid Build Coastguard Worker return STOP;
2768*35238bceSAndroid Build Coastguard Worker }
2769*35238bceSAndroid Build Coastguard Worker
checkLimit(glw::GLenum pname,int usage,const glw::Functions & gl,tcu::TestLog & log)2770*35238bceSAndroid Build Coastguard Worker static bool checkLimit(glw::GLenum pname, int usage, const glw::Functions &gl, tcu::TestLog &log)
2771*35238bceSAndroid Build Coastguard Worker {
2772*35238bceSAndroid Build Coastguard Worker if (usage > 0)
2773*35238bceSAndroid Build Coastguard Worker {
2774*35238bceSAndroid Build Coastguard Worker glw::GLint limit = 0;
2775*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(pname, &limit);
2776*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "query limits");
2777*35238bceSAndroid Build Coastguard Worker
2778*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "\t" << glu::getGettableStateStr(pname) << " = " << limit << ", test requires "
2779*35238bceSAndroid Build Coastguard Worker << usage << tcu::TestLog::EndMessage;
2780*35238bceSAndroid Build Coastguard Worker
2781*35238bceSAndroid Build Coastguard Worker if (limit < usage)
2782*35238bceSAndroid Build Coastguard Worker {
2783*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "\t\tLimit exceeded" << tcu::TestLog::EndMessage;
2784*35238bceSAndroid Build Coastguard Worker return false;
2785*35238bceSAndroid Build Coastguard Worker }
2786*35238bceSAndroid Build Coastguard Worker }
2787*35238bceSAndroid Build Coastguard Worker
2788*35238bceSAndroid Build Coastguard Worker return true;
2789*35238bceSAndroid Build Coastguard Worker }
2790*35238bceSAndroid Build Coastguard Worker
checkShaderResourceUsage(const ProgramInterfaceDefinition::Program * program,const ProgramInterfaceDefinition::Shader * shader,const glw::Functions & gl,tcu::TestLog & log)2791*35238bceSAndroid Build Coastguard Worker static bool checkShaderResourceUsage(const ProgramInterfaceDefinition::Program *program,
2792*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader, const glw::Functions &gl,
2793*35238bceSAndroid Build Coastguard Worker tcu::TestLog &log)
2794*35238bceSAndroid Build Coastguard Worker {
2795*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::ShaderResourceUsage usage = getShaderResourceUsage(program, shader);
2796*35238bceSAndroid Build Coastguard Worker
2797*35238bceSAndroid Build Coastguard Worker switch (shader->getType())
2798*35238bceSAndroid Build Coastguard Worker {
2799*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
2800*35238bceSAndroid Build Coastguard Worker {
2801*35238bceSAndroid Build Coastguard Worker const struct
2802*35238bceSAndroid Build Coastguard Worker {
2803*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2804*35238bceSAndroid Build Coastguard Worker int usage;
2805*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2806*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_ATTRIBS, usage.numInputVectors},
2807*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2808*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_UNIFORM_VECTORS, usage.numUniformVectors},
2809*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_UNIFORM_BLOCKS, usage.numUniformBlocks},
2810*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_OUTPUT_COMPONENTS, usage.numOutputComponents},
2811*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2812*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2813*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_ATOMIC_COUNTERS, usage.numAtomicCounters},
2814*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_IMAGE_UNIFORMS, usage.numImages},
2815*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents},
2816*35238bceSAndroid Build Coastguard Worker {GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2817*35238bceSAndroid Build Coastguard Worker };
2818*35238bceSAndroid Build Coastguard Worker
2819*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2820*35238bceSAndroid Build Coastguard Worker
2821*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Vertex shader:" << tcu::TestLog::EndMessage;
2822*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2823*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2824*35238bceSAndroid Build Coastguard Worker
2825*35238bceSAndroid Build Coastguard Worker return allOk;
2826*35238bceSAndroid Build Coastguard Worker }
2827*35238bceSAndroid Build Coastguard Worker
2828*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
2829*35238bceSAndroid Build Coastguard Worker {
2830*35238bceSAndroid Build Coastguard Worker const struct
2831*35238bceSAndroid Build Coastguard Worker {
2832*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2833*35238bceSAndroid Build Coastguard Worker int usage;
2834*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2835*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2836*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_UNIFORM_VECTORS, usage.numUniformVectors},
2837*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_UNIFORM_BLOCKS, usage.numUniformBlocks},
2838*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_INPUT_COMPONENTS, usage.numInputComponents},
2839*35238bceSAndroid Build Coastguard Worker {GL_MAX_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2840*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2841*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_ATOMIC_COUNTERS, usage.numAtomicCounters},
2842*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_IMAGE_UNIFORMS, usage.numImages},
2843*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents},
2844*35238bceSAndroid Build Coastguard Worker {GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2845*35238bceSAndroid Build Coastguard Worker };
2846*35238bceSAndroid Build Coastguard Worker
2847*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2848*35238bceSAndroid Build Coastguard Worker
2849*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Fragment shader:" << tcu::TestLog::EndMessage;
2850*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2851*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2852*35238bceSAndroid Build Coastguard Worker
2853*35238bceSAndroid Build Coastguard Worker return allOk;
2854*35238bceSAndroid Build Coastguard Worker }
2855*35238bceSAndroid Build Coastguard Worker
2856*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_COMPUTE:
2857*35238bceSAndroid Build Coastguard Worker {
2858*35238bceSAndroid Build Coastguard Worker const struct
2859*35238bceSAndroid Build Coastguard Worker {
2860*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2861*35238bceSAndroid Build Coastguard Worker int usage;
2862*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2863*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_UNIFORM_BLOCKS, usage.numUniformBlocks},
2864*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2865*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2866*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2867*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_ATOMIC_COUNTERS, usage.numAtomicCounters},
2868*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_IMAGE_UNIFORMS, usage.numImages},
2869*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents},
2870*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2871*35238bceSAndroid Build Coastguard Worker };
2872*35238bceSAndroid Build Coastguard Worker
2873*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2874*35238bceSAndroid Build Coastguard Worker
2875*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Compute shader:" << tcu::TestLog::EndMessage;
2876*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2877*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2878*35238bceSAndroid Build Coastguard Worker
2879*35238bceSAndroid Build Coastguard Worker return allOk;
2880*35238bceSAndroid Build Coastguard Worker }
2881*35238bceSAndroid Build Coastguard Worker
2882*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
2883*35238bceSAndroid Build Coastguard Worker {
2884*35238bceSAndroid Build Coastguard Worker const int totalOutputComponents = program->getGeometryNumOutputVertices() * usage.numOutputComponents;
2885*35238bceSAndroid Build Coastguard Worker const struct
2886*35238bceSAndroid Build Coastguard Worker {
2887*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2888*35238bceSAndroid Build Coastguard Worker int usage;
2889*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2890*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2891*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_UNIFORM_BLOCKS, usage.numUniformBlocks},
2892*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_INPUT_COMPONENTS, usage.numInputComponents},
2893*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, usage.numOutputComponents},
2894*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_OUTPUT_VERTICES, (int)program->getGeometryNumOutputVertices()},
2895*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, totalOutputComponents},
2896*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2897*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2898*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_ATOMIC_COUNTERS, usage.numAtomicCounters},
2899*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_IMAGE_UNIFORMS, usage.numImages},
2900*35238bceSAndroid Build Coastguard Worker {GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2901*35238bceSAndroid Build Coastguard Worker };
2902*35238bceSAndroid Build Coastguard Worker
2903*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2904*35238bceSAndroid Build Coastguard Worker
2905*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Geometry shader:" << tcu::TestLog::EndMessage;
2906*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2907*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2908*35238bceSAndroid Build Coastguard Worker
2909*35238bceSAndroid Build Coastguard Worker return allOk;
2910*35238bceSAndroid Build Coastguard Worker }
2911*35238bceSAndroid Build Coastguard Worker
2912*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
2913*35238bceSAndroid Build Coastguard Worker {
2914*35238bceSAndroid Build Coastguard Worker const int totalOutputComponents = program->getTessellationNumOutputPatchVertices() * usage.numOutputComponents +
2915*35238bceSAndroid Build Coastguard Worker usage.numPatchOutputComponents;
2916*35238bceSAndroid Build Coastguard Worker const struct
2917*35238bceSAndroid Build Coastguard Worker {
2918*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2919*35238bceSAndroid Build Coastguard Worker int usage;
2920*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2921*35238bceSAndroid Build Coastguard Worker {GL_MAX_PATCH_VERTICES, (int)program->getTessellationNumOutputPatchVertices()},
2922*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_PATCH_COMPONENTS, usage.numPatchOutputComponents},
2923*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2924*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, usage.numUniformBlocks},
2925*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, usage.numInputComponents},
2926*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, usage.numOutputComponents},
2927*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, totalOutputComponents},
2928*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2929*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2930*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, usage.numAtomicCounters},
2931*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, usage.numImages},
2932*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2933*35238bceSAndroid Build Coastguard Worker };
2934*35238bceSAndroid Build Coastguard Worker
2935*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2936*35238bceSAndroid Build Coastguard Worker
2937*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Tessellation control shader:" << tcu::TestLog::EndMessage;
2938*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2939*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2940*35238bceSAndroid Build Coastguard Worker
2941*35238bceSAndroid Build Coastguard Worker return allOk;
2942*35238bceSAndroid Build Coastguard Worker }
2943*35238bceSAndroid Build Coastguard Worker
2944*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
2945*35238bceSAndroid Build Coastguard Worker {
2946*35238bceSAndroid Build Coastguard Worker const struct
2947*35238bceSAndroid Build Coastguard Worker {
2948*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2949*35238bceSAndroid Build Coastguard Worker int usage;
2950*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2951*35238bceSAndroid Build Coastguard Worker {GL_MAX_PATCH_VERTICES, (int)program->getTessellationNumOutputPatchVertices()},
2952*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_PATCH_COMPONENTS, usage.numPatchInputComponents},
2953*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents},
2954*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, usage.numUniformBlocks},
2955*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, usage.numInputComponents},
2956*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, usage.numOutputComponents},
2957*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, usage.numSamplers},
2958*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
2959*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, usage.numAtomicCounters},
2960*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, usage.numImages},
2961*35238bceSAndroid Build Coastguard Worker {GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
2962*35238bceSAndroid Build Coastguard Worker };
2963*35238bceSAndroid Build Coastguard Worker
2964*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2965*35238bceSAndroid Build Coastguard Worker
2966*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Tessellation evaluation shader:" << tcu::TestLog::EndMessage;
2967*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
2968*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
2969*35238bceSAndroid Build Coastguard Worker
2970*35238bceSAndroid Build Coastguard Worker return allOk;
2971*35238bceSAndroid Build Coastguard Worker }
2972*35238bceSAndroid Build Coastguard Worker
2973*35238bceSAndroid Build Coastguard Worker default:
2974*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2975*35238bceSAndroid Build Coastguard Worker return false;
2976*35238bceSAndroid Build Coastguard Worker }
2977*35238bceSAndroid Build Coastguard Worker }
2978*35238bceSAndroid Build Coastguard Worker
checkProgramCombinedResourceUsage(const ProgramInterfaceDefinition::Program * program,const glw::Functions & gl,tcu::TestLog & log)2979*35238bceSAndroid Build Coastguard Worker static bool checkProgramCombinedResourceUsage(const ProgramInterfaceDefinition::Program *program,
2980*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl, tcu::TestLog &log)
2981*35238bceSAndroid Build Coastguard Worker {
2982*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::ProgramResourceUsage usage = getCombinedProgramResourceUsage(program);
2983*35238bceSAndroid Build Coastguard Worker
2984*35238bceSAndroid Build Coastguard Worker const struct
2985*35238bceSAndroid Build Coastguard Worker {
2986*35238bceSAndroid Build Coastguard Worker glw::GLenum pname;
2987*35238bceSAndroid Build Coastguard Worker int usage;
2988*35238bceSAndroid Build Coastguard Worker } restrictions[] = {
2989*35238bceSAndroid Build Coastguard Worker {GL_MAX_UNIFORM_BUFFER_BINDINGS, usage.uniformBufferMaxBinding + 1},
2990*35238bceSAndroid Build Coastguard Worker {GL_MAX_UNIFORM_BLOCK_SIZE, usage.uniformBufferMaxSize},
2991*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_UNIFORM_BLOCKS, usage.numUniformBlocks},
2992*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, usage.numCombinedVertexUniformComponents},
2993*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, usage.numCombinedFragmentUniformComponents},
2994*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, usage.numCombinedGeometryUniformComponents},
2995*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, usage.numCombinedTessControlUniformComponents},
2996*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, usage.numCombinedTessEvalUniformComponents},
2997*35238bceSAndroid Build Coastguard Worker {GL_MAX_VARYING_COMPONENTS, usage.numVaryingComponents},
2998*35238bceSAndroid Build Coastguard Worker {GL_MAX_VARYING_VECTORS, usage.numVaryingVectors},
2999*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, usage.numCombinedSamplers},
3000*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, usage.numCombinedOutputResources},
3001*35238bceSAndroid Build Coastguard Worker {GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, usage.atomicCounterBufferMaxBinding + 1},
3002*35238bceSAndroid Build Coastguard Worker {GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, usage.atomicCounterBufferMaxSize},
3003*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers},
3004*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_ATOMIC_COUNTERS, usage.numAtomicCounters},
3005*35238bceSAndroid Build Coastguard Worker {GL_MAX_IMAGE_UNITS, usage.maxImageBinding + 1},
3006*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_IMAGE_UNIFORMS, usage.numCombinedImages},
3007*35238bceSAndroid Build Coastguard Worker {GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, usage.shaderStorageBufferMaxBinding + 1},
3008*35238bceSAndroid Build Coastguard Worker {GL_MAX_SHADER_STORAGE_BLOCK_SIZE, usage.shaderStorageBufferMaxSize},
3009*35238bceSAndroid Build Coastguard Worker {GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks},
3010*35238bceSAndroid Build Coastguard Worker {GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, usage.numXFBInterleavedComponents},
3011*35238bceSAndroid Build Coastguard Worker {GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, usage.numXFBSeparateAttribs},
3012*35238bceSAndroid Build Coastguard Worker {GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, usage.numXFBSeparateComponents},
3013*35238bceSAndroid Build Coastguard Worker {GL_MAX_DRAW_BUFFERS, usage.fragmentOutputMaxBinding + 1},
3014*35238bceSAndroid Build Coastguard Worker };
3015*35238bceSAndroid Build Coastguard Worker
3016*35238bceSAndroid Build Coastguard Worker bool allOk = true;
3017*35238bceSAndroid Build Coastguard Worker
3018*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Program combined:" << tcu::TestLog::EndMessage;
3019*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
3020*35238bceSAndroid Build Coastguard Worker allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);
3021*35238bceSAndroid Build Coastguard Worker
3022*35238bceSAndroid Build Coastguard Worker return allOk;
3023*35238bceSAndroid Build Coastguard Worker }
3024*35238bceSAndroid Build Coastguard Worker
checkProgramResourceUsage(const ProgramInterfaceDefinition::Program * program,const glw::Functions & gl,tcu::TestLog & log)3025*35238bceSAndroid Build Coastguard Worker void checkProgramResourceUsage(const ProgramInterfaceDefinition::Program *program, const glw::Functions &gl,
3026*35238bceSAndroid Build Coastguard Worker tcu::TestLog &log)
3027*35238bceSAndroid Build Coastguard Worker {
3028*35238bceSAndroid Build Coastguard Worker bool limitExceeded = false;
3029*35238bceSAndroid Build Coastguard Worker
3030*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
3031*35238bceSAndroid Build Coastguard Worker limitExceeded |= !checkShaderResourceUsage(program, program->getShaders()[shaderNdx], gl, log);
3032*35238bceSAndroid Build Coastguard Worker
3033*35238bceSAndroid Build Coastguard Worker limitExceeded |= !checkProgramCombinedResourceUsage(program, gl, log);
3034*35238bceSAndroid Build Coastguard Worker
3035*35238bceSAndroid Build Coastguard Worker if (limitExceeded)
3036*35238bceSAndroid Build Coastguard Worker {
3037*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "One or more resource limits exceeded" << tcu::TestLog::EndMessage;
3038*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("one or more resource limits exceeded");
3039*35238bceSAndroid Build Coastguard Worker }
3040*35238bceSAndroid Build Coastguard Worker }
3041*35238bceSAndroid Build Coastguard Worker
3042*35238bceSAndroid Build Coastguard Worker } // namespace Functional
3043*35238bceSAndroid Build Coastguard Worker } // namespace gles31
3044*35238bceSAndroid Build Coastguard Worker } // namespace deqp
3045