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 utilities
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceDefinitionUtil.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es31fProgramInterfaceDefinition.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluVarType.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluVarTypeUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deString.h"
30*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
32*35238bceSAndroid Build Coastguard Worker
33*35238bceSAndroid Build Coastguard Worker #include <set>
34*35238bceSAndroid Build Coastguard Worker #include <map>
35*35238bceSAndroid Build Coastguard Worker #include <sstream>
36*35238bceSAndroid Build Coastguard Worker #include <vector>
37*35238bceSAndroid Build Coastguard Worker #include <algorithm>
38*35238bceSAndroid Build Coastguard Worker
39*35238bceSAndroid Build Coastguard Worker namespace deqp
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace gles31
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace Functional
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker namespace ProgramInterfaceDefinition
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker
VariableSearchFilter(void)48*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::VariableSearchFilter(void) : m_shaderTypeBits(0xFFFFFFFFul), m_storageBits(0xFFFFFFFFul)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker
createShaderTypeFilter(glu::ShaderType type)52*35238bceSAndroid Build Coastguard Worker VariableSearchFilter VariableSearchFilter::createShaderTypeFilter(glu::ShaderType type)
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type < glu::SHADERTYPE_LAST);
55*35238bceSAndroid Build Coastguard Worker
56*35238bceSAndroid Build Coastguard Worker VariableSearchFilter filter;
57*35238bceSAndroid Build Coastguard Worker filter.m_shaderTypeBits = (1u << type);
58*35238bceSAndroid Build Coastguard Worker return filter;
59*35238bceSAndroid Build Coastguard Worker }
60*35238bceSAndroid Build Coastguard Worker
createStorageFilter(glu::Storage storage)61*35238bceSAndroid Build Coastguard Worker VariableSearchFilter VariableSearchFilter::createStorageFilter(glu::Storage storage)
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker DE_ASSERT(storage < glu::STORAGE_LAST);
64*35238bceSAndroid Build Coastguard Worker
65*35238bceSAndroid Build Coastguard Worker VariableSearchFilter filter;
66*35238bceSAndroid Build Coastguard Worker filter.m_storageBits = (1u << storage);
67*35238bceSAndroid Build Coastguard Worker return filter;
68*35238bceSAndroid Build Coastguard Worker }
69*35238bceSAndroid Build Coastguard Worker
createShaderTypeStorageFilter(glu::ShaderType type,glu::Storage storage)70*35238bceSAndroid Build Coastguard Worker VariableSearchFilter VariableSearchFilter::createShaderTypeStorageFilter(glu::ShaderType type, glu::Storage storage)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker return logicalAnd(createShaderTypeFilter(type), createStorageFilter(storage));
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker
logicalOr(const VariableSearchFilter & a,const VariableSearchFilter & b)75*35238bceSAndroid Build Coastguard Worker VariableSearchFilter VariableSearchFilter::logicalOr(const VariableSearchFilter &a, const VariableSearchFilter &b)
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker VariableSearchFilter filter;
78*35238bceSAndroid Build Coastguard Worker filter.m_shaderTypeBits = a.m_shaderTypeBits | b.m_shaderTypeBits;
79*35238bceSAndroid Build Coastguard Worker filter.m_storageBits = a.m_storageBits | b.m_storageBits;
80*35238bceSAndroid Build Coastguard Worker return filter;
81*35238bceSAndroid Build Coastguard Worker }
82*35238bceSAndroid Build Coastguard Worker
logicalAnd(const VariableSearchFilter & a,const VariableSearchFilter & b)83*35238bceSAndroid Build Coastguard Worker VariableSearchFilter VariableSearchFilter::logicalAnd(const VariableSearchFilter &a, const VariableSearchFilter &b)
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker VariableSearchFilter filter;
86*35238bceSAndroid Build Coastguard Worker filter.m_shaderTypeBits = a.m_shaderTypeBits & b.m_shaderTypeBits;
87*35238bceSAndroid Build Coastguard Worker filter.m_storageBits = a.m_storageBits & b.m_storageBits;
88*35238bceSAndroid Build Coastguard Worker return filter;
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker
matchesFilter(const ProgramInterfaceDefinition::Shader * shader) const91*35238bceSAndroid Build Coastguard Worker bool VariableSearchFilter::matchesFilter(const ProgramInterfaceDefinition::Shader *shader) const
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shader->getType() < glu::SHADERTYPE_LAST);
94*35238bceSAndroid Build Coastguard Worker return (m_shaderTypeBits & (1u << shader->getType())) != 0;
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker
matchesFilter(const glu::VariableDeclaration & variable) const97*35238bceSAndroid Build Coastguard Worker bool VariableSearchFilter::matchesFilter(const glu::VariableDeclaration &variable) const
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker DE_ASSERT(variable.storage < glu::STORAGE_LAST);
100*35238bceSAndroid Build Coastguard Worker return (m_storageBits & (1u << variable.storage)) != 0;
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker
matchesFilter(const glu::InterfaceBlock & block) const103*35238bceSAndroid Build Coastguard Worker bool VariableSearchFilter::matchesFilter(const glu::InterfaceBlock &block) const
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker DE_ASSERT(block.storage < glu::STORAGE_LAST);
106*35238bceSAndroid Build Coastguard Worker return (m_storageBits & (1u << block.storage)) != 0;
107*35238bceSAndroid Build Coastguard Worker }
108*35238bceSAndroid Build Coastguard Worker
109*35238bceSAndroid Build Coastguard Worker } // namespace ProgramInterfaceDefinition
110*35238bceSAndroid Build Coastguard Worker
incrementMultiDimensionIndex(std::vector<int> & index,const std::vector<int> & dimensions)111*35238bceSAndroid Build Coastguard Worker static bool incrementMultiDimensionIndex(std::vector<int> &index, const std::vector<int> &dimensions)
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker int incrementDimensionNdx = (int)(index.size() - 1);
114*35238bceSAndroid Build Coastguard Worker
115*35238bceSAndroid Build Coastguard Worker while (incrementDimensionNdx >= 0)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker if (++index[incrementDimensionNdx] == dimensions[incrementDimensionNdx])
118*35238bceSAndroid Build Coastguard Worker index[incrementDimensionNdx--] = 0;
119*35238bceSAndroid Build Coastguard Worker else
120*35238bceSAndroid Build Coastguard Worker break;
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker return (incrementDimensionNdx != -1);
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
programContainsIOBlocks(const ProgramInterfaceDefinition::Program * program)126*35238bceSAndroid Build Coastguard Worker bool programContainsIOBlocks(const ProgramInterfaceDefinition::Program *program)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker if (shaderContainsIOBlocks(program->getShaders()[shaderNdx]))
131*35238bceSAndroid Build Coastguard Worker return true;
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker return false;
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker
shaderContainsIOBlocks(const ProgramInterfaceDefinition::Shader * shader)137*35238bceSAndroid Build Coastguard Worker bool shaderContainsIOBlocks(const ProgramInterfaceDefinition::Shader *shader)
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker const glu::Storage storage = shader->getDefaultBlock().interfaceBlocks[ndx].storage;
142*35238bceSAndroid Build Coastguard Worker if (storage == glu::STORAGE_IN || storage == glu::STORAGE_OUT || storage == glu::STORAGE_PATCH_IN ||
143*35238bceSAndroid Build Coastguard Worker storage == glu::STORAGE_PATCH_OUT)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker return true;
146*35238bceSAndroid Build Coastguard Worker }
147*35238bceSAndroid Build Coastguard Worker }
148*35238bceSAndroid Build Coastguard Worker return false;
149*35238bceSAndroid Build Coastguard Worker }
150*35238bceSAndroid Build Coastguard Worker
getProgramTransformFeedbackStage(const ProgramInterfaceDefinition::Program * program)151*35238bceSAndroid Build Coastguard Worker glu::ShaderType getProgramTransformFeedbackStage(const ProgramInterfaceDefinition::Program *program)
152*35238bceSAndroid Build Coastguard Worker {
153*35238bceSAndroid Build Coastguard Worker if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
154*35238bceSAndroid Build Coastguard Worker return glu::SHADERTYPE_GEOMETRY;
155*35238bceSAndroid Build Coastguard Worker
156*35238bceSAndroid Build Coastguard Worker if (program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
157*35238bceSAndroid Build Coastguard Worker return glu::SHADERTYPE_TESSELLATION_EVALUATION;
158*35238bceSAndroid Build Coastguard Worker
159*35238bceSAndroid Build Coastguard Worker if (program->hasStage(glu::SHADERTYPE_VERTEX))
160*35238bceSAndroid Build Coastguard Worker return glu::SHADERTYPE_VERTEX;
161*35238bceSAndroid Build Coastguard Worker
162*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
163*35238bceSAndroid Build Coastguard Worker return glu::SHADERTYPE_LAST;
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker
generateVariableTypeResourceNames(std::vector<std::string> & resources,const std::string & name,const glu::VarType & type,uint32_t resourceNameGenerationFlags)166*35238bceSAndroid Build Coastguard Worker void generateVariableTypeResourceNames(std::vector<std::string> &resources, const std::string &name,
167*35238bceSAndroid Build Coastguard Worker const glu::VarType &type, uint32_t resourceNameGenerationFlags)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker DE_ASSERT((resourceNameGenerationFlags & (~RESOURCE_NAME_GENERATION_FLAG_MASK)) == 0);
170*35238bceSAndroid Build Coastguard Worker
171*35238bceSAndroid Build Coastguard Worker // remove top-level flag from children
172*35238bceSAndroid Build Coastguard Worker const uint32_t childFlags =
173*35238bceSAndroid Build Coastguard Worker resourceNameGenerationFlags & ~((uint32_t)RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE);
174*35238bceSAndroid Build Coastguard Worker
175*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
176*35238bceSAndroid Build Coastguard Worker resources.push_back(name);
177*35238bceSAndroid Build Coastguard Worker else if (type.isStructType())
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker const glu::StructType *structType = type.getStructPtr();
180*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < structType->getNumMembers(); ++ndx)
181*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, name + "." + structType->getMember(ndx).getName(),
182*35238bceSAndroid Build Coastguard Worker structType->getMember(ndx).getType(), childFlags);
183*35238bceSAndroid Build Coastguard Worker }
184*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
185*35238bceSAndroid Build Coastguard Worker {
186*35238bceSAndroid Build Coastguard Worker // Bottom-level arrays of basic types of a transform feedback variable will produce only the first
187*35238bceSAndroid Build Coastguard Worker // element but without the trailing "[0]"
188*35238bceSAndroid Build Coastguard Worker if (type.getElementType().isBasicType() &&
189*35238bceSAndroid Build Coastguard Worker (resourceNameGenerationFlags & RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE) != 0)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker resources.push_back(name);
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker // Bottom-level arrays of basic types and SSBO top-level arrays of any type procude only first element
194*35238bceSAndroid Build Coastguard Worker else if (type.getElementType().isBasicType() ||
195*35238bceSAndroid Build Coastguard Worker (resourceNameGenerationFlags & RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE) != 0)
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, name + "[0]", type.getElementType(), childFlags);
198*35238bceSAndroid Build Coastguard Worker }
199*35238bceSAndroid Build Coastguard Worker // Other arrays of aggregate types are expanded
200*35238bceSAndroid Build Coastguard Worker else
201*35238bceSAndroid Build Coastguard Worker {
202*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < type.getArraySize(); ++ndx)
203*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, name + "[" + de::toString(ndx) + "]",
204*35238bceSAndroid Build Coastguard Worker type.getElementType(), childFlags);
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker else
208*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker
211*35238bceSAndroid Build Coastguard Worker // Program source generation
212*35238bceSAndroid Build Coastguard Worker
213*35238bceSAndroid Build Coastguard Worker namespace
214*35238bceSAndroid Build Coastguard Worker {
215*35238bceSAndroid Build Coastguard Worker
216*35238bceSAndroid Build Coastguard Worker using ProgramInterfaceDefinition::VariablePathComponent;
217*35238bceSAndroid Build Coastguard Worker using ProgramInterfaceDefinition::VariableSearchFilter;
218*35238bceSAndroid Build Coastguard Worker
getShaderExtensionDeclarations(const ProgramInterfaceDefinition::Shader * shader)219*35238bceSAndroid Build Coastguard Worker static std::string getShaderExtensionDeclarations(const ProgramInterfaceDefinition::Shader *shader)
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker if (shader->getVersion() > glu::GLSL_VERSION_440)
222*35238bceSAndroid Build Coastguard Worker return "";
223*35238bceSAndroid Build Coastguard Worker
224*35238bceSAndroid Build Coastguard Worker std::vector<std::string> extensions;
225*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
226*35238bceSAndroid Build Coastguard Worker
227*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_GEOMETRY)
228*35238bceSAndroid Build Coastguard Worker {
229*35238bceSAndroid Build Coastguard Worker extensions.push_back("GL_EXT_geometry_shader");
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_CONTROL ||
232*35238bceSAndroid Build Coastguard Worker shader->getType() == glu::SHADERTYPE_TESSELLATION_EVALUATION)
233*35238bceSAndroid Build Coastguard Worker {
234*35238bceSAndroid Build Coastguard Worker extensions.push_back("GL_EXT_tessellation_shader");
235*35238bceSAndroid Build Coastguard Worker }
236*35238bceSAndroid Build Coastguard Worker
237*35238bceSAndroid Build Coastguard Worker if (shaderContainsIOBlocks(shader))
238*35238bceSAndroid Build Coastguard Worker extensions.push_back("GL_EXT_shader_io_blocks");
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)extensions.size(); ++ndx)
241*35238bceSAndroid Build Coastguard Worker buf << "#extension " << extensions[ndx] << " : require\n";
242*35238bceSAndroid Build Coastguard Worker return buf.str();
243*35238bceSAndroid Build Coastguard Worker }
244*35238bceSAndroid Build Coastguard Worker
getShaderTypeDeclarations(const ProgramInterfaceDefinition::Program * program,const ProgramInterfaceDefinition::Shader * shader)245*35238bceSAndroid Build Coastguard Worker static std::string getShaderTypeDeclarations(const ProgramInterfaceDefinition::Program *program,
246*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader)
247*35238bceSAndroid Build Coastguard Worker {
248*35238bceSAndroid Build Coastguard Worker glu::ShaderType type = shader->getType();
249*35238bceSAndroid Build Coastguard Worker auto isCoreGL = (shader->getVersion() > glu::GLSL_VERSION_440);
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker switch (type)
252*35238bceSAndroid Build Coastguard Worker {
253*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
254*35238bceSAndroid Build Coastguard Worker if (isCoreGL)
255*35238bceSAndroid Build Coastguard Worker return "out gl_PerVertex { vec4 gl_Position; };\n";
256*35238bceSAndroid Build Coastguard Worker return "";
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
259*35238bceSAndroid Build Coastguard Worker return "";
260*35238bceSAndroid Build Coastguard Worker
261*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
262*35238bceSAndroid Build Coastguard Worker {
263*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
264*35238bceSAndroid Build Coastguard Worker buf << "layout(points) in;\n"
265*35238bceSAndroid Build Coastguard Worker "layout(points, max_vertices="
266*35238bceSAndroid Build Coastguard Worker << program->getGeometryNumOutputVertices() << ") out;\n";
267*35238bceSAndroid Build Coastguard Worker if (isCoreGL)
268*35238bceSAndroid Build Coastguard Worker {
269*35238bceSAndroid Build Coastguard Worker buf << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
270*35238bceSAndroid Build Coastguard Worker "out gl_PerVertex { vec4 gl_Position; };\n";
271*35238bceSAndroid Build Coastguard Worker }
272*35238bceSAndroid Build Coastguard Worker return buf.str();
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker
275*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
276*35238bceSAndroid Build Coastguard Worker {
277*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
278*35238bceSAndroid Build Coastguard Worker buf << "layout(vertices=" << program->getTessellationNumOutputPatchVertices() << ") out;\n";
279*35238bceSAndroid Build Coastguard Worker if (isCoreGL)
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker buf << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
282*35238bceSAndroid Build Coastguard Worker "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n";
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker return buf.str();
285*35238bceSAndroid Build Coastguard Worker }
286*35238bceSAndroid Build Coastguard Worker
287*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
290*35238bceSAndroid Build Coastguard Worker if (isCoreGL)
291*35238bceSAndroid Build Coastguard Worker {
292*35238bceSAndroid Build Coastguard Worker buf << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
293*35238bceSAndroid Build Coastguard Worker "out gl_PerVertex { vec4 gl_Position; };\n";
294*35238bceSAndroid Build Coastguard Worker }
295*35238bceSAndroid Build Coastguard Worker buf << "layout(triangles, point_mode) in;\n";
296*35238bceSAndroid Build Coastguard Worker return buf.str();
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker
299*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_COMPUTE:
300*35238bceSAndroid Build Coastguard Worker return "layout(local_size_x=1) in;\n";
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker default:
303*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
304*35238bceSAndroid Build Coastguard Worker return "";
305*35238bceSAndroid Build Coastguard Worker }
306*35238bceSAndroid Build Coastguard Worker }
307*35238bceSAndroid Build Coastguard Worker
308*35238bceSAndroid Build Coastguard Worker class StructNameEqualPredicate
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker public:
StructNameEqualPredicate(const char * name)311*35238bceSAndroid Build Coastguard Worker StructNameEqualPredicate(const char *name) : m_name(name)
312*35238bceSAndroid Build Coastguard Worker {
313*35238bceSAndroid Build Coastguard Worker }
operator ()(const glu::StructType * type)314*35238bceSAndroid Build Coastguard Worker bool operator()(const glu::StructType *type)
315*35238bceSAndroid Build Coastguard Worker {
316*35238bceSAndroid Build Coastguard Worker return type->hasTypeName() && (deStringEqual(m_name, type->getTypeName()) == true);
317*35238bceSAndroid Build Coastguard Worker }
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker private:
320*35238bceSAndroid Build Coastguard Worker const char *m_name;
321*35238bceSAndroid Build Coastguard Worker };
322*35238bceSAndroid Build Coastguard Worker
collectNamedStructureDefinitions(std::vector<const glu::StructType * > & dst,const glu::VarType & type)323*35238bceSAndroid Build Coastguard Worker static void collectNamedStructureDefinitions(std::vector<const glu::StructType *> &dst, const glu::VarType &type)
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
326*35238bceSAndroid Build Coastguard Worker return;
327*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
328*35238bceSAndroid Build Coastguard Worker return collectNamedStructureDefinitions(dst, type.getElementType());
329*35238bceSAndroid Build Coastguard Worker else if (type.isStructType())
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker if (type.getStructPtr()->hasTypeName())
332*35238bceSAndroid Build Coastguard Worker {
333*35238bceSAndroid Build Coastguard Worker // must be unique (may share the the same struct)
334*35238bceSAndroid Build Coastguard Worker std::vector<const glu::StructType *>::iterator where =
335*35238bceSAndroid Build Coastguard Worker std::find_if(dst.begin(), dst.end(), StructNameEqualPredicate(type.getStructPtr()->getTypeName()));
336*35238bceSAndroid Build Coastguard Worker if (where != dst.end())
337*35238bceSAndroid Build Coastguard Worker {
338*35238bceSAndroid Build Coastguard Worker DE_ASSERT(**where == *type.getStructPtr());
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker // identical type has been added already, types of members must be added too
341*35238bceSAndroid Build Coastguard Worker return;
342*35238bceSAndroid Build Coastguard Worker }
343*35238bceSAndroid Build Coastguard Worker }
344*35238bceSAndroid Build Coastguard Worker
345*35238bceSAndroid Build Coastguard Worker // Add types of members first
346*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
347*35238bceSAndroid Build Coastguard Worker collectNamedStructureDefinitions(dst, type.getStructPtr()->getMember(ndx).getType());
348*35238bceSAndroid Build Coastguard Worker
349*35238bceSAndroid Build Coastguard Worker dst.push_back(type.getStructPtr());
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker else
352*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
353*35238bceSAndroid Build Coastguard Worker }
354*35238bceSAndroid Build Coastguard Worker
writeStructureDefinitions(std::ostringstream & buf,const ProgramInterfaceDefinition::DefaultBlock & defaultBlock)355*35238bceSAndroid Build Coastguard Worker static void writeStructureDefinitions(std::ostringstream &buf,
356*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::DefaultBlock &defaultBlock)
357*35238bceSAndroid Build Coastguard Worker {
358*35238bceSAndroid Build Coastguard Worker std::vector<const glu::StructType *> namedStructs;
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker // Collect all structs in post order
361*35238bceSAndroid Build Coastguard Worker
362*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)defaultBlock.variables.size(); ++ndx)
363*35238bceSAndroid Build Coastguard Worker collectNamedStructureDefinitions(namedStructs, defaultBlock.variables[ndx].varType);
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)defaultBlock.interfaceBlocks.size(); ++blockNdx)
366*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)defaultBlock.interfaceBlocks[blockNdx].variables.size(); ++ndx)
367*35238bceSAndroid Build Coastguard Worker collectNamedStructureDefinitions(namedStructs,
368*35238bceSAndroid Build Coastguard Worker defaultBlock.interfaceBlocks[blockNdx].variables[ndx].varType);
369*35238bceSAndroid Build Coastguard Worker
370*35238bceSAndroid Build Coastguard Worker // Write
371*35238bceSAndroid Build Coastguard Worker
372*35238bceSAndroid Build Coastguard Worker for (int structNdx = 0; structNdx < (int)namedStructs.size(); ++structNdx)
373*35238bceSAndroid Build Coastguard Worker {
374*35238bceSAndroid Build Coastguard Worker buf << "struct " << namedStructs[structNdx]->getTypeName()
375*35238bceSAndroid Build Coastguard Worker << "\n"
376*35238bceSAndroid Build Coastguard Worker "{\n";
377*35238bceSAndroid Build Coastguard Worker
378*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < namedStructs[structNdx]->getNumMembers(); ++memberNdx)
379*35238bceSAndroid Build Coastguard Worker buf << glu::indent(1)
380*35238bceSAndroid Build Coastguard Worker << glu::declare(namedStructs[structNdx]->getMember(memberNdx).getType(),
381*35238bceSAndroid Build Coastguard Worker namedStructs[structNdx]->getMember(memberNdx).getName(), 1)
382*35238bceSAndroid Build Coastguard Worker << ";\n";
383*35238bceSAndroid Build Coastguard Worker
384*35238bceSAndroid Build Coastguard Worker buf << "};\n";
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker
387*35238bceSAndroid Build Coastguard Worker if (!namedStructs.empty())
388*35238bceSAndroid Build Coastguard Worker buf << "\n";
389*35238bceSAndroid Build Coastguard Worker }
390*35238bceSAndroid Build Coastguard Worker
writeInterfaceBlock(std::ostringstream & buf,const glu::InterfaceBlock & interfaceBlock)391*35238bceSAndroid Build Coastguard Worker static void writeInterfaceBlock(std::ostringstream &buf, const glu::InterfaceBlock &interfaceBlock)
392*35238bceSAndroid Build Coastguard Worker {
393*35238bceSAndroid Build Coastguard Worker buf << interfaceBlock.layout;
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker if (interfaceBlock.layout != glu::Layout())
396*35238bceSAndroid Build Coastguard Worker buf << " ";
397*35238bceSAndroid Build Coastguard Worker
398*35238bceSAndroid Build Coastguard Worker buf << glu::getStorageName(interfaceBlock.storage) << " " << interfaceBlock.interfaceName << "\n"
399*35238bceSAndroid Build Coastguard Worker << "{\n";
400*35238bceSAndroid Build Coastguard Worker
401*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)interfaceBlock.variables.size(); ++ndx)
402*35238bceSAndroid Build Coastguard Worker buf << glu::indent(1) << interfaceBlock.variables[ndx] << ";\n";
403*35238bceSAndroid Build Coastguard Worker
404*35238bceSAndroid Build Coastguard Worker buf << "}";
405*35238bceSAndroid Build Coastguard Worker
406*35238bceSAndroid Build Coastguard Worker if (!interfaceBlock.instanceName.empty())
407*35238bceSAndroid Build Coastguard Worker buf << " " << interfaceBlock.instanceName;
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0; dimensionNdx < (int)interfaceBlock.dimensions.size(); ++dimensionNdx)
410*35238bceSAndroid Build Coastguard Worker buf << "[" << interfaceBlock.dimensions[dimensionNdx] << "]";
411*35238bceSAndroid Build Coastguard Worker
412*35238bceSAndroid Build Coastguard Worker buf << ";\n\n";
413*35238bceSAndroid Build Coastguard Worker }
414*35238bceSAndroid Build Coastguard Worker
isReadableInterface(const glu::InterfaceBlock & interface)415*35238bceSAndroid Build Coastguard Worker static bool isReadableInterface(const glu::InterfaceBlock &interface)
416*35238bceSAndroid Build Coastguard Worker {
417*35238bceSAndroid Build Coastguard Worker return interface.storage == glu::STORAGE_UNIFORM || interface.storage == glu::STORAGE_IN ||
418*35238bceSAndroid Build Coastguard Worker interface.storage == glu::STORAGE_PATCH_IN ||
419*35238bceSAndroid Build Coastguard Worker (interface.storage == glu::STORAGE_BUFFER &&
420*35238bceSAndroid Build Coastguard Worker (interface.memoryAccessQualifierFlags & glu::MEMORYACCESSQUALIFIER_WRITEONLY_BIT) == 0);
421*35238bceSAndroid Build Coastguard Worker }
422*35238bceSAndroid Build Coastguard Worker
isWritableInterface(const glu::InterfaceBlock & interface)423*35238bceSAndroid Build Coastguard Worker static bool isWritableInterface(const glu::InterfaceBlock &interface)
424*35238bceSAndroid Build Coastguard Worker {
425*35238bceSAndroid Build Coastguard Worker return interface.storage == glu::STORAGE_OUT || interface.storage == glu::STORAGE_PATCH_OUT ||
426*35238bceSAndroid Build Coastguard Worker (interface.storage == glu::STORAGE_BUFFER &&
427*35238bceSAndroid Build Coastguard Worker (interface.memoryAccessQualifierFlags & glu::MEMORYACCESSQUALIFIER_READONLY_BIT) == 0);
428*35238bceSAndroid Build Coastguard Worker }
429*35238bceSAndroid Build Coastguard Worker
writeVariableReadAccumulateExpression(std::ostringstream & buf,const std::string & accumulatorName,const std::string & name,glu::ShaderType shaderType,glu::Storage storage,const ProgramInterfaceDefinition::Program * program,const glu::VarType & varType)430*35238bceSAndroid Build Coastguard Worker static void writeVariableReadAccumulateExpression(std::ostringstream &buf, const std::string &accumulatorName,
431*35238bceSAndroid Build Coastguard Worker const std::string &name, glu::ShaderType shaderType,
432*35238bceSAndroid Build Coastguard Worker glu::Storage storage,
433*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program,
434*35238bceSAndroid Build Coastguard Worker const glu::VarType &varType)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker if (varType.isBasicType())
437*35238bceSAndroid Build Coastguard Worker {
438*35238bceSAndroid Build Coastguard Worker buf << "\t" << accumulatorName << " += ";
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeScalar(varType.getBasicType()))
441*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(" << name << "))";
442*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeVector(varType.getBasicType()))
443*35238bceSAndroid Build Coastguard Worker buf << "vec4(" << name << ".xyxy)";
444*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeMatrix(varType.getBasicType()))
445*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(" << name << "[0][0]))";
446*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeSamplerMultisample(varType.getBasicType()))
447*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(textureSize(" << name << ").x))";
448*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeSampler(varType.getBasicType()))
449*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(textureSize(" << name << ", 0).x))";
450*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeImage(varType.getBasicType()))
451*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(imageSize(" << name << ").x))";
452*35238bceSAndroid Build Coastguard Worker else if (varType.getBasicType() == glu::TYPE_UINT_ATOMIC_COUNTER)
453*35238bceSAndroid Build Coastguard Worker buf << "vec4(float(atomicCounterIncrement(" << name << ")))";
454*35238bceSAndroid Build Coastguard Worker else
455*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
456*35238bceSAndroid Build Coastguard Worker
457*35238bceSAndroid Build Coastguard Worker buf << ";\n";
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker else if (varType.isStructType())
460*35238bceSAndroid Build Coastguard Worker {
461*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx)
462*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(
463*35238bceSAndroid Build Coastguard Worker buf, accumulatorName, name + "." + varType.getStructPtr()->getMember(ndx).getName(), shaderType,
464*35238bceSAndroid Build Coastguard Worker storage, program, varType.getStructPtr()->getMember(ndx).getType());
465*35238bceSAndroid Build Coastguard Worker }
466*35238bceSAndroid Build Coastguard Worker else if (varType.isArrayType())
467*35238bceSAndroid Build Coastguard Worker {
468*35238bceSAndroid Build Coastguard Worker if (varType.getArraySize() != glu::VarType::UNSIZED_ARRAY)
469*35238bceSAndroid Build Coastguard Worker {
470*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < varType.getArraySize(); ++ndx)
471*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[" + de::toString(ndx) + "]",
472*35238bceSAndroid Build Coastguard Worker shaderType, storage, program, varType.getElementType());
473*35238bceSAndroid Build Coastguard Worker }
474*35238bceSAndroid Build Coastguard Worker else if (storage == glu::STORAGE_BUFFER)
475*35238bceSAndroid Build Coastguard Worker {
476*35238bceSAndroid Build Coastguard Worker // run-time sized array, read arbitrary
477*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[8]", shaderType, storage, program,
478*35238bceSAndroid Build Coastguard Worker varType.getElementType());
479*35238bceSAndroid Build Coastguard Worker }
480*35238bceSAndroid Build Coastguard Worker else
481*35238bceSAndroid Build Coastguard Worker {
482*35238bceSAndroid Build Coastguard Worker DE_ASSERT(storage == glu::STORAGE_IN);
483*35238bceSAndroid Build Coastguard Worker
484*35238bceSAndroid Build Coastguard Worker if (shaderType == glu::SHADERTYPE_GEOMETRY)
485*35238bceSAndroid Build Coastguard Worker {
486*35238bceSAndroid Build Coastguard Worker // implicit sized geometry input array, size = primitive size. Just reading first is enough
487*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[0]", shaderType, storage, program,
488*35238bceSAndroid Build Coastguard Worker varType.getElementType());
489*35238bceSAndroid Build Coastguard Worker }
490*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
491*35238bceSAndroid Build Coastguard Worker {
492*35238bceSAndroid Build Coastguard Worker // implicit sized tessellation input array, size = input patch max size. Just reading current is enough
493*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[gl_InvocationID]", shaderType,
494*35238bceSAndroid Build Coastguard Worker storage, program, varType.getElementType());
495*35238bceSAndroid Build Coastguard Worker }
496*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION)
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker // implicit sized tessellation input array, size = output patch max size. Read all to prevent optimizations
499*35238bceSAndroid Build Coastguard Worker DE_ASSERT(program->getTessellationNumOutputPatchVertices() > 0);
500*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)program->getTessellationNumOutputPatchVertices(); ++ndx)
501*35238bceSAndroid Build Coastguard Worker {
502*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[" + de::toString(ndx) + "]",
503*35238bceSAndroid Build Coastguard Worker shaderType, storage, program, varType.getElementType());
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker }
506*35238bceSAndroid Build Coastguard Worker else
507*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
508*35238bceSAndroid Build Coastguard Worker }
509*35238bceSAndroid Build Coastguard Worker }
510*35238bceSAndroid Build Coastguard Worker else
511*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
512*35238bceSAndroid Build Coastguard Worker }
513*35238bceSAndroid Build Coastguard Worker
writeInterfaceReadAccumulateExpression(std::ostringstream & buf,const std::string & accumulatorName,const glu::InterfaceBlock & block,glu::ShaderType shaderType,const ProgramInterfaceDefinition::Program * program)514*35238bceSAndroid Build Coastguard Worker static void writeInterfaceReadAccumulateExpression(std::ostringstream &buf, const std::string &accumulatorName,
515*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block, glu::ShaderType shaderType,
516*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program)
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker if (block.dimensions.empty())
519*35238bceSAndroid Build Coastguard Worker {
520*35238bceSAndroid Build Coastguard Worker const std::string prefix = (block.instanceName.empty()) ? ("") : (block.instanceName + ".");
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
523*35238bceSAndroid Build Coastguard Worker {
524*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName, prefix + block.variables[ndx].name, shaderType,
525*35238bceSAndroid Build Coastguard Worker block.storage, program, block.variables[ndx].varType);
526*35238bceSAndroid Build Coastguard Worker }
527*35238bceSAndroid Build Coastguard Worker }
528*35238bceSAndroid Build Coastguard Worker else
529*35238bceSAndroid Build Coastguard Worker {
530*35238bceSAndroid Build Coastguard Worker std::vector<int> index(block.dimensions.size(), 0);
531*35238bceSAndroid Build Coastguard Worker
532*35238bceSAndroid Build Coastguard Worker for (;;)
533*35238bceSAndroid Build Coastguard Worker {
534*35238bceSAndroid Build Coastguard Worker // access element
535*35238bceSAndroid Build Coastguard Worker {
536*35238bceSAndroid Build Coastguard Worker std::ostringstream name;
537*35238bceSAndroid Build Coastguard Worker name << block.instanceName;
538*35238bceSAndroid Build Coastguard Worker
539*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0; dimensionNdx < (int)block.dimensions.size(); ++dimensionNdx)
540*35238bceSAndroid Build Coastguard Worker name << "[" << index[dimensionNdx] << "]";
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
543*35238bceSAndroid Build Coastguard Worker {
544*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(buf, accumulatorName,
545*35238bceSAndroid Build Coastguard Worker name.str() + "." + block.variables[ndx].name, shaderType,
546*35238bceSAndroid Build Coastguard Worker block.storage, program, block.variables[ndx].varType);
547*35238bceSAndroid Build Coastguard Worker }
548*35238bceSAndroid Build Coastguard Worker }
549*35238bceSAndroid Build Coastguard Worker
550*35238bceSAndroid Build Coastguard Worker // increment index
551*35238bceSAndroid Build Coastguard Worker if (!incrementMultiDimensionIndex(index, block.dimensions))
552*35238bceSAndroid Build Coastguard Worker break;
553*35238bceSAndroid Build Coastguard Worker }
554*35238bceSAndroid Build Coastguard Worker }
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker
writeVariableWriteExpression(std::ostringstream & buf,const std::string & sourceVec4Name,const std::string & name,glu::ShaderType shaderType,glu::Storage storage,const ProgramInterfaceDefinition::Program * program,const glu::VarType & varType)557*35238bceSAndroid Build Coastguard Worker static void writeVariableWriteExpression(std::ostringstream &buf, const std::string &sourceVec4Name,
558*35238bceSAndroid Build Coastguard Worker const std::string &name, glu::ShaderType shaderType, glu::Storage storage,
559*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program,
560*35238bceSAndroid Build Coastguard Worker const glu::VarType &varType)
561*35238bceSAndroid Build Coastguard Worker {
562*35238bceSAndroid Build Coastguard Worker if (varType.isBasicType())
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker buf << "\t" << name << " = ";
565*35238bceSAndroid Build Coastguard Worker
566*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeScalar(varType.getBasicType()))
567*35238bceSAndroid Build Coastguard Worker buf << glu::getDataTypeName(varType.getBasicType()) << "(" << sourceVec4Name << ".y)";
568*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeVector(varType.getBasicType()) || glu::isDataTypeMatrix(varType.getBasicType()))
569*35238bceSAndroid Build Coastguard Worker buf << glu::getDataTypeName(varType.getBasicType()) << "("
570*35238bceSAndroid Build Coastguard Worker << glu::getDataTypeName(glu::getDataTypeScalarType(varType.getBasicType())) << "(" << sourceVec4Name
571*35238bceSAndroid Build Coastguard Worker << ".y))";
572*35238bceSAndroid Build Coastguard Worker else
573*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
574*35238bceSAndroid Build Coastguard Worker
575*35238bceSAndroid Build Coastguard Worker buf << ";\n";
576*35238bceSAndroid Build Coastguard Worker }
577*35238bceSAndroid Build Coastguard Worker else if (varType.isStructType())
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx)
580*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name,
581*35238bceSAndroid Build Coastguard Worker name + "." + varType.getStructPtr()->getMember(ndx).getName(), shaderType,
582*35238bceSAndroid Build Coastguard Worker storage, program, varType.getStructPtr()->getMember(ndx).getType());
583*35238bceSAndroid Build Coastguard Worker }
584*35238bceSAndroid Build Coastguard Worker else if (varType.isArrayType())
585*35238bceSAndroid Build Coastguard Worker {
586*35238bceSAndroid Build Coastguard Worker if (varType.getArraySize() != glu::VarType::UNSIZED_ARRAY)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < varType.getArraySize(); ++ndx)
589*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name, name + "[" + de::toString(ndx) + "]", shaderType,
590*35238bceSAndroid Build Coastguard Worker storage, program, varType.getElementType());
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker else if (storage == glu::STORAGE_BUFFER)
593*35238bceSAndroid Build Coastguard Worker {
594*35238bceSAndroid Build Coastguard Worker // run-time sized array, write arbitrary
595*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name, name + "[9]", shaderType, storage, program,
596*35238bceSAndroid Build Coastguard Worker varType.getElementType());
597*35238bceSAndroid Build Coastguard Worker }
598*35238bceSAndroid Build Coastguard Worker else
599*35238bceSAndroid Build Coastguard Worker {
600*35238bceSAndroid Build Coastguard Worker DE_ASSERT(storage == glu::STORAGE_OUT);
601*35238bceSAndroid Build Coastguard Worker
602*35238bceSAndroid Build Coastguard Worker if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker // implicit sized tessellation onput array, size = output patch max size. Can only write to gl_InvocationID
605*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name, name + "[gl_InvocationID]", shaderType, storage,
606*35238bceSAndroid Build Coastguard Worker program, varType.getElementType());
607*35238bceSAndroid Build Coastguard Worker }
608*35238bceSAndroid Build Coastguard Worker else
609*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
610*35238bceSAndroid Build Coastguard Worker }
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker else
613*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
614*35238bceSAndroid Build Coastguard Worker }
615*35238bceSAndroid Build Coastguard Worker
writeInterfaceWriteExpression(std::ostringstream & buf,const std::string & sourceVec4Name,const glu::InterfaceBlock & block,glu::ShaderType shaderType,const ProgramInterfaceDefinition::Program * program)616*35238bceSAndroid Build Coastguard Worker static void writeInterfaceWriteExpression(std::ostringstream &buf, const std::string &sourceVec4Name,
617*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &block, glu::ShaderType shaderType,
618*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program)
619*35238bceSAndroid Build Coastguard Worker {
620*35238bceSAndroid Build Coastguard Worker if (block.dimensions.empty())
621*35238bceSAndroid Build Coastguard Worker {
622*35238bceSAndroid Build Coastguard Worker const std::string prefix = (block.instanceName.empty()) ? ("") : (block.instanceName + ".");
623*35238bceSAndroid Build Coastguard Worker
624*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
625*35238bceSAndroid Build Coastguard Worker {
626*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name, prefix + block.variables[ndx].name, shaderType,
627*35238bceSAndroid Build Coastguard Worker block.storage, program, block.variables[ndx].varType);
628*35238bceSAndroid Build Coastguard Worker }
629*35238bceSAndroid Build Coastguard Worker }
630*35238bceSAndroid Build Coastguard Worker else
631*35238bceSAndroid Build Coastguard Worker {
632*35238bceSAndroid Build Coastguard Worker std::vector<int> index(block.dimensions.size(), 0);
633*35238bceSAndroid Build Coastguard Worker
634*35238bceSAndroid Build Coastguard Worker for (;;)
635*35238bceSAndroid Build Coastguard Worker {
636*35238bceSAndroid Build Coastguard Worker // access element
637*35238bceSAndroid Build Coastguard Worker {
638*35238bceSAndroid Build Coastguard Worker std::ostringstream name;
639*35238bceSAndroid Build Coastguard Worker name << block.instanceName;
640*35238bceSAndroid Build Coastguard Worker
641*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0; dimensionNdx < (int)block.dimensions.size(); ++dimensionNdx)
642*35238bceSAndroid Build Coastguard Worker name << "[" << index[dimensionNdx] << "]";
643*35238bceSAndroid Build Coastguard Worker
644*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
645*35238bceSAndroid Build Coastguard Worker {
646*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(buf, sourceVec4Name, name.str() + "." + block.variables[ndx].name,
647*35238bceSAndroid Build Coastguard Worker shaderType, block.storage, program, block.variables[ndx].varType);
648*35238bceSAndroid Build Coastguard Worker }
649*35238bceSAndroid Build Coastguard Worker }
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker // increment index
652*35238bceSAndroid Build Coastguard Worker if (!incrementMultiDimensionIndex(index, block.dimensions))
653*35238bceSAndroid Build Coastguard Worker break;
654*35238bceSAndroid Build Coastguard Worker }
655*35238bceSAndroid Build Coastguard Worker }
656*35238bceSAndroid Build Coastguard Worker }
657*35238bceSAndroid Build Coastguard Worker
traverseVariablePath(std::vector<VariablePathComponent> & typePath,const char * subPath,const glu::VarType & type)658*35238bceSAndroid Build Coastguard Worker static bool traverseVariablePath(std::vector<VariablePathComponent> &typePath, const char *subPath,
659*35238bceSAndroid Build Coastguard Worker const glu::VarType &type)
660*35238bceSAndroid Build Coastguard Worker {
661*35238bceSAndroid Build Coastguard Worker glu::VarTokenizer tokenizer(subPath);
662*35238bceSAndroid Build Coastguard Worker
663*35238bceSAndroid Build Coastguard Worker typePath.push_back(VariablePathComponent(&type));
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker if (tokenizer.getToken() == glu::VarTokenizer::TOKEN_END)
666*35238bceSAndroid Build Coastguard Worker return true;
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker if (type.isStructType() && tokenizer.getToken() == glu::VarTokenizer::TOKEN_PERIOD)
669*35238bceSAndroid Build Coastguard Worker {
670*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
671*35238bceSAndroid Build Coastguard Worker
672*35238bceSAndroid Build Coastguard Worker // malformed path
673*35238bceSAndroid Build Coastguard Worker if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_IDENTIFIER)
674*35238bceSAndroid Build Coastguard Worker return false;
675*35238bceSAndroid Build Coastguard Worker
676*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < type.getStructPtr()->getNumMembers(); ++memberNdx)
677*35238bceSAndroid Build Coastguard Worker if (type.getStructPtr()->getMember(memberNdx).getName() == tokenizer.getIdentifier())
678*35238bceSAndroid Build Coastguard Worker return traverseVariablePath(typePath, subPath + tokenizer.getCurrentTokenEndLocation(),
679*35238bceSAndroid Build Coastguard Worker type.getStructPtr()->getMember(memberNdx).getType());
680*35238bceSAndroid Build Coastguard Worker
681*35238bceSAndroid Build Coastguard Worker // malformed path, no such member
682*35238bceSAndroid Build Coastguard Worker return false;
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType() && tokenizer.getToken() == glu::VarTokenizer::TOKEN_LEFT_BRACKET)
685*35238bceSAndroid Build Coastguard Worker {
686*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
687*35238bceSAndroid Build Coastguard Worker
688*35238bceSAndroid Build Coastguard Worker // malformed path
689*35238bceSAndroid Build Coastguard Worker if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_NUMBER)
690*35238bceSAndroid Build Coastguard Worker return false;
691*35238bceSAndroid Build Coastguard Worker
692*35238bceSAndroid Build Coastguard Worker tokenizer.advance();
693*35238bceSAndroid Build Coastguard Worker if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_RIGHT_BRACKET)
694*35238bceSAndroid Build Coastguard Worker return false;
695*35238bceSAndroid Build Coastguard Worker
696*35238bceSAndroid Build Coastguard Worker return traverseVariablePath(typePath, subPath + tokenizer.getCurrentTokenEndLocation(), type.getElementType());
697*35238bceSAndroid Build Coastguard Worker }
698*35238bceSAndroid Build Coastguard Worker
699*35238bceSAndroid Build Coastguard Worker return false;
700*35238bceSAndroid Build Coastguard Worker }
701*35238bceSAndroid Build Coastguard Worker
traverseVariablePath(std::vector<VariablePathComponent> & typePath,const std::string & path,const glu::VariableDeclaration & var)702*35238bceSAndroid Build Coastguard Worker static bool traverseVariablePath(std::vector<VariablePathComponent> &typePath, const std::string &path,
703*35238bceSAndroid Build Coastguard Worker const glu::VariableDeclaration &var)
704*35238bceSAndroid Build Coastguard Worker {
705*35238bceSAndroid Build Coastguard Worker if (glu::parseVariableName(path.c_str()) != var.name)
706*35238bceSAndroid Build Coastguard Worker return false;
707*35238bceSAndroid Build Coastguard Worker
708*35238bceSAndroid Build Coastguard Worker typePath.push_back(VariablePathComponent(&var));
709*35238bceSAndroid Build Coastguard Worker return traverseVariablePath(typePath, path.c_str() + var.name.length(), var.varType);
710*35238bceSAndroid Build Coastguard Worker }
711*35238bceSAndroid Build Coastguard Worker
traverseShaderVariablePath(std::vector<VariablePathComponent> & typePath,const ProgramInterfaceDefinition::Shader * shader,const std::string & path,const VariableSearchFilter & filter)712*35238bceSAndroid Build Coastguard Worker static bool traverseShaderVariablePath(std::vector<VariablePathComponent> &typePath,
713*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader, const std::string &path,
714*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker // Default block variable?
717*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx)
718*35238bceSAndroid Build Coastguard Worker if (filter.matchesFilter(shader->getDefaultBlock().variables[varNdx]))
719*35238bceSAndroid Build Coastguard Worker if (traverseVariablePath(typePath, path, shader->getDefaultBlock().variables[varNdx]))
720*35238bceSAndroid Build Coastguard Worker return true;
721*35238bceSAndroid Build Coastguard Worker
722*35238bceSAndroid Build Coastguard Worker // is variable an interface block variable?
723*35238bceSAndroid Build Coastguard Worker {
724*35238bceSAndroid Build Coastguard Worker const std::string blockName = glu::parseVariableName(path.c_str());
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
727*35238bceSAndroid Build Coastguard Worker {
728*35238bceSAndroid Build Coastguard Worker if (!filter.matchesFilter(shader->getDefaultBlock().interfaceBlocks[interfaceNdx]))
729*35238bceSAndroid Build Coastguard Worker continue;
730*35238bceSAndroid Build Coastguard Worker
731*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
732*35238bceSAndroid Build Coastguard Worker {
733*35238bceSAndroid Build Coastguard Worker // resource is a member of a named interface block
734*35238bceSAndroid Build Coastguard Worker // \note there is no array index specifier even if the interface is declared as an array of instances
735*35238bceSAndroid Build Coastguard Worker const std::string blockMemberPath = path.substr(blockName.size() + 1);
736*35238bceSAndroid Build Coastguard Worker const std::string blockMemeberName = glu::parseVariableName(blockMemberPath.c_str());
737*35238bceSAndroid Build Coastguard Worker
738*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0;
739*35238bceSAndroid Build Coastguard Worker varNdx < (int)shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables.size(); ++varNdx)
740*35238bceSAndroid Build Coastguard Worker {
741*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx].name ==
742*35238bceSAndroid Build Coastguard Worker blockMemeberName)
743*35238bceSAndroid Build Coastguard Worker {
744*35238bceSAndroid Build Coastguard Worker typePath.push_back(
745*35238bceSAndroid Build Coastguard Worker VariablePathComponent(&shader->getDefaultBlock().interfaceBlocks[interfaceNdx]));
746*35238bceSAndroid Build Coastguard Worker return traverseVariablePath(
747*35238bceSAndroid Build Coastguard Worker typePath, blockMemberPath,
748*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx]);
749*35238bceSAndroid Build Coastguard Worker }
750*35238bceSAndroid Build Coastguard Worker }
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker // terminate search
753*35238bceSAndroid Build Coastguard Worker return false;
754*35238bceSAndroid Build Coastguard Worker }
755*35238bceSAndroid Build Coastguard Worker else if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].instanceName.empty())
756*35238bceSAndroid Build Coastguard Worker {
757*35238bceSAndroid Build Coastguard Worker const std::string blockMemeberName = glu::parseVariableName(path.c_str());
758*35238bceSAndroid Build Coastguard Worker
759*35238bceSAndroid Build Coastguard Worker // unnamed block contains such variable?
760*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0;
761*35238bceSAndroid Build Coastguard Worker varNdx < (int)shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables.size(); ++varNdx)
762*35238bceSAndroid Build Coastguard Worker {
763*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx].name ==
764*35238bceSAndroid Build Coastguard Worker blockMemeberName)
765*35238bceSAndroid Build Coastguard Worker {
766*35238bceSAndroid Build Coastguard Worker typePath.push_back(
767*35238bceSAndroid Build Coastguard Worker VariablePathComponent(&shader->getDefaultBlock().interfaceBlocks[interfaceNdx]));
768*35238bceSAndroid Build Coastguard Worker return traverseVariablePath(
769*35238bceSAndroid Build Coastguard Worker typePath, path, shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx]);
770*35238bceSAndroid Build Coastguard Worker }
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker
773*35238bceSAndroid Build Coastguard Worker // continue search
774*35238bceSAndroid Build Coastguard Worker }
775*35238bceSAndroid Build Coastguard Worker }
776*35238bceSAndroid Build Coastguard Worker }
777*35238bceSAndroid Build Coastguard Worker
778*35238bceSAndroid Build Coastguard Worker return false;
779*35238bceSAndroid Build Coastguard Worker }
780*35238bceSAndroid Build Coastguard Worker
traverseProgramVariablePath(std::vector<VariablePathComponent> & typePath,const ProgramInterfaceDefinition::Program * program,const std::string & path,const VariableSearchFilter & filter)781*35238bceSAndroid Build Coastguard Worker static bool traverseProgramVariablePath(std::vector<VariablePathComponent> &typePath,
782*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program, const std::string &path,
783*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
784*35238bceSAndroid Build Coastguard Worker {
785*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
786*35238bceSAndroid Build Coastguard Worker {
787*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader = program->getShaders()[shaderNdx];
788*35238bceSAndroid Build Coastguard Worker
789*35238bceSAndroid Build Coastguard Worker if (filter.matchesFilter(shader))
790*35238bceSAndroid Build Coastguard Worker {
791*35238bceSAndroid Build Coastguard Worker // \note modifying output variable even when returning false
792*35238bceSAndroid Build Coastguard Worker typePath.clear();
793*35238bceSAndroid Build Coastguard Worker if (traverseShaderVariablePath(typePath, shader, path, filter))
794*35238bceSAndroid Build Coastguard Worker return true;
795*35238bceSAndroid Build Coastguard Worker }
796*35238bceSAndroid Build Coastguard Worker }
797*35238bceSAndroid Build Coastguard Worker
798*35238bceSAndroid Build Coastguard Worker return false;
799*35238bceSAndroid Build Coastguard Worker }
800*35238bceSAndroid Build Coastguard Worker
containsSubType(const glu::VarType & complexType,glu::DataType basicType)801*35238bceSAndroid Build Coastguard Worker static bool containsSubType(const glu::VarType &complexType, glu::DataType basicType)
802*35238bceSAndroid Build Coastguard Worker {
803*35238bceSAndroid Build Coastguard Worker if (complexType.isBasicType())
804*35238bceSAndroid Build Coastguard Worker {
805*35238bceSAndroid Build Coastguard Worker return complexType.getBasicType() == basicType;
806*35238bceSAndroid Build Coastguard Worker }
807*35238bceSAndroid Build Coastguard Worker else if (complexType.isArrayType())
808*35238bceSAndroid Build Coastguard Worker {
809*35238bceSAndroid Build Coastguard Worker return containsSubType(complexType.getElementType(), basicType);
810*35238bceSAndroid Build Coastguard Worker }
811*35238bceSAndroid Build Coastguard Worker else if (complexType.isStructType())
812*35238bceSAndroid Build Coastguard Worker {
813*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < complexType.getStructPtr()->getNumMembers(); ++ndx)
814*35238bceSAndroid Build Coastguard Worker if (containsSubType(complexType.getStructPtr()->getMember(ndx).getType(), basicType))
815*35238bceSAndroid Build Coastguard Worker return true;
816*35238bceSAndroid Build Coastguard Worker return false;
817*35238bceSAndroid Build Coastguard Worker }
818*35238bceSAndroid Build Coastguard Worker else
819*35238bceSAndroid Build Coastguard Worker {
820*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
821*35238bceSAndroid Build Coastguard Worker return false;
822*35238bceSAndroid Build Coastguard Worker }
823*35238bceSAndroid Build Coastguard Worker }
824*35238bceSAndroid Build Coastguard Worker
getNumShaderBlocks(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)825*35238bceSAndroid Build Coastguard Worker static int getNumShaderBlocks(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
826*35238bceSAndroid Build Coastguard Worker {
827*35238bceSAndroid Build Coastguard Worker int retVal = 0;
828*35238bceSAndroid Build Coastguard Worker
829*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
830*35238bceSAndroid Build Coastguard Worker {
831*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage)
832*35238bceSAndroid Build Coastguard Worker {
833*35238bceSAndroid Build Coastguard Worker int numInstances = 1;
834*35238bceSAndroid Build Coastguard Worker
835*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0;
836*35238bceSAndroid Build Coastguard Worker dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx)
837*35238bceSAndroid Build Coastguard Worker numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx];
838*35238bceSAndroid Build Coastguard Worker
839*35238bceSAndroid Build Coastguard Worker retVal += numInstances;
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker }
842*35238bceSAndroid Build Coastguard Worker
843*35238bceSAndroid Build Coastguard Worker return retVal;
844*35238bceSAndroid Build Coastguard Worker }
845*35238bceSAndroid Build Coastguard Worker
getNumAtomicCounterBuffers(const ProgramInterfaceDefinition::Shader * shader)846*35238bceSAndroid Build Coastguard Worker static int getNumAtomicCounterBuffers(const ProgramInterfaceDefinition::Shader *shader)
847*35238bceSAndroid Build Coastguard Worker {
848*35238bceSAndroid Build Coastguard Worker std::set<int> buffers;
849*35238bceSAndroid Build Coastguard Worker
850*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
851*35238bceSAndroid Build Coastguard Worker {
852*35238bceSAndroid Build Coastguard Worker if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER))
853*35238bceSAndroid Build Coastguard Worker {
854*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1);
855*35238bceSAndroid Build Coastguard Worker buffers.insert(shader->getDefaultBlock().variables[ndx].layout.binding);
856*35238bceSAndroid Build Coastguard Worker }
857*35238bceSAndroid Build Coastguard Worker }
858*35238bceSAndroid Build Coastguard Worker
859*35238bceSAndroid Build Coastguard Worker return (int)buffers.size();
860*35238bceSAndroid Build Coastguard Worker }
861*35238bceSAndroid Build Coastguard Worker
862*35238bceSAndroid Build Coastguard Worker template <typename DataTypeMap>
accumulateComplexType(const glu::VarType & complexType,const DataTypeMap & dTypeMap)863*35238bceSAndroid Build Coastguard Worker static int accumulateComplexType(const glu::VarType &complexType, const DataTypeMap &dTypeMap)
864*35238bceSAndroid Build Coastguard Worker {
865*35238bceSAndroid Build Coastguard Worker if (complexType.isBasicType())
866*35238bceSAndroid Build Coastguard Worker return dTypeMap(complexType.getBasicType());
867*35238bceSAndroid Build Coastguard Worker else if (complexType.isArrayType())
868*35238bceSAndroid Build Coastguard Worker {
869*35238bceSAndroid Build Coastguard Worker const int arraySize =
870*35238bceSAndroid Build Coastguard Worker (complexType.getArraySize() == glu::VarType::UNSIZED_ARRAY) ? (1) : (complexType.getArraySize());
871*35238bceSAndroid Build Coastguard Worker return arraySize * accumulateComplexType(complexType.getElementType(), dTypeMap);
872*35238bceSAndroid Build Coastguard Worker }
873*35238bceSAndroid Build Coastguard Worker else if (complexType.isStructType())
874*35238bceSAndroid Build Coastguard Worker {
875*35238bceSAndroid Build Coastguard Worker int sum = 0;
876*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < complexType.getStructPtr()->getNumMembers(); ++ndx)
877*35238bceSAndroid Build Coastguard Worker sum += accumulateComplexType(complexType.getStructPtr()->getMember(ndx).getType(), dTypeMap);
878*35238bceSAndroid Build Coastguard Worker return sum;
879*35238bceSAndroid Build Coastguard Worker }
880*35238bceSAndroid Build Coastguard Worker else
881*35238bceSAndroid Build Coastguard Worker {
882*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
883*35238bceSAndroid Build Coastguard Worker return false;
884*35238bceSAndroid Build Coastguard Worker }
885*35238bceSAndroid Build Coastguard Worker }
886*35238bceSAndroid Build Coastguard Worker
887*35238bceSAndroid Build Coastguard Worker template <typename InterfaceBlockFilter, typename VarDeclFilter, typename DataTypeMap>
accumulateShader(const ProgramInterfaceDefinition::Shader * shader,const InterfaceBlockFilter & ibFilter,const VarDeclFilter & vdFilter,const DataTypeMap & dMap)888*35238bceSAndroid Build Coastguard Worker static int accumulateShader(const ProgramInterfaceDefinition::Shader *shader, const InterfaceBlockFilter &ibFilter,
889*35238bceSAndroid Build Coastguard Worker const VarDeclFilter &vdFilter, const DataTypeMap &dMap)
890*35238bceSAndroid Build Coastguard Worker {
891*35238bceSAndroid Build Coastguard Worker int retVal = 0;
892*35238bceSAndroid Build Coastguard Worker
893*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
894*35238bceSAndroid Build Coastguard Worker {
895*35238bceSAndroid Build Coastguard Worker if (ibFilter(shader->getDefaultBlock().interfaceBlocks[ndx]))
896*35238bceSAndroid Build Coastguard Worker {
897*35238bceSAndroid Build Coastguard Worker int numInstances = 1;
898*35238bceSAndroid Build Coastguard Worker
899*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0;
900*35238bceSAndroid Build Coastguard Worker dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx)
901*35238bceSAndroid Build Coastguard Worker numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx];
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].variables.size();
904*35238bceSAndroid Build Coastguard Worker ++varNdx)
905*35238bceSAndroid Build Coastguard Worker retVal +=
906*35238bceSAndroid Build Coastguard Worker numInstances * accumulateComplexType(
907*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().interfaceBlocks[ndx].variables[varNdx].varType, dMap);
908*35238bceSAndroid Build Coastguard Worker }
909*35238bceSAndroid Build Coastguard Worker }
910*35238bceSAndroid Build Coastguard Worker
911*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx)
912*35238bceSAndroid Build Coastguard Worker if (vdFilter(shader->getDefaultBlock().variables[varNdx]))
913*35238bceSAndroid Build Coastguard Worker retVal += accumulateComplexType(shader->getDefaultBlock().variables[varNdx].varType, dMap);
914*35238bceSAndroid Build Coastguard Worker
915*35238bceSAndroid Build Coastguard Worker return retVal;
916*35238bceSAndroid Build Coastguard Worker }
917*35238bceSAndroid Build Coastguard Worker
unusedTrueConstantTypeFilter(glu::DataType d)918*35238bceSAndroid Build Coastguard Worker static bool unusedTrueConstantTypeFilter(glu::DataType d)
919*35238bceSAndroid Build Coastguard Worker {
920*35238bceSAndroid Build Coastguard Worker DE_UNREF(d);
921*35238bceSAndroid Build Coastguard Worker return true;
922*35238bceSAndroid Build Coastguard Worker }
923*35238bceSAndroid Build Coastguard Worker
924*35238bceSAndroid Build Coastguard Worker class InstanceCounter
925*35238bceSAndroid Build Coastguard Worker {
926*35238bceSAndroid Build Coastguard Worker public:
InstanceCounter(bool (* predicate)(glu::DataType))927*35238bceSAndroid Build Coastguard Worker InstanceCounter(bool (*predicate)(glu::DataType)) : m_predicate(predicate)
928*35238bceSAndroid Build Coastguard Worker {
929*35238bceSAndroid Build Coastguard Worker }
930*35238bceSAndroid Build Coastguard Worker
operator ()(glu::DataType t) const931*35238bceSAndroid Build Coastguard Worker int operator()(glu::DataType t) const
932*35238bceSAndroid Build Coastguard Worker {
933*35238bceSAndroid Build Coastguard Worker return (m_predicate(t)) ? (1) : (0);
934*35238bceSAndroid Build Coastguard Worker }
935*35238bceSAndroid Build Coastguard Worker
936*35238bceSAndroid Build Coastguard Worker private:
937*35238bceSAndroid Build Coastguard Worker bool (*const m_predicate)(glu::DataType);
938*35238bceSAndroid Build Coastguard Worker };
939*35238bceSAndroid Build Coastguard Worker
940*35238bceSAndroid Build Coastguard Worker class InterfaceBlockStorageFilter
941*35238bceSAndroid Build Coastguard Worker {
942*35238bceSAndroid Build Coastguard Worker public:
InterfaceBlockStorageFilter(glu::Storage storage)943*35238bceSAndroid Build Coastguard Worker InterfaceBlockStorageFilter(glu::Storage storage) : m_storage(storage)
944*35238bceSAndroid Build Coastguard Worker {
945*35238bceSAndroid Build Coastguard Worker }
946*35238bceSAndroid Build Coastguard Worker
operator ()(const glu::InterfaceBlock & b) const947*35238bceSAndroid Build Coastguard Worker bool operator()(const glu::InterfaceBlock &b) const
948*35238bceSAndroid Build Coastguard Worker {
949*35238bceSAndroid Build Coastguard Worker return m_storage == b.storage;
950*35238bceSAndroid Build Coastguard Worker }
951*35238bceSAndroid Build Coastguard Worker
952*35238bceSAndroid Build Coastguard Worker private:
953*35238bceSAndroid Build Coastguard Worker const glu::Storage m_storage;
954*35238bceSAndroid Build Coastguard Worker };
955*35238bceSAndroid Build Coastguard Worker
956*35238bceSAndroid Build Coastguard Worker class VariableDeclarationStorageFilter
957*35238bceSAndroid Build Coastguard Worker {
958*35238bceSAndroid Build Coastguard Worker public:
VariableDeclarationStorageFilter(glu::Storage storage)959*35238bceSAndroid Build Coastguard Worker VariableDeclarationStorageFilter(glu::Storage storage) : m_storage(storage)
960*35238bceSAndroid Build Coastguard Worker {
961*35238bceSAndroid Build Coastguard Worker }
962*35238bceSAndroid Build Coastguard Worker
operator ()(const glu::VariableDeclaration & d) const963*35238bceSAndroid Build Coastguard Worker bool operator()(const glu::VariableDeclaration &d) const
964*35238bceSAndroid Build Coastguard Worker {
965*35238bceSAndroid Build Coastguard Worker return m_storage == d.storage;
966*35238bceSAndroid Build Coastguard Worker }
967*35238bceSAndroid Build Coastguard Worker
968*35238bceSAndroid Build Coastguard Worker private:
969*35238bceSAndroid Build Coastguard Worker const glu::Storage m_storage;
970*35238bceSAndroid Build Coastguard Worker };
971*35238bceSAndroid Build Coastguard Worker
getNumTypeInstances(const glu::VarType & complexType,bool (* predicate)(glu::DataType))972*35238bceSAndroid Build Coastguard Worker static int getNumTypeInstances(const glu::VarType &complexType, bool (*predicate)(glu::DataType))
973*35238bceSAndroid Build Coastguard Worker {
974*35238bceSAndroid Build Coastguard Worker return accumulateComplexType(complexType, InstanceCounter(predicate));
975*35238bceSAndroid Build Coastguard Worker }
976*35238bceSAndroid Build Coastguard Worker
getNumTypeInstances(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage,bool (* predicate)(glu::DataType))977*35238bceSAndroid Build Coastguard Worker static int getNumTypeInstances(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage,
978*35238bceSAndroid Build Coastguard Worker bool (*predicate)(glu::DataType))
979*35238bceSAndroid Build Coastguard Worker {
980*35238bceSAndroid Build Coastguard Worker return accumulateShader(shader, InterfaceBlockStorageFilter(storage), VariableDeclarationStorageFilter(storage),
981*35238bceSAndroid Build Coastguard Worker InstanceCounter(predicate));
982*35238bceSAndroid Build Coastguard Worker }
983*35238bceSAndroid Build Coastguard Worker
getNumTypeInstances(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)984*35238bceSAndroid Build Coastguard Worker static int getNumTypeInstances(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
985*35238bceSAndroid Build Coastguard Worker {
986*35238bceSAndroid Build Coastguard Worker return getNumTypeInstances(shader, storage, unusedTrueConstantTypeFilter);
987*35238bceSAndroid Build Coastguard Worker }
988*35238bceSAndroid Build Coastguard Worker
accumulateShaderStorage(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage,int (* typeMap)(glu::DataType))989*35238bceSAndroid Build Coastguard Worker static int accumulateShaderStorage(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage,
990*35238bceSAndroid Build Coastguard Worker int (*typeMap)(glu::DataType))
991*35238bceSAndroid Build Coastguard Worker {
992*35238bceSAndroid Build Coastguard Worker return accumulateShader(shader, InterfaceBlockStorageFilter(storage), VariableDeclarationStorageFilter(storage),
993*35238bceSAndroid Build Coastguard Worker typeMap);
994*35238bceSAndroid Build Coastguard Worker }
995*35238bceSAndroid Build Coastguard Worker
getNumDataTypeComponents(glu::DataType type)996*35238bceSAndroid Build Coastguard Worker static int getNumDataTypeComponents(glu::DataType type)
997*35238bceSAndroid Build Coastguard Worker {
998*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
999*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeScalarSize(type);
1000*35238bceSAndroid Build Coastguard Worker else
1001*35238bceSAndroid Build Coastguard Worker return 0;
1002*35238bceSAndroid Build Coastguard Worker }
1003*35238bceSAndroid Build Coastguard Worker
getNumDataTypeVectors(glu::DataType type)1004*35238bceSAndroid Build Coastguard Worker static int getNumDataTypeVectors(glu::DataType type)
1005*35238bceSAndroid Build Coastguard Worker {
1006*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeScalar(type))
1007*35238bceSAndroid Build Coastguard Worker return 1;
1008*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeVector(type))
1009*35238bceSAndroid Build Coastguard Worker return 1;
1010*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeMatrix(type))
1011*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeMatrixNumColumns(type);
1012*35238bceSAndroid Build Coastguard Worker else
1013*35238bceSAndroid Build Coastguard Worker return 0;
1014*35238bceSAndroid Build Coastguard Worker }
1015*35238bceSAndroid Build Coastguard Worker
getNumComponents(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)1016*35238bceSAndroid Build Coastguard Worker static int getNumComponents(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
1017*35238bceSAndroid Build Coastguard Worker {
1018*35238bceSAndroid Build Coastguard Worker return accumulateShaderStorage(shader, storage, getNumDataTypeComponents);
1019*35238bceSAndroid Build Coastguard Worker }
1020*35238bceSAndroid Build Coastguard Worker
getNumVectors(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)1021*35238bceSAndroid Build Coastguard Worker static int getNumVectors(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
1022*35238bceSAndroid Build Coastguard Worker {
1023*35238bceSAndroid Build Coastguard Worker return accumulateShaderStorage(shader, storage, getNumDataTypeVectors);
1024*35238bceSAndroid Build Coastguard Worker }
1025*35238bceSAndroid Build Coastguard Worker
getNumDefaultBlockComponents(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)1026*35238bceSAndroid Build Coastguard Worker static int getNumDefaultBlockComponents(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
1027*35238bceSAndroid Build Coastguard Worker {
1028*35238bceSAndroid Build Coastguard Worker int retVal = 0;
1029*35238bceSAndroid Build Coastguard Worker
1030*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx)
1031*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().variables[varNdx].storage == storage)
1032*35238bceSAndroid Build Coastguard Worker retVal +=
1033*35238bceSAndroid Build Coastguard Worker accumulateComplexType(shader->getDefaultBlock().variables[varNdx].varType, getNumDataTypeComponents);
1034*35238bceSAndroid Build Coastguard Worker
1035*35238bceSAndroid Build Coastguard Worker return retVal;
1036*35238bceSAndroid Build Coastguard Worker }
1037*35238bceSAndroid Build Coastguard Worker
getMaxBufferBinding(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)1038*35238bceSAndroid Build Coastguard Worker static int getMaxBufferBinding(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
1039*35238bceSAndroid Build Coastguard Worker {
1040*35238bceSAndroid Build Coastguard Worker int maxBinding = -1;
1041*35238bceSAndroid Build Coastguard Worker
1042*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
1043*35238bceSAndroid Build Coastguard Worker {
1044*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage)
1045*35238bceSAndroid Build Coastguard Worker {
1046*35238bceSAndroid Build Coastguard Worker const int binding = (shader->getDefaultBlock().interfaceBlocks[ndx].layout.binding == -1) ?
1047*35238bceSAndroid Build Coastguard Worker (0) :
1048*35238bceSAndroid Build Coastguard Worker (shader->getDefaultBlock().interfaceBlocks[ndx].layout.binding);
1049*35238bceSAndroid Build Coastguard Worker int numInstances = 1;
1050*35238bceSAndroid Build Coastguard Worker
1051*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0;
1052*35238bceSAndroid Build Coastguard Worker dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx)
1053*35238bceSAndroid Build Coastguard Worker numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx];
1054*35238bceSAndroid Build Coastguard Worker
1055*35238bceSAndroid Build Coastguard Worker maxBinding = de::max(maxBinding, binding + numInstances - 1);
1056*35238bceSAndroid Build Coastguard Worker }
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker
1059*35238bceSAndroid Build Coastguard Worker return (int)maxBinding;
1060*35238bceSAndroid Build Coastguard Worker }
1061*35238bceSAndroid Build Coastguard Worker
getBufferTypeSize(glu::DataType type,glu::MatrixOrder order)1062*35238bceSAndroid Build Coastguard Worker static int getBufferTypeSize(glu::DataType type, glu::MatrixOrder order)
1063*35238bceSAndroid Build Coastguard Worker {
1064*35238bceSAndroid Build Coastguard Worker // assume vec4 alignments, should produce values greater than or equal to the actual resource usage
1065*35238bceSAndroid Build Coastguard Worker int numVectors = 0;
1066*35238bceSAndroid Build Coastguard Worker
1067*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeScalarOrVector(type))
1068*35238bceSAndroid Build Coastguard Worker numVectors = 1;
1069*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeMatrix(type) && order == glu::MATRIXORDER_ROW_MAJOR)
1070*35238bceSAndroid Build Coastguard Worker numVectors = glu::getDataTypeMatrixNumRows(type);
1071*35238bceSAndroid Build Coastguard Worker else if (glu::isDataTypeMatrix(type) && order != glu::MATRIXORDER_ROW_MAJOR)
1072*35238bceSAndroid Build Coastguard Worker numVectors = glu::getDataTypeMatrixNumColumns(type);
1073*35238bceSAndroid Build Coastguard Worker else
1074*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1075*35238bceSAndroid Build Coastguard Worker
1076*35238bceSAndroid Build Coastguard Worker return 4 * numVectors;
1077*35238bceSAndroid Build Coastguard Worker }
1078*35238bceSAndroid Build Coastguard Worker
getBufferVariableSize(const glu::VarType & type,glu::MatrixOrder order)1079*35238bceSAndroid Build Coastguard Worker static int getBufferVariableSize(const glu::VarType &type, glu::MatrixOrder order)
1080*35238bceSAndroid Build Coastguard Worker {
1081*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
1082*35238bceSAndroid Build Coastguard Worker return getBufferTypeSize(type.getBasicType(), order);
1083*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
1084*35238bceSAndroid Build Coastguard Worker {
1085*35238bceSAndroid Build Coastguard Worker const int arraySize = (type.getArraySize() == glu::VarType::UNSIZED_ARRAY) ? (1) : (type.getArraySize());
1086*35238bceSAndroid Build Coastguard Worker return arraySize * getBufferVariableSize(type.getElementType(), order);
1087*35238bceSAndroid Build Coastguard Worker }
1088*35238bceSAndroid Build Coastguard Worker else if (type.isStructType())
1089*35238bceSAndroid Build Coastguard Worker {
1090*35238bceSAndroid Build Coastguard Worker int sum = 0;
1091*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
1092*35238bceSAndroid Build Coastguard Worker sum += getBufferVariableSize(type.getStructPtr()->getMember(ndx).getType(), order);
1093*35238bceSAndroid Build Coastguard Worker return sum;
1094*35238bceSAndroid Build Coastguard Worker }
1095*35238bceSAndroid Build Coastguard Worker else
1096*35238bceSAndroid Build Coastguard Worker {
1097*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1098*35238bceSAndroid Build Coastguard Worker return false;
1099*35238bceSAndroid Build Coastguard Worker }
1100*35238bceSAndroid Build Coastguard Worker }
1101*35238bceSAndroid Build Coastguard Worker
getBufferSize(const glu::InterfaceBlock & block,glu::MatrixOrder blockOrder)1102*35238bceSAndroid Build Coastguard Worker static int getBufferSize(const glu::InterfaceBlock &block, glu::MatrixOrder blockOrder)
1103*35238bceSAndroid Build Coastguard Worker {
1104*35238bceSAndroid Build Coastguard Worker int size = 0;
1105*35238bceSAndroid Build Coastguard Worker
1106*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
1107*35238bceSAndroid Build Coastguard Worker size += getBufferVariableSize(block.variables[ndx].varType,
1108*35238bceSAndroid Build Coastguard Worker (block.variables[ndx].layout.matrixOrder == glu::MATRIXORDER_LAST) ?
1109*35238bceSAndroid Build Coastguard Worker (blockOrder) :
1110*35238bceSAndroid Build Coastguard Worker (block.variables[ndx].layout.matrixOrder));
1111*35238bceSAndroid Build Coastguard Worker
1112*35238bceSAndroid Build Coastguard Worker return size;
1113*35238bceSAndroid Build Coastguard Worker }
1114*35238bceSAndroid Build Coastguard Worker
getBufferMaxSize(const ProgramInterfaceDefinition::Shader * shader,glu::Storage storage)1115*35238bceSAndroid Build Coastguard Worker static int getBufferMaxSize(const ProgramInterfaceDefinition::Shader *shader, glu::Storage storage)
1116*35238bceSAndroid Build Coastguard Worker {
1117*35238bceSAndroid Build Coastguard Worker int maxSize = 0;
1118*35238bceSAndroid Build Coastguard Worker
1119*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
1120*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage)
1121*35238bceSAndroid Build Coastguard Worker maxSize =
1122*35238bceSAndroid Build Coastguard Worker de::max(maxSize, getBufferSize(shader->getDefaultBlock().interfaceBlocks[ndx],
1123*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().interfaceBlocks[ndx].layout.matrixOrder));
1124*35238bceSAndroid Build Coastguard Worker
1125*35238bceSAndroid Build Coastguard Worker return (int)maxSize;
1126*35238bceSAndroid Build Coastguard Worker }
1127*35238bceSAndroid Build Coastguard Worker
getAtomicCounterMaxBinding(const ProgramInterfaceDefinition::Shader * shader)1128*35238bceSAndroid Build Coastguard Worker static int getAtomicCounterMaxBinding(const ProgramInterfaceDefinition::Shader *shader)
1129*35238bceSAndroid Build Coastguard Worker {
1130*35238bceSAndroid Build Coastguard Worker int maxBinding = -1;
1131*35238bceSAndroid Build Coastguard Worker
1132*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1133*35238bceSAndroid Build Coastguard Worker {
1134*35238bceSAndroid Build Coastguard Worker if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER))
1135*35238bceSAndroid Build Coastguard Worker {
1136*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1);
1137*35238bceSAndroid Build Coastguard Worker maxBinding = de::max(maxBinding, shader->getDefaultBlock().variables[ndx].layout.binding);
1138*35238bceSAndroid Build Coastguard Worker }
1139*35238bceSAndroid Build Coastguard Worker }
1140*35238bceSAndroid Build Coastguard Worker
1141*35238bceSAndroid Build Coastguard Worker return (int)maxBinding;
1142*35238bceSAndroid Build Coastguard Worker }
1143*35238bceSAndroid Build Coastguard Worker
getUniformMaxBinding(const ProgramInterfaceDefinition::Shader * shader,bool (* predicate)(glu::DataType))1144*35238bceSAndroid Build Coastguard Worker static int getUniformMaxBinding(const ProgramInterfaceDefinition::Shader *shader, bool (*predicate)(glu::DataType))
1145*35238bceSAndroid Build Coastguard Worker {
1146*35238bceSAndroid Build Coastguard Worker int maxBinding = -1;
1147*35238bceSAndroid Build Coastguard Worker
1148*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1149*35238bceSAndroid Build Coastguard Worker {
1150*35238bceSAndroid Build Coastguard Worker const int binding = (shader->getDefaultBlock().variables[ndx].layout.binding == -1) ?
1151*35238bceSAndroid Build Coastguard Worker (0) :
1152*35238bceSAndroid Build Coastguard Worker (shader->getDefaultBlock().variables[ndx].layout.binding);
1153*35238bceSAndroid Build Coastguard Worker const int numInstances = getNumTypeInstances(shader->getDefaultBlock().variables[ndx].varType, predicate);
1154*35238bceSAndroid Build Coastguard Worker
1155*35238bceSAndroid Build Coastguard Worker maxBinding = de::max(maxBinding, binding + numInstances - 1);
1156*35238bceSAndroid Build Coastguard Worker }
1157*35238bceSAndroid Build Coastguard Worker
1158*35238bceSAndroid Build Coastguard Worker return maxBinding;
1159*35238bceSAndroid Build Coastguard Worker }
1160*35238bceSAndroid Build Coastguard Worker
getAtomicCounterMaxBufferSize(const ProgramInterfaceDefinition::Shader * shader)1161*35238bceSAndroid Build Coastguard Worker static int getAtomicCounterMaxBufferSize(const ProgramInterfaceDefinition::Shader *shader)
1162*35238bceSAndroid Build Coastguard Worker {
1163*35238bceSAndroid Build Coastguard Worker std::map<int, int> bufferSizes;
1164*35238bceSAndroid Build Coastguard Worker int maxSize = 0;
1165*35238bceSAndroid Build Coastguard Worker
1166*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1167*35238bceSAndroid Build Coastguard Worker {
1168*35238bceSAndroid Build Coastguard Worker if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER))
1169*35238bceSAndroid Build Coastguard Worker {
1170*35238bceSAndroid Build Coastguard Worker const int bufferBinding = shader->getDefaultBlock().variables[ndx].layout.binding;
1171*35238bceSAndroid Build Coastguard Worker const int offset = (shader->getDefaultBlock().variables[ndx].layout.offset == -1) ?
1172*35238bceSAndroid Build Coastguard Worker (0) :
1173*35238bceSAndroid Build Coastguard Worker (shader->getDefaultBlock().variables[ndx].layout.offset);
1174*35238bceSAndroid Build Coastguard Worker const int size = offset + 4 * getNumTypeInstances(shader->getDefaultBlock().variables[ndx].varType,
1175*35238bceSAndroid Build Coastguard Worker glu::isDataTypeAtomicCounter);
1176*35238bceSAndroid Build Coastguard Worker
1177*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1);
1178*35238bceSAndroid Build Coastguard Worker
1179*35238bceSAndroid Build Coastguard Worker if (bufferSizes.find(bufferBinding) == bufferSizes.end())
1180*35238bceSAndroid Build Coastguard Worker bufferSizes[bufferBinding] = size;
1181*35238bceSAndroid Build Coastguard Worker else
1182*35238bceSAndroid Build Coastguard Worker bufferSizes[bufferBinding] = de::max<int>(bufferSizes[bufferBinding], size);
1183*35238bceSAndroid Build Coastguard Worker }
1184*35238bceSAndroid Build Coastguard Worker }
1185*35238bceSAndroid Build Coastguard Worker
1186*35238bceSAndroid Build Coastguard Worker for (std::map<int, int>::iterator it = bufferSizes.begin(); it != bufferSizes.end(); ++it)
1187*35238bceSAndroid Build Coastguard Worker maxSize = de::max<int>(maxSize, it->second);
1188*35238bceSAndroid Build Coastguard Worker
1189*35238bceSAndroid Build Coastguard Worker return maxSize;
1190*35238bceSAndroid Build Coastguard Worker }
1191*35238bceSAndroid Build Coastguard Worker
getNumFeedbackVaryingComponents(const ProgramInterfaceDefinition::Program * program,const std::string & name)1192*35238bceSAndroid Build Coastguard Worker static int getNumFeedbackVaryingComponents(const ProgramInterfaceDefinition::Program *program, const std::string &name)
1193*35238bceSAndroid Build Coastguard Worker {
1194*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> path;
1195*35238bceSAndroid Build Coastguard Worker
1196*35238bceSAndroid Build Coastguard Worker if (name == "gl_Position")
1197*35238bceSAndroid Build Coastguard Worker return 4;
1198*35238bceSAndroid Build Coastguard Worker
1199*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deStringBeginsWith(name.c_str(), "gl_") == false);
1200*35238bceSAndroid Build Coastguard Worker
1201*35238bceSAndroid Build Coastguard Worker if (!traverseProgramVariablePath(path, program, name,
1202*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createShaderTypeStorageFilter(
1203*35238bceSAndroid Build Coastguard Worker getProgramTransformFeedbackStage(program), glu::STORAGE_OUT)))
1204*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); // Program failed validate, invalid operation
1205*35238bceSAndroid Build Coastguard Worker
1206*35238bceSAndroid Build Coastguard Worker return accumulateComplexType(*path.back().getVariableType(), getNumDataTypeComponents);
1207*35238bceSAndroid Build Coastguard Worker }
1208*35238bceSAndroid Build Coastguard Worker
getNumXFBComponents(const ProgramInterfaceDefinition::Program * program)1209*35238bceSAndroid Build Coastguard Worker static int getNumXFBComponents(const ProgramInterfaceDefinition::Program *program)
1210*35238bceSAndroid Build Coastguard Worker {
1211*35238bceSAndroid Build Coastguard Worker int numComponents = 0;
1212*35238bceSAndroid Build Coastguard Worker
1213*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx)
1214*35238bceSAndroid Build Coastguard Worker numComponents += getNumFeedbackVaryingComponents(program, program->getTransformFeedbackVaryings()[ndx]);
1215*35238bceSAndroid Build Coastguard Worker
1216*35238bceSAndroid Build Coastguard Worker return numComponents;
1217*35238bceSAndroid Build Coastguard Worker }
1218*35238bceSAndroid Build Coastguard Worker
getNumMaxXFBOutputComponents(const ProgramInterfaceDefinition::Program * program)1219*35238bceSAndroid Build Coastguard Worker static int getNumMaxXFBOutputComponents(const ProgramInterfaceDefinition::Program *program)
1220*35238bceSAndroid Build Coastguard Worker {
1221*35238bceSAndroid Build Coastguard Worker int numComponents = 0;
1222*35238bceSAndroid Build Coastguard Worker
1223*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx)
1224*35238bceSAndroid Build Coastguard Worker numComponents = de::max(numComponents,
1225*35238bceSAndroid Build Coastguard Worker getNumFeedbackVaryingComponents(program, program->getTransformFeedbackVaryings()[ndx]));
1226*35238bceSAndroid Build Coastguard Worker
1227*35238bceSAndroid Build Coastguard Worker return numComponents;
1228*35238bceSAndroid Build Coastguard Worker }
1229*35238bceSAndroid Build Coastguard Worker
getFragmentOutputMaxLocation(const ProgramInterfaceDefinition::Shader * shader)1230*35238bceSAndroid Build Coastguard Worker static int getFragmentOutputMaxLocation(const ProgramInterfaceDefinition::Shader *shader)
1231*35238bceSAndroid Build Coastguard Worker {
1232*35238bceSAndroid Build Coastguard Worker DE_ASSERT(shader->getType() == glu::SHADERTYPE_FRAGMENT);
1233*35238bceSAndroid Build Coastguard Worker
1234*35238bceSAndroid Build Coastguard Worker int maxOutputLocation = -1;
1235*35238bceSAndroid Build Coastguard Worker
1236*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1237*35238bceSAndroid Build Coastguard Worker {
1238*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_OUT)
1239*35238bceSAndroid Build Coastguard Worker {
1240*35238bceSAndroid Build Coastguard Worker // missing location qualifier means location == 0
1241*35238bceSAndroid Build Coastguard Worker const int outputLocation = (shader->getDefaultBlock().variables[ndx].layout.location == -1) ?
1242*35238bceSAndroid Build Coastguard Worker (0) :
1243*35238bceSAndroid Build Coastguard Worker (shader->getDefaultBlock().variables[ndx].layout.location);
1244*35238bceSAndroid Build Coastguard Worker
1245*35238bceSAndroid Build Coastguard Worker // only basic types or arrays of basic types possible
1246*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!shader->getDefaultBlock().variables[ndx].varType.isStructType());
1247*35238bceSAndroid Build Coastguard Worker
1248*35238bceSAndroid Build Coastguard Worker const int locationSlotsTaken = (shader->getDefaultBlock().variables[ndx].varType.isArrayType()) ?
1249*35238bceSAndroid Build Coastguard Worker (shader->getDefaultBlock().variables[ndx].varType.getArraySize()) :
1250*35238bceSAndroid Build Coastguard Worker (1);
1251*35238bceSAndroid Build Coastguard Worker
1252*35238bceSAndroid Build Coastguard Worker maxOutputLocation = de::max(maxOutputLocation, outputLocation + locationSlotsTaken - 1);
1253*35238bceSAndroid Build Coastguard Worker }
1254*35238bceSAndroid Build Coastguard Worker }
1255*35238bceSAndroid Build Coastguard Worker
1256*35238bceSAndroid Build Coastguard Worker return maxOutputLocation;
1257*35238bceSAndroid Build Coastguard Worker }
1258*35238bceSAndroid Build Coastguard Worker
1259*35238bceSAndroid Build Coastguard Worker } // namespace
1260*35238bceSAndroid Build Coastguard Worker
getProgramInterfaceBlockMemberResourceList(const glu::InterfaceBlock & interfaceBlock)1261*35238bceSAndroid Build Coastguard Worker std::vector<std::string> getProgramInterfaceBlockMemberResourceList(const glu::InterfaceBlock &interfaceBlock)
1262*35238bceSAndroid Build Coastguard Worker {
1263*35238bceSAndroid Build Coastguard Worker const std::string namePrefix = (!interfaceBlock.instanceName.empty()) ? (interfaceBlock.interfaceName + ".") : ("");
1264*35238bceSAndroid Build Coastguard Worker const bool isTopLevelBufferVariable = (interfaceBlock.storage == glu::STORAGE_BUFFER);
1265*35238bceSAndroid Build Coastguard Worker std::vector<std::string> resources;
1266*35238bceSAndroid Build Coastguard Worker
1267*35238bceSAndroid Build Coastguard Worker // \note this is defined in the GLSL spec, not in the GL spec
1268*35238bceSAndroid Build Coastguard Worker for (int variableNdx = 0; variableNdx < (int)interfaceBlock.variables.size(); ++variableNdx)
1269*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, namePrefix + interfaceBlock.variables[variableNdx].name,
1270*35238bceSAndroid Build Coastguard Worker interfaceBlock.variables[variableNdx].varType,
1271*35238bceSAndroid Build Coastguard Worker (isTopLevelBufferVariable) ?
1272*35238bceSAndroid Build Coastguard Worker (RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE) :
1273*35238bceSAndroid Build Coastguard Worker (RESOURCE_NAME_GENERATION_FLAG_DEFAULT));
1274*35238bceSAndroid Build Coastguard Worker
1275*35238bceSAndroid Build Coastguard Worker return resources;
1276*35238bceSAndroid Build Coastguard Worker }
1277*35238bceSAndroid Build Coastguard Worker
getProgramInterfaceResourceList(const ProgramInterfaceDefinition::Program * program,ProgramInterface interface)1278*35238bceSAndroid Build Coastguard Worker std::vector<std::string> getProgramInterfaceResourceList(const ProgramInterfaceDefinition::Program *program,
1279*35238bceSAndroid Build Coastguard Worker ProgramInterface interface)
1280*35238bceSAndroid Build Coastguard Worker {
1281*35238bceSAndroid Build Coastguard Worker // The same {uniform (block), buffer (variable)} can exist in multiple shaders, remove duplicates but keep order
1282*35238bceSAndroid Build Coastguard Worker const bool removeDuplicated =
1283*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_UNIFORM) || (interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ||
1284*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_BUFFER_VARIABLE) || (interface == PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
1285*35238bceSAndroid Build Coastguard Worker std::vector<std::string> resources;
1286*35238bceSAndroid Build Coastguard Worker
1287*35238bceSAndroid Build Coastguard Worker switch (interface)
1288*35238bceSAndroid Build Coastguard Worker {
1289*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM:
1290*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_BUFFER_VARIABLE:
1291*35238bceSAndroid Build Coastguard Worker {
1292*35238bceSAndroid Build Coastguard Worker const glu::Storage storage =
1293*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_UNIFORM) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER);
1294*35238bceSAndroid Build Coastguard Worker
1295*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1296*35238bceSAndroid Build Coastguard Worker {
1297*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader = program->getShaders()[shaderNdx];
1298*35238bceSAndroid Build Coastguard Worker
1299*35238bceSAndroid Build Coastguard Worker for (int variableNdx = 0; variableNdx < (int)shader->getDefaultBlock().variables.size(); ++variableNdx)
1300*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().variables[variableNdx].storage == storage)
1301*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, shader->getDefaultBlock().variables[variableNdx].name,
1302*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[variableNdx].varType,
1303*35238bceSAndroid Build Coastguard Worker RESOURCE_NAME_GENERATION_FLAG_DEFAULT);
1304*35238bceSAndroid Build Coastguard Worker
1305*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size();
1306*35238bceSAndroid Build Coastguard Worker ++interfaceNdx)
1307*35238bceSAndroid Build Coastguard Worker {
1308*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx];
1309*35238bceSAndroid Build Coastguard Worker if (interfaceBlock.storage == storage)
1310*35238bceSAndroid Build Coastguard Worker {
1311*35238bceSAndroid Build Coastguard Worker const std::vector<std::string> blockResources =
1312*35238bceSAndroid Build Coastguard Worker getProgramInterfaceBlockMemberResourceList(interfaceBlock);
1313*35238bceSAndroid Build Coastguard Worker resources.insert(resources.end(), blockResources.begin(), blockResources.end());
1314*35238bceSAndroid Build Coastguard Worker }
1315*35238bceSAndroid Build Coastguard Worker }
1316*35238bceSAndroid Build Coastguard Worker }
1317*35238bceSAndroid Build Coastguard Worker break;
1318*35238bceSAndroid Build Coastguard Worker }
1319*35238bceSAndroid Build Coastguard Worker
1320*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_UNIFORM_BLOCK:
1321*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
1322*35238bceSAndroid Build Coastguard Worker {
1323*35238bceSAndroid Build Coastguard Worker const glu::Storage storage =
1324*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER);
1325*35238bceSAndroid Build Coastguard Worker
1326*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1327*35238bceSAndroid Build Coastguard Worker {
1328*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader = program->getShaders()[shaderNdx];
1329*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size();
1330*35238bceSAndroid Build Coastguard Worker ++interfaceNdx)
1331*35238bceSAndroid Build Coastguard Worker {
1332*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx];
1333*35238bceSAndroid Build Coastguard Worker if (interfaceBlock.storage == storage)
1334*35238bceSAndroid Build Coastguard Worker {
1335*35238bceSAndroid Build Coastguard Worker std::vector<int> index(interfaceBlock.dimensions.size(), 0);
1336*35238bceSAndroid Build Coastguard Worker
1337*35238bceSAndroid Build Coastguard Worker for (;;)
1338*35238bceSAndroid Build Coastguard Worker {
1339*35238bceSAndroid Build Coastguard Worker // add resource string for each element
1340*35238bceSAndroid Build Coastguard Worker {
1341*35238bceSAndroid Build Coastguard Worker std::ostringstream name;
1342*35238bceSAndroid Build Coastguard Worker name << interfaceBlock.interfaceName;
1343*35238bceSAndroid Build Coastguard Worker
1344*35238bceSAndroid Build Coastguard Worker for (int dimensionNdx = 0; dimensionNdx < (int)interfaceBlock.dimensions.size();
1345*35238bceSAndroid Build Coastguard Worker ++dimensionNdx)
1346*35238bceSAndroid Build Coastguard Worker name << "[" << index[dimensionNdx] << "]";
1347*35238bceSAndroid Build Coastguard Worker
1348*35238bceSAndroid Build Coastguard Worker resources.push_back(name.str());
1349*35238bceSAndroid Build Coastguard Worker }
1350*35238bceSAndroid Build Coastguard Worker
1351*35238bceSAndroid Build Coastguard Worker // increment index
1352*35238bceSAndroid Build Coastguard Worker if (!incrementMultiDimensionIndex(index, interfaceBlock.dimensions))
1353*35238bceSAndroid Build Coastguard Worker break;
1354*35238bceSAndroid Build Coastguard Worker }
1355*35238bceSAndroid Build Coastguard Worker }
1356*35238bceSAndroid Build Coastguard Worker }
1357*35238bceSAndroid Build Coastguard Worker }
1358*35238bceSAndroid Build Coastguard Worker break;
1359*35238bceSAndroid Build Coastguard Worker }
1360*35238bceSAndroid Build Coastguard Worker
1361*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_INPUT:
1362*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_PROGRAM_OUTPUT:
1363*35238bceSAndroid Build Coastguard Worker {
1364*35238bceSAndroid Build Coastguard Worker const glu::Storage queryStorage =
1365*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (glu::STORAGE_IN) : (glu::STORAGE_OUT);
1366*35238bceSAndroid Build Coastguard Worker const glu::Storage queryPatchStorage =
1367*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (glu::STORAGE_PATCH_IN) : (glu::STORAGE_PATCH_OUT);
1368*35238bceSAndroid Build Coastguard Worker const glu::ShaderType shaderType =
1369*35238bceSAndroid Build Coastguard Worker (interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (program->getFirstStage()) : (program->getLastStage());
1370*35238bceSAndroid Build Coastguard Worker
1371*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1372*35238bceSAndroid Build Coastguard Worker {
1373*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader = program->getShaders()[shaderNdx];
1374*35238bceSAndroid Build Coastguard Worker
1375*35238bceSAndroid Build Coastguard Worker if (shader->getType() != shaderType)
1376*35238bceSAndroid Build Coastguard Worker continue;
1377*35238bceSAndroid Build Coastguard Worker
1378*35238bceSAndroid Build Coastguard Worker for (int variableNdx = 0; variableNdx < (int)shader->getDefaultBlock().variables.size(); ++variableNdx)
1379*35238bceSAndroid Build Coastguard Worker {
1380*35238bceSAndroid Build Coastguard Worker const glu::Storage variableStorage = shader->getDefaultBlock().variables[variableNdx].storage;
1381*35238bceSAndroid Build Coastguard Worker if (variableStorage == queryStorage || variableStorage == queryPatchStorage)
1382*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, shader->getDefaultBlock().variables[variableNdx].name,
1383*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[variableNdx].varType,
1384*35238bceSAndroid Build Coastguard Worker RESOURCE_NAME_GENERATION_FLAG_DEFAULT);
1385*35238bceSAndroid Build Coastguard Worker }
1386*35238bceSAndroid Build Coastguard Worker
1387*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size();
1388*35238bceSAndroid Build Coastguard Worker ++interfaceNdx)
1389*35238bceSAndroid Build Coastguard Worker {
1390*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx];
1391*35238bceSAndroid Build Coastguard Worker if (interfaceBlock.storage == queryStorage || interfaceBlock.storage == queryPatchStorage)
1392*35238bceSAndroid Build Coastguard Worker {
1393*35238bceSAndroid Build Coastguard Worker const std::vector<std::string> blockResources =
1394*35238bceSAndroid Build Coastguard Worker getProgramInterfaceBlockMemberResourceList(interfaceBlock);
1395*35238bceSAndroid Build Coastguard Worker resources.insert(resources.end(), blockResources.begin(), blockResources.end());
1396*35238bceSAndroid Build Coastguard Worker }
1397*35238bceSAndroid Build Coastguard Worker }
1398*35238bceSAndroid Build Coastguard Worker }
1399*35238bceSAndroid Build Coastguard Worker
1400*35238bceSAndroid Build Coastguard Worker // built-ins
1401*35238bceSAndroid Build Coastguard Worker if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1402*35238bceSAndroid Build Coastguard Worker {
1403*35238bceSAndroid Build Coastguard Worker if (shaderType == glu::SHADERTYPE_VERTEX && resources.empty())
1404*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_VertexID"); // only read from when there are no other inputs
1405*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_FRAGMENT && resources.empty())
1406*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_FragCoord"); // only read from when there are no other inputs
1407*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_GEOMETRY)
1408*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_PerVertex.gl_Position");
1409*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
1410*35238bceSAndroid Build Coastguard Worker {
1411*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_InvocationID");
1412*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_PerVertex.gl_Position");
1413*35238bceSAndroid Build Coastguard Worker }
1414*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION)
1415*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_PerVertex.gl_Position");
1416*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_COMPUTE && resources.empty())
1417*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_NumWorkGroups"); // only read from when there are no other inputs
1418*35238bceSAndroid Build Coastguard Worker }
1419*35238bceSAndroid Build Coastguard Worker else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1420*35238bceSAndroid Build Coastguard Worker {
1421*35238bceSAndroid Build Coastguard Worker if (shaderType == glu::SHADERTYPE_VERTEX)
1422*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_Position");
1423*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_FRAGMENT && resources.empty())
1424*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_FragDepth"); // only written to when there are no other outputs
1425*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_GEOMETRY)
1426*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_Position");
1427*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
1428*35238bceSAndroid Build Coastguard Worker {
1429*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_PerVertex.gl_Position");
1430*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_TessLevelOuter[0]");
1431*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_TessLevelInner[0]");
1432*35238bceSAndroid Build Coastguard Worker }
1433*35238bceSAndroid Build Coastguard Worker else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION)
1434*35238bceSAndroid Build Coastguard Worker resources.push_back("gl_Position");
1435*35238bceSAndroid Build Coastguard Worker }
1436*35238bceSAndroid Build Coastguard Worker
1437*35238bceSAndroid Build Coastguard Worker break;
1438*35238bceSAndroid Build Coastguard Worker }
1439*35238bceSAndroid Build Coastguard Worker
1440*35238bceSAndroid Build Coastguard Worker case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
1441*35238bceSAndroid Build Coastguard Worker {
1442*35238bceSAndroid Build Coastguard Worker const glu::ShaderType xfbStage = getProgramTransformFeedbackStage(program);
1443*35238bceSAndroid Build Coastguard Worker
1444*35238bceSAndroid Build Coastguard Worker for (int varyingNdx = 0; varyingNdx < (int)program->getTransformFeedbackVaryings().size(); ++varyingNdx)
1445*35238bceSAndroid Build Coastguard Worker {
1446*35238bceSAndroid Build Coastguard Worker const std::string &varyingName = program->getTransformFeedbackVaryings()[varyingNdx];
1447*35238bceSAndroid Build Coastguard Worker
1448*35238bceSAndroid Build Coastguard Worker if (deStringBeginsWith(varyingName.c_str(), "gl_"))
1449*35238bceSAndroid Build Coastguard Worker resources.push_back(varyingName); // builtin
1450*35238bceSAndroid Build Coastguard Worker else
1451*35238bceSAndroid Build Coastguard Worker {
1452*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> path;
1453*35238bceSAndroid Build Coastguard Worker
1454*35238bceSAndroid Build Coastguard Worker if (!traverseProgramVariablePath(
1455*35238bceSAndroid Build Coastguard Worker path, program, varyingName,
1456*35238bceSAndroid Build Coastguard Worker VariableSearchFilter::createShaderTypeStorageFilter(xfbStage, glu::STORAGE_OUT)))
1457*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); // Program failed validate, invalid operation
1458*35238bceSAndroid Build Coastguard Worker
1459*35238bceSAndroid Build Coastguard Worker generateVariableTypeResourceNames(resources, varyingName, *path.back().getVariableType(),
1460*35238bceSAndroid Build Coastguard Worker RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE);
1461*35238bceSAndroid Build Coastguard Worker }
1462*35238bceSAndroid Build Coastguard Worker }
1463*35238bceSAndroid Build Coastguard Worker
1464*35238bceSAndroid Build Coastguard Worker break;
1465*35238bceSAndroid Build Coastguard Worker }
1466*35238bceSAndroid Build Coastguard Worker
1467*35238bceSAndroid Build Coastguard Worker default:
1468*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1469*35238bceSAndroid Build Coastguard Worker }
1470*35238bceSAndroid Build Coastguard Worker
1471*35238bceSAndroid Build Coastguard Worker if (removeDuplicated)
1472*35238bceSAndroid Build Coastguard Worker {
1473*35238bceSAndroid Build Coastguard Worker std::set<std::string> addedVariables;
1474*35238bceSAndroid Build Coastguard Worker std::vector<std::string> uniqueResouces;
1475*35238bceSAndroid Build Coastguard Worker
1476*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)resources.size(); ++ndx)
1477*35238bceSAndroid Build Coastguard Worker {
1478*35238bceSAndroid Build Coastguard Worker if (addedVariables.find(resources[ndx]) == addedVariables.end())
1479*35238bceSAndroid Build Coastguard Worker {
1480*35238bceSAndroid Build Coastguard Worker addedVariables.insert(resources[ndx]);
1481*35238bceSAndroid Build Coastguard Worker uniqueResouces.push_back(resources[ndx]);
1482*35238bceSAndroid Build Coastguard Worker }
1483*35238bceSAndroid Build Coastguard Worker }
1484*35238bceSAndroid Build Coastguard Worker
1485*35238bceSAndroid Build Coastguard Worker uniqueResouces.swap(resources);
1486*35238bceSAndroid Build Coastguard Worker }
1487*35238bceSAndroid Build Coastguard Worker
1488*35238bceSAndroid Build Coastguard Worker return resources;
1489*35238bceSAndroid Build Coastguard Worker }
1490*35238bceSAndroid Build Coastguard Worker
1491*35238bceSAndroid Build Coastguard Worker /**
1492*35238bceSAndroid Build Coastguard Worker * Name of the unused uniform added by generateProgramInterfaceProgramSources
1493*35238bceSAndroid Build Coastguard Worker *
1494*35238bceSAndroid Build Coastguard Worker * A uniform named "unusedZero" is added by
1495*35238bceSAndroid Build Coastguard Worker * generateProgramInterfaceProgramSources. It is used in expressions to
1496*35238bceSAndroid Build Coastguard Worker * prevent various program resources from being eliminated by the GLSL
1497*35238bceSAndroid Build Coastguard Worker * compiler's optimizer.
1498*35238bceSAndroid Build Coastguard Worker *
1499*35238bceSAndroid Build Coastguard Worker * \sa deqp::gles31::Functional::ProgramInterfaceDefinition::generateProgramInterfaceProgramSources
1500*35238bceSAndroid Build Coastguard Worker */
getUnusedZeroUniformName()1501*35238bceSAndroid Build Coastguard Worker const char *getUnusedZeroUniformName()
1502*35238bceSAndroid Build Coastguard Worker {
1503*35238bceSAndroid Build Coastguard Worker return "unusedZero";
1504*35238bceSAndroid Build Coastguard Worker }
1505*35238bceSAndroid Build Coastguard Worker
generateProgramInterfaceProgramSources(const ProgramInterfaceDefinition::Program * program)1506*35238bceSAndroid Build Coastguard Worker glu::ProgramSources generateProgramInterfaceProgramSources(const ProgramInterfaceDefinition::Program *program)
1507*35238bceSAndroid Build Coastguard Worker {
1508*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
1509*35238bceSAndroid Build Coastguard Worker
1510*35238bceSAndroid Build Coastguard Worker DE_ASSERT(program->isValid());
1511*35238bceSAndroid Build Coastguard Worker
1512*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1513*35238bceSAndroid Build Coastguard Worker {
1514*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *shader = program->getShaders()[shaderNdx];
1515*35238bceSAndroid Build Coastguard Worker bool containsUserDefinedOutputs = false;
1516*35238bceSAndroid Build Coastguard Worker bool containsUserDefinedInputs = false;
1517*35238bceSAndroid Build Coastguard Worker std::ostringstream sourceBuf;
1518*35238bceSAndroid Build Coastguard Worker std::ostringstream usageBuf;
1519*35238bceSAndroid Build Coastguard Worker
1520*35238bceSAndroid Build Coastguard Worker sourceBuf << glu::getGLSLVersionDeclaration(shader->getVersion()) << "\n"
1521*35238bceSAndroid Build Coastguard Worker << getShaderExtensionDeclarations(shader) << getShaderTypeDeclarations(program, shader) << "\n";
1522*35238bceSAndroid Build Coastguard Worker
1523*35238bceSAndroid Build Coastguard Worker // Struct definitions
1524*35238bceSAndroid Build Coastguard Worker
1525*35238bceSAndroid Build Coastguard Worker writeStructureDefinitions(sourceBuf, shader->getDefaultBlock());
1526*35238bceSAndroid Build Coastguard Worker
1527*35238bceSAndroid Build Coastguard Worker // variables in the default scope
1528*35238bceSAndroid Build Coastguard Worker
1529*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1530*35238bceSAndroid Build Coastguard Worker sourceBuf << shader->getDefaultBlock().variables[ndx] << ";\n";
1531*35238bceSAndroid Build Coastguard Worker
1532*35238bceSAndroid Build Coastguard Worker if (!shader->getDefaultBlock().variables.empty())
1533*35238bceSAndroid Build Coastguard Worker sourceBuf << "\n";
1534*35238bceSAndroid Build Coastguard Worker
1535*35238bceSAndroid Build Coastguard Worker // Interface blocks
1536*35238bceSAndroid Build Coastguard Worker
1537*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx)
1538*35238bceSAndroid Build Coastguard Worker writeInterfaceBlock(sourceBuf, shader->getDefaultBlock().interfaceBlocks[ndx]);
1539*35238bceSAndroid Build Coastguard Worker
1540*35238bceSAndroid Build Coastguard Worker // Use inputs and outputs so that they won't be removed by the optimizer
1541*35238bceSAndroid Build Coastguard Worker
1542*35238bceSAndroid Build Coastguard Worker usageBuf << "highp uniform vec4 " << getUnusedZeroUniformName()
1543*35238bceSAndroid Build Coastguard Worker << "; // Default value is vec4(0.0).\n"
1544*35238bceSAndroid Build Coastguard Worker "highp vec4 readInputs()\n"
1545*35238bceSAndroid Build Coastguard Worker "{\n"
1546*35238bceSAndroid Build Coastguard Worker " highp vec4 retValue = "
1547*35238bceSAndroid Build Coastguard Worker << getUnusedZeroUniformName() << ";\n";
1548*35238bceSAndroid Build Coastguard Worker
1549*35238bceSAndroid Build Coastguard Worker // User-defined inputs
1550*35238bceSAndroid Build Coastguard Worker
1551*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1552*35238bceSAndroid Build Coastguard Worker {
1553*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_IN ||
1554*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_PATCH_IN ||
1555*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_UNIFORM)
1556*35238bceSAndroid Build Coastguard Worker {
1557*35238bceSAndroid Build Coastguard Worker writeVariableReadAccumulateExpression(usageBuf, "retValue",
1558*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].name, shader->getType(),
1559*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].storage, program,
1560*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].varType);
1561*35238bceSAndroid Build Coastguard Worker containsUserDefinedInputs = true;
1562*35238bceSAndroid Build Coastguard Worker }
1563*35238bceSAndroid Build Coastguard Worker }
1564*35238bceSAndroid Build Coastguard Worker
1565*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1566*35238bceSAndroid Build Coastguard Worker {
1567*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &interface = shader->getDefaultBlock().interfaceBlocks[interfaceNdx];
1568*35238bceSAndroid Build Coastguard Worker if (isReadableInterface(interface))
1569*35238bceSAndroid Build Coastguard Worker {
1570*35238bceSAndroid Build Coastguard Worker writeInterfaceReadAccumulateExpression(usageBuf, "retValue", interface, shader->getType(), program);
1571*35238bceSAndroid Build Coastguard Worker containsUserDefinedInputs = true;
1572*35238bceSAndroid Build Coastguard Worker }
1573*35238bceSAndroid Build Coastguard Worker }
1574*35238bceSAndroid Build Coastguard Worker
1575*35238bceSAndroid Build Coastguard Worker // Built-in-inputs
1576*35238bceSAndroid Build Coastguard Worker
1577*35238bceSAndroid Build Coastguard Worker switch (shader->getType())
1578*35238bceSAndroid Build Coastguard Worker {
1579*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
1580*35238bceSAndroid Build Coastguard Worker // make readInputs to never be compile time constant
1581*35238bceSAndroid Build Coastguard Worker if (!containsUserDefinedInputs)
1582*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += vec4(float(gl_VertexID));\n";
1583*35238bceSAndroid Build Coastguard Worker break;
1584*35238bceSAndroid Build Coastguard Worker
1585*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
1586*35238bceSAndroid Build Coastguard Worker // make readInputs to never be compile time constant
1587*35238bceSAndroid Build Coastguard Worker if (!containsUserDefinedInputs)
1588*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += gl_FragCoord;\n";
1589*35238bceSAndroid Build Coastguard Worker break;
1590*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
1591*35238bceSAndroid Build Coastguard Worker // always use previous stage's output values so that previous stage won't be optimized out
1592*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += gl_in[0].gl_Position;\n";
1593*35238bceSAndroid Build Coastguard Worker break;
1594*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
1595*35238bceSAndroid Build Coastguard Worker // always use previous stage's output values so that previous stage won't be optimized out
1596*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += gl_in[0].gl_Position;\n";
1597*35238bceSAndroid Build Coastguard Worker break;
1598*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
1599*35238bceSAndroid Build Coastguard Worker // always use previous stage's output values so that previous stage won't be optimized out
1600*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += gl_in[0].gl_Position;\n";
1601*35238bceSAndroid Build Coastguard Worker break;
1602*35238bceSAndroid Build Coastguard Worker
1603*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_COMPUTE:
1604*35238bceSAndroid Build Coastguard Worker // make readInputs to never be compile time constant
1605*35238bceSAndroid Build Coastguard Worker if (!containsUserDefinedInputs)
1606*35238bceSAndroid Build Coastguard Worker usageBuf << " retValue += vec4(float(gl_NumWorkGroups.x));\n";
1607*35238bceSAndroid Build Coastguard Worker break;
1608*35238bceSAndroid Build Coastguard Worker default:
1609*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1610*35238bceSAndroid Build Coastguard Worker }
1611*35238bceSAndroid Build Coastguard Worker
1612*35238bceSAndroid Build Coastguard Worker usageBuf << " return retValue;\n"
1613*35238bceSAndroid Build Coastguard Worker "}\n\n";
1614*35238bceSAndroid Build Coastguard Worker
1615*35238bceSAndroid Build Coastguard Worker usageBuf << "void writeOutputs(in highp vec4 unusedValue)\n"
1616*35238bceSAndroid Build Coastguard Worker "{\n";
1617*35238bceSAndroid Build Coastguard Worker
1618*35238bceSAndroid Build Coastguard Worker // User-defined outputs
1619*35238bceSAndroid Build Coastguard Worker
1620*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx)
1621*35238bceSAndroid Build Coastguard Worker {
1622*35238bceSAndroid Build Coastguard Worker if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_OUT ||
1623*35238bceSAndroid Build Coastguard Worker shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_PATCH_OUT)
1624*35238bceSAndroid Build Coastguard Worker {
1625*35238bceSAndroid Build Coastguard Worker writeVariableWriteExpression(usageBuf, "unusedValue", shader->getDefaultBlock().variables[ndx].name,
1626*35238bceSAndroid Build Coastguard Worker shader->getType(), shader->getDefaultBlock().variables[ndx].storage,
1627*35238bceSAndroid Build Coastguard Worker program, shader->getDefaultBlock().variables[ndx].varType);
1628*35238bceSAndroid Build Coastguard Worker containsUserDefinedOutputs = true;
1629*35238bceSAndroid Build Coastguard Worker }
1630*35238bceSAndroid Build Coastguard Worker }
1631*35238bceSAndroid Build Coastguard Worker
1632*35238bceSAndroid Build Coastguard Worker for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1633*35238bceSAndroid Build Coastguard Worker {
1634*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlock &interface = shader->getDefaultBlock().interfaceBlocks[interfaceNdx];
1635*35238bceSAndroid Build Coastguard Worker if (isWritableInterface(interface))
1636*35238bceSAndroid Build Coastguard Worker {
1637*35238bceSAndroid Build Coastguard Worker writeInterfaceWriteExpression(usageBuf, "unusedValue", interface, shader->getType(), program);
1638*35238bceSAndroid Build Coastguard Worker containsUserDefinedOutputs = true;
1639*35238bceSAndroid Build Coastguard Worker }
1640*35238bceSAndroid Build Coastguard Worker }
1641*35238bceSAndroid Build Coastguard Worker
1642*35238bceSAndroid Build Coastguard Worker // Builtin-outputs that must be written to
1643*35238bceSAndroid Build Coastguard Worker
1644*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_VERTEX)
1645*35238bceSAndroid Build Coastguard Worker usageBuf << " gl_Position = unusedValue;\n";
1646*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_GEOMETRY)
1647*35238bceSAndroid Build Coastguard Worker usageBuf << " gl_Position = unusedValue;\n"
1648*35238bceSAndroid Build Coastguard Worker " EmitVertex();\n";
1649*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_CONTROL)
1650*35238bceSAndroid Build Coastguard Worker usageBuf << " gl_out[gl_InvocationID].gl_Position = unusedValue;\n"
1651*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[0] = 2.8;\n"
1652*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[1] = 2.8;\n"
1653*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[2] = 2.8;\n"
1654*35238bceSAndroid Build Coastguard Worker " gl_TessLevelOuter[3] = 2.8;\n"
1655*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[0] = 2.8;\n"
1656*35238bceSAndroid Build Coastguard Worker " gl_TessLevelInner[1] = 2.8;\n";
1657*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_EVALUATION)
1658*35238bceSAndroid Build Coastguard Worker usageBuf << " gl_Position = unusedValue;\n";
1659*35238bceSAndroid Build Coastguard Worker
1660*35238bceSAndroid Build Coastguard Worker // Output to sink input data to
1661*35238bceSAndroid Build Coastguard Worker
1662*35238bceSAndroid Build Coastguard Worker if (!containsUserDefinedOutputs)
1663*35238bceSAndroid Build Coastguard Worker {
1664*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_FRAGMENT)
1665*35238bceSAndroid Build Coastguard Worker usageBuf << " gl_FragDepth = dot(unusedValue.xy, unusedValue.xw);\n";
1666*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_COMPUTE)
1667*35238bceSAndroid Build Coastguard Worker usageBuf << " unusedOutputBlock.unusedValue = unusedValue;\n";
1668*35238bceSAndroid Build Coastguard Worker }
1669*35238bceSAndroid Build Coastguard Worker
1670*35238bceSAndroid Build Coastguard Worker usageBuf << "}\n\n"
1671*35238bceSAndroid Build Coastguard Worker "void main()\n"
1672*35238bceSAndroid Build Coastguard Worker "{\n"
1673*35238bceSAndroid Build Coastguard Worker " writeOutputs(readInputs());\n"
1674*35238bceSAndroid Build Coastguard Worker "}\n";
1675*35238bceSAndroid Build Coastguard Worker
1676*35238bceSAndroid Build Coastguard Worker // Interface for unused output
1677*35238bceSAndroid Build Coastguard Worker
1678*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_COMPUTE && !containsUserDefinedOutputs)
1679*35238bceSAndroid Build Coastguard Worker {
1680*35238bceSAndroid Build Coastguard Worker sourceBuf << "writeonly buffer UnusedOutputInterface\n"
1681*35238bceSAndroid Build Coastguard Worker << "{\n"
1682*35238bceSAndroid Build Coastguard Worker << " highp vec4 unusedValue;\n"
1683*35238bceSAndroid Build Coastguard Worker << "} unusedOutputBlock;\n\n";
1684*35238bceSAndroid Build Coastguard Worker }
1685*35238bceSAndroid Build Coastguard Worker
1686*35238bceSAndroid Build Coastguard Worker sources << glu::ShaderSource(shader->getType(), sourceBuf.str() + usageBuf.str());
1687*35238bceSAndroid Build Coastguard Worker }
1688*35238bceSAndroid Build Coastguard Worker
1689*35238bceSAndroid Build Coastguard Worker if (program->isSeparable())
1690*35238bceSAndroid Build Coastguard Worker sources << glu::ProgramSeparable(true);
1691*35238bceSAndroid Build Coastguard Worker
1692*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx)
1693*35238bceSAndroid Build Coastguard Worker sources << glu::TransformFeedbackVarying(program->getTransformFeedbackVaryings()[ndx]);
1694*35238bceSAndroid Build Coastguard Worker
1695*35238bceSAndroid Build Coastguard Worker if (program->getTransformFeedbackMode())
1696*35238bceSAndroid Build Coastguard Worker sources << glu::TransformFeedbackMode(program->getTransformFeedbackMode());
1697*35238bceSAndroid Build Coastguard Worker
1698*35238bceSAndroid Build Coastguard Worker return sources;
1699*35238bceSAndroid Build Coastguard Worker }
1700*35238bceSAndroid Build Coastguard Worker
findProgramVariablePathByPathName(std::vector<VariablePathComponent> & typePath,const ProgramInterfaceDefinition::Program * program,const std::string & pathName,const VariableSearchFilter & filter)1701*35238bceSAndroid Build Coastguard Worker bool findProgramVariablePathByPathName(std::vector<VariablePathComponent> &typePath,
1702*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program, const std::string &pathName,
1703*35238bceSAndroid Build Coastguard Worker const VariableSearchFilter &filter)
1704*35238bceSAndroid Build Coastguard Worker {
1705*35238bceSAndroid Build Coastguard Worker std::vector<VariablePathComponent> modifiedPath;
1706*35238bceSAndroid Build Coastguard Worker
1707*35238bceSAndroid Build Coastguard Worker if (!traverseProgramVariablePath(modifiedPath, program, pathName, filter))
1708*35238bceSAndroid Build Coastguard Worker return false;
1709*35238bceSAndroid Build Coastguard Worker
1710*35238bceSAndroid Build Coastguard Worker // modify param only on success
1711*35238bceSAndroid Build Coastguard Worker typePath.swap(modifiedPath);
1712*35238bceSAndroid Build Coastguard Worker return true;
1713*35238bceSAndroid Build Coastguard Worker }
1714*35238bceSAndroid Build Coastguard Worker
getShaderResourceUsage(const ProgramInterfaceDefinition::Program * program,const ProgramInterfaceDefinition::Shader * shader)1715*35238bceSAndroid Build Coastguard Worker ProgramInterfaceDefinition::ShaderResourceUsage getShaderResourceUsage(
1716*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program, const ProgramInterfaceDefinition::Shader *shader)
1717*35238bceSAndroid Build Coastguard Worker {
1718*35238bceSAndroid Build Coastguard Worker ProgramInterfaceDefinition::ShaderResourceUsage retVal;
1719*35238bceSAndroid Build Coastguard Worker
1720*35238bceSAndroid Build Coastguard Worker retVal.numInputs = getNumTypeInstances(shader, glu::STORAGE_IN);
1721*35238bceSAndroid Build Coastguard Worker retVal.numInputVectors = getNumVectors(shader, glu::STORAGE_IN);
1722*35238bceSAndroid Build Coastguard Worker retVal.numInputComponents = getNumComponents(shader, glu::STORAGE_IN);
1723*35238bceSAndroid Build Coastguard Worker
1724*35238bceSAndroid Build Coastguard Worker retVal.numOutputs = getNumTypeInstances(shader, glu::STORAGE_OUT);
1725*35238bceSAndroid Build Coastguard Worker retVal.numOutputVectors = getNumVectors(shader, glu::STORAGE_OUT);
1726*35238bceSAndroid Build Coastguard Worker retVal.numOutputComponents = getNumComponents(shader, glu::STORAGE_OUT);
1727*35238bceSAndroid Build Coastguard Worker
1728*35238bceSAndroid Build Coastguard Worker retVal.numPatchInputComponents = getNumComponents(shader, glu::STORAGE_PATCH_IN);
1729*35238bceSAndroid Build Coastguard Worker retVal.numPatchOutputComponents = getNumComponents(shader, glu::STORAGE_PATCH_OUT);
1730*35238bceSAndroid Build Coastguard Worker
1731*35238bceSAndroid Build Coastguard Worker retVal.numDefaultBlockUniformComponents = getNumDefaultBlockComponents(shader, glu::STORAGE_UNIFORM);
1732*35238bceSAndroid Build Coastguard Worker retVal.numCombinedUniformComponents = getNumComponents(shader, glu::STORAGE_UNIFORM);
1733*35238bceSAndroid Build Coastguard Worker retVal.numUniformVectors = getNumVectors(shader, glu::STORAGE_UNIFORM);
1734*35238bceSAndroid Build Coastguard Worker
1735*35238bceSAndroid Build Coastguard Worker retVal.numSamplers = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeSampler);
1736*35238bceSAndroid Build Coastguard Worker retVal.numImages = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage);
1737*35238bceSAndroid Build Coastguard Worker
1738*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounterBuffers = getNumAtomicCounterBuffers(shader);
1739*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounters = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeAtomicCounter);
1740*35238bceSAndroid Build Coastguard Worker
1741*35238bceSAndroid Build Coastguard Worker retVal.numUniformBlocks = getNumShaderBlocks(shader, glu::STORAGE_UNIFORM);
1742*35238bceSAndroid Build Coastguard Worker retVal.numShaderStorageBlocks = getNumShaderBlocks(shader, glu::STORAGE_BUFFER);
1743*35238bceSAndroid Build Coastguard Worker
1744*35238bceSAndroid Build Coastguard Worker // add builtins
1745*35238bceSAndroid Build Coastguard Worker switch (shader->getType())
1746*35238bceSAndroid Build Coastguard Worker {
1747*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
1748*35238bceSAndroid Build Coastguard Worker // gl_Position is not counted
1749*35238bceSAndroid Build Coastguard Worker break;
1750*35238bceSAndroid Build Coastguard Worker
1751*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
1752*35238bceSAndroid Build Coastguard Worker // nada
1753*35238bceSAndroid Build Coastguard Worker break;
1754*35238bceSAndroid Build Coastguard Worker
1755*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
1756*35238bceSAndroid Build Coastguard Worker // gl_Position in (point mode => size 1)
1757*35238bceSAndroid Build Coastguard Worker retVal.numInputs += 1;
1758*35238bceSAndroid Build Coastguard Worker retVal.numInputVectors += 1;
1759*35238bceSAndroid Build Coastguard Worker retVal.numInputComponents += 4;
1760*35238bceSAndroid Build Coastguard Worker
1761*35238bceSAndroid Build Coastguard Worker // gl_Position out
1762*35238bceSAndroid Build Coastguard Worker retVal.numOutputs += 1;
1763*35238bceSAndroid Build Coastguard Worker retVal.numOutputVectors += 1;
1764*35238bceSAndroid Build Coastguard Worker retVal.numOutputComponents += 4;
1765*35238bceSAndroid Build Coastguard Worker break;
1766*35238bceSAndroid Build Coastguard Worker
1767*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
1768*35238bceSAndroid Build Coastguard Worker // gl_Position in is read up to gl_InstanceID
1769*35238bceSAndroid Build Coastguard Worker retVal.numInputs += 1 * program->getTessellationNumOutputPatchVertices();
1770*35238bceSAndroid Build Coastguard Worker retVal.numInputVectors += 1 * program->getTessellationNumOutputPatchVertices();
1771*35238bceSAndroid Build Coastguard Worker retVal.numInputComponents += 4 * program->getTessellationNumOutputPatchVertices();
1772*35238bceSAndroid Build Coastguard Worker
1773*35238bceSAndroid Build Coastguard Worker // gl_Position out, size = num patch out vertices
1774*35238bceSAndroid Build Coastguard Worker retVal.numOutputs += 1 * program->getTessellationNumOutputPatchVertices();
1775*35238bceSAndroid Build Coastguard Worker retVal.numOutputVectors += 1 * program->getTessellationNumOutputPatchVertices();
1776*35238bceSAndroid Build Coastguard Worker retVal.numOutputComponents += 4 * program->getTessellationNumOutputPatchVertices();
1777*35238bceSAndroid Build Coastguard Worker break;
1778*35238bceSAndroid Build Coastguard Worker
1779*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
1780*35238bceSAndroid Build Coastguard Worker // gl_Position in is read up to gl_InstanceID
1781*35238bceSAndroid Build Coastguard Worker retVal.numInputs += 1 * program->getTessellationNumOutputPatchVertices();
1782*35238bceSAndroid Build Coastguard Worker retVal.numInputVectors += 1 * program->getTessellationNumOutputPatchVertices();
1783*35238bceSAndroid Build Coastguard Worker retVal.numInputComponents += 4 * program->getTessellationNumOutputPatchVertices();
1784*35238bceSAndroid Build Coastguard Worker
1785*35238bceSAndroid Build Coastguard Worker // gl_Position out
1786*35238bceSAndroid Build Coastguard Worker retVal.numOutputs += 1;
1787*35238bceSAndroid Build Coastguard Worker retVal.numOutputVectors += 1;
1788*35238bceSAndroid Build Coastguard Worker retVal.numOutputComponents += 4;
1789*35238bceSAndroid Build Coastguard Worker break;
1790*35238bceSAndroid Build Coastguard Worker
1791*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_COMPUTE:
1792*35238bceSAndroid Build Coastguard Worker // nada
1793*35238bceSAndroid Build Coastguard Worker break;
1794*35238bceSAndroid Build Coastguard Worker
1795*35238bceSAndroid Build Coastguard Worker default:
1796*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1797*35238bceSAndroid Build Coastguard Worker break;
1798*35238bceSAndroid Build Coastguard Worker }
1799*35238bceSAndroid Build Coastguard Worker return retVal;
1800*35238bceSAndroid Build Coastguard Worker }
1801*35238bceSAndroid Build Coastguard Worker
getCombinedProgramResourceUsage(const ProgramInterfaceDefinition::Program * program)1802*35238bceSAndroid Build Coastguard Worker ProgramInterfaceDefinition::ProgramResourceUsage getCombinedProgramResourceUsage(
1803*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Program *program)
1804*35238bceSAndroid Build Coastguard Worker {
1805*35238bceSAndroid Build Coastguard Worker ProgramInterfaceDefinition::ProgramResourceUsage retVal;
1806*35238bceSAndroid Build Coastguard Worker int numVertexOutputComponents = 0;
1807*35238bceSAndroid Build Coastguard Worker int numFragmentInputComponents = 0;
1808*35238bceSAndroid Build Coastguard Worker int numVertexOutputVectors = 0;
1809*35238bceSAndroid Build Coastguard Worker int numFragmentInputVectors = 0;
1810*35238bceSAndroid Build Coastguard Worker
1811*35238bceSAndroid Build Coastguard Worker retVal.uniformBufferMaxBinding =
1812*35238bceSAndroid Build Coastguard Worker -1; // max binding is inclusive upper bound. Allow 0 bindings by using negative value
1813*35238bceSAndroid Build Coastguard Worker retVal.uniformBufferMaxSize = 0;
1814*35238bceSAndroid Build Coastguard Worker retVal.numUniformBlocks = 0;
1815*35238bceSAndroid Build Coastguard Worker retVal.numCombinedVertexUniformComponents = 0;
1816*35238bceSAndroid Build Coastguard Worker retVal.numCombinedFragmentUniformComponents = 0;
1817*35238bceSAndroid Build Coastguard Worker retVal.numCombinedGeometryUniformComponents = 0;
1818*35238bceSAndroid Build Coastguard Worker retVal.numCombinedTessControlUniformComponents = 0;
1819*35238bceSAndroid Build Coastguard Worker retVal.numCombinedTessEvalUniformComponents = 0;
1820*35238bceSAndroid Build Coastguard Worker retVal.shaderStorageBufferMaxBinding = -1; // see above
1821*35238bceSAndroid Build Coastguard Worker retVal.shaderStorageBufferMaxSize = 0;
1822*35238bceSAndroid Build Coastguard Worker retVal.numShaderStorageBlocks = 0;
1823*35238bceSAndroid Build Coastguard Worker retVal.numVaryingComponents = 0;
1824*35238bceSAndroid Build Coastguard Worker retVal.numVaryingVectors = 0;
1825*35238bceSAndroid Build Coastguard Worker retVal.numCombinedSamplers = 0;
1826*35238bceSAndroid Build Coastguard Worker retVal.atomicCounterBufferMaxBinding = -1; // see above
1827*35238bceSAndroid Build Coastguard Worker retVal.atomicCounterBufferMaxSize = 0;
1828*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounterBuffers = 0;
1829*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounters = 0;
1830*35238bceSAndroid Build Coastguard Worker retVal.maxImageBinding = -1; // see above
1831*35238bceSAndroid Build Coastguard Worker retVal.numCombinedImages = 0;
1832*35238bceSAndroid Build Coastguard Worker retVal.numCombinedOutputResources = 0;
1833*35238bceSAndroid Build Coastguard Worker retVal.numXFBInterleavedComponents = 0;
1834*35238bceSAndroid Build Coastguard Worker retVal.numXFBSeparateAttribs = 0;
1835*35238bceSAndroid Build Coastguard Worker retVal.numXFBSeparateComponents = 0;
1836*35238bceSAndroid Build Coastguard Worker retVal.fragmentOutputMaxBinding = -1; // see above
1837*35238bceSAndroid Build Coastguard Worker
1838*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
1839*35238bceSAndroid Build Coastguard Worker {
1840*35238bceSAndroid Build Coastguard Worker const ProgramInterfaceDefinition::Shader *const shader = program->getShaders()[shaderNdx];
1841*35238bceSAndroid Build Coastguard Worker
1842*35238bceSAndroid Build Coastguard Worker retVal.uniformBufferMaxBinding =
1843*35238bceSAndroid Build Coastguard Worker de::max(retVal.uniformBufferMaxBinding, getMaxBufferBinding(shader, glu::STORAGE_UNIFORM));
1844*35238bceSAndroid Build Coastguard Worker retVal.uniformBufferMaxSize =
1845*35238bceSAndroid Build Coastguard Worker de::max(retVal.uniformBufferMaxSize, getBufferMaxSize(shader, glu::STORAGE_UNIFORM));
1846*35238bceSAndroid Build Coastguard Worker retVal.numUniformBlocks += getNumShaderBlocks(shader, glu::STORAGE_UNIFORM);
1847*35238bceSAndroid Build Coastguard Worker
1848*35238bceSAndroid Build Coastguard Worker switch (shader->getType())
1849*35238bceSAndroid Build Coastguard Worker {
1850*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_VERTEX:
1851*35238bceSAndroid Build Coastguard Worker retVal.numCombinedVertexUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM);
1852*35238bceSAndroid Build Coastguard Worker break;
1853*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_FRAGMENT:
1854*35238bceSAndroid Build Coastguard Worker retVal.numCombinedFragmentUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM);
1855*35238bceSAndroid Build Coastguard Worker break;
1856*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_GEOMETRY:
1857*35238bceSAndroid Build Coastguard Worker retVal.numCombinedGeometryUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM);
1858*35238bceSAndroid Build Coastguard Worker break;
1859*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_CONTROL:
1860*35238bceSAndroid Build Coastguard Worker retVal.numCombinedTessControlUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM);
1861*35238bceSAndroid Build Coastguard Worker break;
1862*35238bceSAndroid Build Coastguard Worker case glu::SHADERTYPE_TESSELLATION_EVALUATION:
1863*35238bceSAndroid Build Coastguard Worker retVal.numCombinedTessEvalUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM);
1864*35238bceSAndroid Build Coastguard Worker break;
1865*35238bceSAndroid Build Coastguard Worker default:
1866*35238bceSAndroid Build Coastguard Worker break;
1867*35238bceSAndroid Build Coastguard Worker }
1868*35238bceSAndroid Build Coastguard Worker
1869*35238bceSAndroid Build Coastguard Worker retVal.shaderStorageBufferMaxBinding =
1870*35238bceSAndroid Build Coastguard Worker de::max(retVal.shaderStorageBufferMaxBinding, getMaxBufferBinding(shader, glu::STORAGE_BUFFER));
1871*35238bceSAndroid Build Coastguard Worker retVal.shaderStorageBufferMaxSize =
1872*35238bceSAndroid Build Coastguard Worker de::max(retVal.shaderStorageBufferMaxSize, getBufferMaxSize(shader, glu::STORAGE_BUFFER));
1873*35238bceSAndroid Build Coastguard Worker retVal.numShaderStorageBlocks += getNumShaderBlocks(shader, glu::STORAGE_BUFFER);
1874*35238bceSAndroid Build Coastguard Worker
1875*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_VERTEX)
1876*35238bceSAndroid Build Coastguard Worker {
1877*35238bceSAndroid Build Coastguard Worker numVertexOutputComponents += getNumComponents(shader, glu::STORAGE_OUT);
1878*35238bceSAndroid Build Coastguard Worker numVertexOutputVectors += getNumVectors(shader, glu::STORAGE_OUT);
1879*35238bceSAndroid Build Coastguard Worker }
1880*35238bceSAndroid Build Coastguard Worker else if (shader->getType() == glu::SHADERTYPE_FRAGMENT)
1881*35238bceSAndroid Build Coastguard Worker {
1882*35238bceSAndroid Build Coastguard Worker numFragmentInputComponents += getNumComponents(shader, glu::STORAGE_IN);
1883*35238bceSAndroid Build Coastguard Worker numFragmentInputVectors += getNumVectors(shader, glu::STORAGE_IN);
1884*35238bceSAndroid Build Coastguard Worker }
1885*35238bceSAndroid Build Coastguard Worker
1886*35238bceSAndroid Build Coastguard Worker retVal.numCombinedSamplers += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeSampler);
1887*35238bceSAndroid Build Coastguard Worker
1888*35238bceSAndroid Build Coastguard Worker retVal.atomicCounterBufferMaxBinding =
1889*35238bceSAndroid Build Coastguard Worker de::max(retVal.atomicCounterBufferMaxBinding, getAtomicCounterMaxBinding(shader));
1890*35238bceSAndroid Build Coastguard Worker retVal.atomicCounterBufferMaxSize =
1891*35238bceSAndroid Build Coastguard Worker de::max(retVal.atomicCounterBufferMaxSize, getAtomicCounterMaxBufferSize(shader));
1892*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounterBuffers += getNumAtomicCounterBuffers(shader);
1893*35238bceSAndroid Build Coastguard Worker retVal.numAtomicCounters += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeAtomicCounter);
1894*35238bceSAndroid Build Coastguard Worker retVal.maxImageBinding = de::max(retVal.maxImageBinding, getUniformMaxBinding(shader, glu::isDataTypeImage));
1895*35238bceSAndroid Build Coastguard Worker retVal.numCombinedImages += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage);
1896*35238bceSAndroid Build Coastguard Worker
1897*35238bceSAndroid Build Coastguard Worker retVal.numCombinedOutputResources += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage);
1898*35238bceSAndroid Build Coastguard Worker retVal.numCombinedOutputResources += getNumShaderBlocks(shader, glu::STORAGE_BUFFER);
1899*35238bceSAndroid Build Coastguard Worker
1900*35238bceSAndroid Build Coastguard Worker if (shader->getType() == glu::SHADERTYPE_FRAGMENT)
1901*35238bceSAndroid Build Coastguard Worker {
1902*35238bceSAndroid Build Coastguard Worker retVal.numCombinedOutputResources += getNumVectors(shader, glu::STORAGE_OUT);
1903*35238bceSAndroid Build Coastguard Worker retVal.fragmentOutputMaxBinding =
1904*35238bceSAndroid Build Coastguard Worker de::max(retVal.fragmentOutputMaxBinding, getFragmentOutputMaxLocation(shader));
1905*35238bceSAndroid Build Coastguard Worker }
1906*35238bceSAndroid Build Coastguard Worker }
1907*35238bceSAndroid Build Coastguard Worker
1908*35238bceSAndroid Build Coastguard Worker if (program->getTransformFeedbackMode() == GL_INTERLEAVED_ATTRIBS)
1909*35238bceSAndroid Build Coastguard Worker retVal.numXFBInterleavedComponents = getNumXFBComponents(program);
1910*35238bceSAndroid Build Coastguard Worker else if (program->getTransformFeedbackMode() == GL_SEPARATE_ATTRIBS)
1911*35238bceSAndroid Build Coastguard Worker {
1912*35238bceSAndroid Build Coastguard Worker retVal.numXFBSeparateAttribs = (int)program->getTransformFeedbackVaryings().size();
1913*35238bceSAndroid Build Coastguard Worker retVal.numXFBSeparateComponents = getNumMaxXFBOutputComponents(program);
1914*35238bceSAndroid Build Coastguard Worker }
1915*35238bceSAndroid Build Coastguard Worker
1916*35238bceSAndroid Build Coastguard Worker // legacy limits
1917*35238bceSAndroid Build Coastguard Worker retVal.numVaryingComponents = de::max(numVertexOutputComponents, numFragmentInputComponents);
1918*35238bceSAndroid Build Coastguard Worker retVal.numVaryingVectors = de::max(numVertexOutputVectors, numFragmentInputVectors);
1919*35238bceSAndroid Build Coastguard Worker
1920*35238bceSAndroid Build Coastguard Worker return retVal;
1921*35238bceSAndroid Build Coastguard Worker }
1922*35238bceSAndroid Build Coastguard Worker
1923*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1924*35238bceSAndroid Build Coastguard Worker } // namespace gles31
1925*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1926