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 SSBO layout case.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fSSBOLayoutCase.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluProgramInterfaceQuery.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluVarTypeUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
39*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
41*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
42*35238bceSAndroid Build Coastguard Worker #include "deString.h"
43*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
44*35238bceSAndroid Build Coastguard Worker
45*35238bceSAndroid Build Coastguard Worker #include <algorithm>
46*35238bceSAndroid Build Coastguard Worker #include <map>
47*35238bceSAndroid Build Coastguard Worker
48*35238bceSAndroid Build Coastguard Worker using std::map;
49*35238bceSAndroid Build Coastguard Worker using std::string;
50*35238bceSAndroid Build Coastguard Worker using std::vector;
51*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker namespace deqp
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker namespace gles31
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker using glu::StructMember;
59*35238bceSAndroid Build Coastguard Worker using glu::StructType;
60*35238bceSAndroid Build Coastguard Worker using glu::VarType;
61*35238bceSAndroid Build Coastguard Worker
62*35238bceSAndroid Build Coastguard Worker namespace bb
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker
65*35238bceSAndroid Build Coastguard Worker struct LayoutFlagsFmt
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker uint32_t flags;
LayoutFlagsFmtdeqp::gles31::bb::LayoutFlagsFmt68*35238bceSAndroid Build Coastguard Worker LayoutFlagsFmt(uint32_t flags_) : flags(flags_)
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker }
71*35238bceSAndroid Build Coastguard Worker };
72*35238bceSAndroid Build Coastguard Worker
operator <<(std::ostream & str,const LayoutFlagsFmt & fmt)73*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &str, const LayoutFlagsFmt &fmt)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker static const struct
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker uint32_t bit;
78*35238bceSAndroid Build Coastguard Worker const char *token;
79*35238bceSAndroid Build Coastguard Worker } bitDesc[] = {{LAYOUT_SHARED, "shared"}, {LAYOUT_PACKED, "packed"}, {LAYOUT_STD140, "std140"},
80*35238bceSAndroid Build Coastguard Worker {LAYOUT_STD430, "std430"}, {LAYOUT_ROW_MAJOR, "row_major"}, {LAYOUT_COLUMN_MAJOR, "column_major"}};
81*35238bceSAndroid Build Coastguard Worker
82*35238bceSAndroid Build Coastguard Worker uint32_t remBits = fmt.flags;
83*35238bceSAndroid Build Coastguard Worker for (int descNdx = 0; descNdx < DE_LENGTH_OF_ARRAY(bitDesc); descNdx++)
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker if (remBits & bitDesc[descNdx].bit)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker if (remBits != fmt.flags)
88*35238bceSAndroid Build Coastguard Worker str << ", ";
89*35238bceSAndroid Build Coastguard Worker str << bitDesc[descNdx].token;
90*35238bceSAndroid Build Coastguard Worker remBits &= ~bitDesc[descNdx].bit;
91*35238bceSAndroid Build Coastguard Worker }
92*35238bceSAndroid Build Coastguard Worker }
93*35238bceSAndroid Build Coastguard Worker DE_ASSERT(remBits == 0);
94*35238bceSAndroid Build Coastguard Worker return str;
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker // BufferVar implementation.
98*35238bceSAndroid Build Coastguard Worker
BufferVar(const char * name,const VarType & type,uint32_t flags)99*35238bceSAndroid Build Coastguard Worker BufferVar::BufferVar(const char *name, const VarType &type, uint32_t flags) : m_name(name), m_type(type), m_flags(flags)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker
103*35238bceSAndroid Build Coastguard Worker // BufferBlock implementation.
104*35238bceSAndroid Build Coastguard Worker
BufferBlock(const char * blockName)105*35238bceSAndroid Build Coastguard Worker BufferBlock::BufferBlock(const char *blockName) : m_blockName(blockName), m_arraySize(-1), m_flags(0)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker setArraySize(0);
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker
setArraySize(int arraySize)110*35238bceSAndroid Build Coastguard Worker void BufferBlock::setArraySize(int arraySize)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker DE_ASSERT(arraySize >= 0);
113*35238bceSAndroid Build Coastguard Worker m_lastUnsizedArraySizes.resize(arraySize == 0 ? 1 : arraySize, 0);
114*35238bceSAndroid Build Coastguard Worker m_arraySize = arraySize;
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker
117*35238bceSAndroid Build Coastguard Worker struct BlockLayoutEntry
118*35238bceSAndroid Build Coastguard Worker {
BlockLayoutEntrydeqp::gles31::bb::BlockLayoutEntry119*35238bceSAndroid Build Coastguard Worker BlockLayoutEntry(void) : size(0)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker std::string name;
124*35238bceSAndroid Build Coastguard Worker int size;
125*35238bceSAndroid Build Coastguard Worker std::vector<int> activeVarIndices;
126*35238bceSAndroid Build Coastguard Worker };
127*35238bceSAndroid Build Coastguard Worker
operator <<(std::ostream & stream,const BlockLayoutEntry & entry)128*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &stream, const BlockLayoutEntry &entry)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker stream << entry.name << " { name = " << entry.name << ", size = " << entry.size << ", activeVarIndices = [";
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator i = entry.activeVarIndices.begin(); i != entry.activeVarIndices.end(); i++)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker if (i != entry.activeVarIndices.begin())
135*35238bceSAndroid Build Coastguard Worker stream << ", ";
136*35238bceSAndroid Build Coastguard Worker stream << *i;
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker
139*35238bceSAndroid Build Coastguard Worker stream << "] }";
140*35238bceSAndroid Build Coastguard Worker return stream;
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker
143*35238bceSAndroid Build Coastguard Worker struct BufferVarLayoutEntry
144*35238bceSAndroid Build Coastguard Worker {
BufferVarLayoutEntrydeqp::gles31::bb::BufferVarLayoutEntry145*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry(void)
146*35238bceSAndroid Build Coastguard Worker : type(glu::TYPE_LAST)
147*35238bceSAndroid Build Coastguard Worker , blockNdx(-1)
148*35238bceSAndroid Build Coastguard Worker , offset(-1)
149*35238bceSAndroid Build Coastguard Worker , arraySize(-1)
150*35238bceSAndroid Build Coastguard Worker , arrayStride(-1)
151*35238bceSAndroid Build Coastguard Worker , matrixStride(-1)
152*35238bceSAndroid Build Coastguard Worker , topLevelArraySize(-1)
153*35238bceSAndroid Build Coastguard Worker , topLevelArrayStride(-1)
154*35238bceSAndroid Build Coastguard Worker , isRowMajor(false)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker }
157*35238bceSAndroid Build Coastguard Worker
158*35238bceSAndroid Build Coastguard Worker std::string name;
159*35238bceSAndroid Build Coastguard Worker glu::DataType type;
160*35238bceSAndroid Build Coastguard Worker int blockNdx;
161*35238bceSAndroid Build Coastguard Worker int offset;
162*35238bceSAndroid Build Coastguard Worker int arraySize;
163*35238bceSAndroid Build Coastguard Worker int arrayStride;
164*35238bceSAndroid Build Coastguard Worker int matrixStride;
165*35238bceSAndroid Build Coastguard Worker int topLevelArraySize;
166*35238bceSAndroid Build Coastguard Worker int topLevelArrayStride;
167*35238bceSAndroid Build Coastguard Worker bool isRowMajor;
168*35238bceSAndroid Build Coastguard Worker };
169*35238bceSAndroid Build Coastguard Worker
isUnsizedArray(const BufferVarLayoutEntry & entry)170*35238bceSAndroid Build Coastguard Worker static bool isUnsizedArray(const BufferVarLayoutEntry &entry)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker DE_ASSERT(entry.arraySize != 0 || entry.topLevelArraySize != 0);
173*35238bceSAndroid Build Coastguard Worker return entry.arraySize == 0 || entry.topLevelArraySize == 0;
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker
operator <<(std::ostream & stream,const BufferVarLayoutEntry & entry)176*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &stream, const BufferVarLayoutEntry &entry)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker stream << entry.name << " { type = " << glu::getDataTypeName(entry.type) << ", blockNdx = " << entry.blockNdx
179*35238bceSAndroid Build Coastguard Worker << ", offset = " << entry.offset << ", arraySize = " << entry.arraySize
180*35238bceSAndroid Build Coastguard Worker << ", arrayStride = " << entry.arrayStride << ", matrixStride = " << entry.matrixStride
181*35238bceSAndroid Build Coastguard Worker << ", topLevelArraySize = " << entry.topLevelArraySize
182*35238bceSAndroid Build Coastguard Worker << ", topLevelArrayStride = " << entry.topLevelArrayStride
183*35238bceSAndroid Build Coastguard Worker << ", isRowMajor = " << (entry.isRowMajor ? "true" : "false") << " }";
184*35238bceSAndroid Build Coastguard Worker return stream;
185*35238bceSAndroid Build Coastguard Worker }
186*35238bceSAndroid Build Coastguard Worker
187*35238bceSAndroid Build Coastguard Worker class BufferLayout
188*35238bceSAndroid Build Coastguard Worker {
189*35238bceSAndroid Build Coastguard Worker public:
190*35238bceSAndroid Build Coastguard Worker std::vector<BlockLayoutEntry> blocks;
191*35238bceSAndroid Build Coastguard Worker std::vector<BufferVarLayoutEntry> bufferVars;
192*35238bceSAndroid Build Coastguard Worker
193*35238bceSAndroid Build Coastguard Worker int getVariableIndex(const string &name) const;
194*35238bceSAndroid Build Coastguard Worker int getBlockIndex(const string &name) const;
195*35238bceSAndroid Build Coastguard Worker };
196*35238bceSAndroid Build Coastguard Worker
197*35238bceSAndroid Build Coastguard Worker // \todo [2012-01-24 pyry] Speed up lookups using hash.
198*35238bceSAndroid Build Coastguard Worker
getVariableIndex(const string & name) const199*35238bceSAndroid Build Coastguard Worker int BufferLayout::getVariableIndex(const string &name) const
200*35238bceSAndroid Build Coastguard Worker {
201*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)bufferVars.size(); ndx++)
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker if (bufferVars[ndx].name == name)
204*35238bceSAndroid Build Coastguard Worker return ndx;
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker return -1;
207*35238bceSAndroid Build Coastguard Worker }
208*35238bceSAndroid Build Coastguard Worker
getBlockIndex(const string & name) const209*35238bceSAndroid Build Coastguard Worker int BufferLayout::getBlockIndex(const string &name) const
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)blocks.size(); ndx++)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker if (blocks[ndx].name == name)
214*35238bceSAndroid Build Coastguard Worker return ndx;
215*35238bceSAndroid Build Coastguard Worker }
216*35238bceSAndroid Build Coastguard Worker return -1;
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker
219*35238bceSAndroid Build Coastguard Worker // ShaderInterface implementation.
220*35238bceSAndroid Build Coastguard Worker
ShaderInterface(void)221*35238bceSAndroid Build Coastguard Worker ShaderInterface::ShaderInterface(void)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker }
224*35238bceSAndroid Build Coastguard Worker
~ShaderInterface(void)225*35238bceSAndroid Build Coastguard Worker ShaderInterface::~ShaderInterface(void)
226*35238bceSAndroid Build Coastguard Worker {
227*35238bceSAndroid Build Coastguard Worker for (std::vector<StructType *>::iterator i = m_structs.begin(); i != m_structs.end(); i++)
228*35238bceSAndroid Build Coastguard Worker delete *i;
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker for (std::vector<BufferBlock *>::iterator i = m_bufferBlocks.begin(); i != m_bufferBlocks.end(); i++)
231*35238bceSAndroid Build Coastguard Worker delete *i;
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker
allocStruct(const char * name)234*35238bceSAndroid Build Coastguard Worker StructType &ShaderInterface::allocStruct(const char *name)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker m_structs.reserve(m_structs.size() + 1);
237*35238bceSAndroid Build Coastguard Worker m_structs.push_back(new StructType(name));
238*35238bceSAndroid Build Coastguard Worker return *m_structs.back();
239*35238bceSAndroid Build Coastguard Worker }
240*35238bceSAndroid Build Coastguard Worker
241*35238bceSAndroid Build Coastguard Worker struct StructNameEquals
242*35238bceSAndroid Build Coastguard Worker {
243*35238bceSAndroid Build Coastguard Worker std::string name;
244*35238bceSAndroid Build Coastguard Worker
StructNameEqualsdeqp::gles31::bb::StructNameEquals245*35238bceSAndroid Build Coastguard Worker StructNameEquals(const char *name_) : name(name_)
246*35238bceSAndroid Build Coastguard Worker {
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker
operator ()deqp::gles31::bb::StructNameEquals249*35238bceSAndroid Build Coastguard Worker bool operator()(const StructType *type) const
250*35238bceSAndroid Build Coastguard Worker {
251*35238bceSAndroid Build Coastguard Worker return type->getTypeName() && name == type->getTypeName();
252*35238bceSAndroid Build Coastguard Worker }
253*35238bceSAndroid Build Coastguard Worker };
254*35238bceSAndroid Build Coastguard Worker
findStruct(const char * name) const255*35238bceSAndroid Build Coastguard Worker const StructType *ShaderInterface::findStruct(const char *name) const
256*35238bceSAndroid Build Coastguard Worker {
257*35238bceSAndroid Build Coastguard Worker std::vector<StructType *>::const_iterator pos =
258*35238bceSAndroid Build Coastguard Worker std::find_if(m_structs.begin(), m_structs.end(), StructNameEquals(name));
259*35238bceSAndroid Build Coastguard Worker return pos != m_structs.end() ? *pos : DE_NULL;
260*35238bceSAndroid Build Coastguard Worker }
261*35238bceSAndroid Build Coastguard Worker
getNamedStructs(std::vector<const StructType * > & structs) const262*35238bceSAndroid Build Coastguard Worker void ShaderInterface::getNamedStructs(std::vector<const StructType *> &structs) const
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker for (std::vector<StructType *>::const_iterator i = m_structs.begin(); i != m_structs.end(); i++)
265*35238bceSAndroid Build Coastguard Worker {
266*35238bceSAndroid Build Coastguard Worker if ((*i)->getTypeName() != DE_NULL)
267*35238bceSAndroid Build Coastguard Worker structs.push_back(*i);
268*35238bceSAndroid Build Coastguard Worker }
269*35238bceSAndroid Build Coastguard Worker }
270*35238bceSAndroid Build Coastguard Worker
allocBlock(const char * name)271*35238bceSAndroid Build Coastguard Worker BufferBlock &ShaderInterface::allocBlock(const char *name)
272*35238bceSAndroid Build Coastguard Worker {
273*35238bceSAndroid Build Coastguard Worker m_bufferBlocks.reserve(m_bufferBlocks.size() + 1);
274*35238bceSAndroid Build Coastguard Worker m_bufferBlocks.push_back(new BufferBlock(name));
275*35238bceSAndroid Build Coastguard Worker return *m_bufferBlocks.back();
276*35238bceSAndroid Build Coastguard Worker }
277*35238bceSAndroid Build Coastguard Worker
278*35238bceSAndroid Build Coastguard Worker // BlockDataPtr
279*35238bceSAndroid Build Coastguard Worker
280*35238bceSAndroid Build Coastguard Worker struct BlockDataPtr
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker void *ptr;
283*35238bceSAndroid Build Coastguard Worker int size; //!< Redundant, for debugging purposes.
284*35238bceSAndroid Build Coastguard Worker int lastUnsizedArraySize;
285*35238bceSAndroid Build Coastguard Worker
BlockDataPtrdeqp::gles31::bb::BlockDataPtr286*35238bceSAndroid Build Coastguard Worker BlockDataPtr(void *ptr_, int size_, int lastUnsizedArraySize_)
287*35238bceSAndroid Build Coastguard Worker : ptr(ptr_)
288*35238bceSAndroid Build Coastguard Worker , size(size_)
289*35238bceSAndroid Build Coastguard Worker , lastUnsizedArraySize(lastUnsizedArraySize_)
290*35238bceSAndroid Build Coastguard Worker {
291*35238bceSAndroid Build Coastguard Worker }
292*35238bceSAndroid Build Coastguard Worker
BlockDataPtrdeqp::gles31::bb::BlockDataPtr293*35238bceSAndroid Build Coastguard Worker BlockDataPtr(void) : ptr(DE_NULL), size(0), lastUnsizedArraySize(0)
294*35238bceSAndroid Build Coastguard Worker {
295*35238bceSAndroid Build Coastguard Worker }
296*35238bceSAndroid Build Coastguard Worker };
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker namespace // Utilities
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker
findBlockIndex(const BufferLayout & layout,const string & name)301*35238bceSAndroid Build Coastguard Worker int findBlockIndex(const BufferLayout &layout, const string &name)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)layout.blocks.size(); ndx++)
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker if (layout.blocks[ndx].name == name)
306*35238bceSAndroid Build Coastguard Worker return ndx;
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker return -1;
309*35238bceSAndroid Build Coastguard Worker }
310*35238bceSAndroid Build Coastguard Worker
311*35238bceSAndroid Build Coastguard Worker // Layout computation.
312*35238bceSAndroid Build Coastguard Worker
getDataTypeByteSize(glu::DataType type)313*35238bceSAndroid Build Coastguard Worker int getDataTypeByteSize(glu::DataType type)
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeScalarSize(type) * (int)sizeof(uint32_t);
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker
getDataTypeByteAlignment(glu::DataType type)318*35238bceSAndroid Build Coastguard Worker int getDataTypeByteAlignment(glu::DataType type)
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker switch (type)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
323*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT:
324*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT:
325*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL:
326*35238bceSAndroid Build Coastguard Worker return 1 * (int)sizeof(uint32_t);
327*35238bceSAndroid Build Coastguard Worker
328*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC2:
329*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC2:
330*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC2:
331*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC2:
332*35238bceSAndroid Build Coastguard Worker return 2 * (int)sizeof(uint32_t);
333*35238bceSAndroid Build Coastguard Worker
334*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC3:
335*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC3:
336*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC3:
337*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC3: // Fall-through to vec4
338*35238bceSAndroid Build Coastguard Worker
339*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC4:
340*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC4:
341*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC4:
342*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC4:
343*35238bceSAndroid Build Coastguard Worker return 4 * (int)sizeof(uint32_t);
344*35238bceSAndroid Build Coastguard Worker
345*35238bceSAndroid Build Coastguard Worker default:
346*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
347*35238bceSAndroid Build Coastguard Worker return 0;
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker }
350*35238bceSAndroid Build Coastguard Worker
computeStd140BaseAlignment(const VarType & type,uint32_t layoutFlags)351*35238bceSAndroid Build Coastguard Worker int computeStd140BaseAlignment(const VarType &type, uint32_t layoutFlags)
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker const int vec4Alignment = (int)sizeof(uint32_t) * 4;
354*35238bceSAndroid Build Coastguard Worker
355*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
356*35238bceSAndroid Build Coastguard Worker {
357*35238bceSAndroid Build Coastguard Worker glu::DataType basicType = type.getBasicType();
358*35238bceSAndroid Build Coastguard Worker
359*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeMatrix(basicType))
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR);
362*35238bceSAndroid Build Coastguard Worker const int vecSize =
363*35238bceSAndroid Build Coastguard Worker isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) : glu::getDataTypeMatrixNumRows(basicType);
364*35238bceSAndroid Build Coastguard Worker const int vecAlign = deAlign32(getDataTypeByteAlignment(glu::getDataTypeFloatVec(vecSize)), vec4Alignment);
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker return vecAlign;
367*35238bceSAndroid Build Coastguard Worker }
368*35238bceSAndroid Build Coastguard Worker else
369*35238bceSAndroid Build Coastguard Worker return getDataTypeByteAlignment(basicType);
370*35238bceSAndroid Build Coastguard Worker }
371*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker int elemAlignment = computeStd140BaseAlignment(type.getElementType(), layoutFlags);
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker // Round up to alignment of vec4
376*35238bceSAndroid Build Coastguard Worker return deAlign32(elemAlignment, vec4Alignment);
377*35238bceSAndroid Build Coastguard Worker }
378*35238bceSAndroid Build Coastguard Worker else
379*35238bceSAndroid Build Coastguard Worker {
380*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type.isStructType());
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker int maxBaseAlignment = 0;
383*35238bceSAndroid Build Coastguard Worker
384*35238bceSAndroid Build Coastguard Worker for (StructType::ConstIterator memberIter = type.getStructPtr()->begin();
385*35238bceSAndroid Build Coastguard Worker memberIter != type.getStructPtr()->end(); memberIter++)
386*35238bceSAndroid Build Coastguard Worker maxBaseAlignment =
387*35238bceSAndroid Build Coastguard Worker de::max(maxBaseAlignment, computeStd140BaseAlignment(memberIter->getType(), layoutFlags));
388*35238bceSAndroid Build Coastguard Worker
389*35238bceSAndroid Build Coastguard Worker return deAlign32(maxBaseAlignment, vec4Alignment);
390*35238bceSAndroid Build Coastguard Worker }
391*35238bceSAndroid Build Coastguard Worker }
392*35238bceSAndroid Build Coastguard Worker
computeStd430BaseAlignment(const VarType & type,uint32_t layoutFlags)393*35238bceSAndroid Build Coastguard Worker int computeStd430BaseAlignment(const VarType &type, uint32_t layoutFlags)
394*35238bceSAndroid Build Coastguard Worker {
395*35238bceSAndroid Build Coastguard Worker // Otherwise identical to std140 except that alignment of structures and arrays
396*35238bceSAndroid Build Coastguard Worker // are not rounded up to alignment of vec4.
397*35238bceSAndroid Build Coastguard Worker
398*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
399*35238bceSAndroid Build Coastguard Worker {
400*35238bceSAndroid Build Coastguard Worker glu::DataType basicType = type.getBasicType();
401*35238bceSAndroid Build Coastguard Worker
402*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeMatrix(basicType))
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR);
405*35238bceSAndroid Build Coastguard Worker const int vecSize =
406*35238bceSAndroid Build Coastguard Worker isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) : glu::getDataTypeMatrixNumRows(basicType);
407*35238bceSAndroid Build Coastguard Worker const int vecAlign = getDataTypeByteAlignment(glu::getDataTypeFloatVec(vecSize));
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker return vecAlign;
410*35238bceSAndroid Build Coastguard Worker }
411*35238bceSAndroid Build Coastguard Worker else
412*35238bceSAndroid Build Coastguard Worker return getDataTypeByteAlignment(basicType);
413*35238bceSAndroid Build Coastguard Worker }
414*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
415*35238bceSAndroid Build Coastguard Worker {
416*35238bceSAndroid Build Coastguard Worker return computeStd430BaseAlignment(type.getElementType(), layoutFlags);
417*35238bceSAndroid Build Coastguard Worker }
418*35238bceSAndroid Build Coastguard Worker else
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type.isStructType());
421*35238bceSAndroid Build Coastguard Worker
422*35238bceSAndroid Build Coastguard Worker int maxBaseAlignment = 0;
423*35238bceSAndroid Build Coastguard Worker
424*35238bceSAndroid Build Coastguard Worker for (StructType::ConstIterator memberIter = type.getStructPtr()->begin();
425*35238bceSAndroid Build Coastguard Worker memberIter != type.getStructPtr()->end(); memberIter++)
426*35238bceSAndroid Build Coastguard Worker maxBaseAlignment =
427*35238bceSAndroid Build Coastguard Worker de::max(maxBaseAlignment, computeStd430BaseAlignment(memberIter->getType(), layoutFlags));
428*35238bceSAndroid Build Coastguard Worker
429*35238bceSAndroid Build Coastguard Worker return maxBaseAlignment;
430*35238bceSAndroid Build Coastguard Worker }
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker
mergeLayoutFlags(uint32_t prevFlags,uint32_t newFlags)433*35238bceSAndroid Build Coastguard Worker inline uint32_t mergeLayoutFlags(uint32_t prevFlags, uint32_t newFlags)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker const uint32_t packingMask = LAYOUT_PACKED | LAYOUT_SHARED | LAYOUT_STD140 | LAYOUT_STD430;
436*35238bceSAndroid Build Coastguard Worker const uint32_t matrixMask = LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR;
437*35238bceSAndroid Build Coastguard Worker
438*35238bceSAndroid Build Coastguard Worker uint32_t mergedFlags = 0;
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker mergedFlags |= ((newFlags & packingMask) ? newFlags : prevFlags) & packingMask;
441*35238bceSAndroid Build Coastguard Worker mergedFlags |= ((newFlags & matrixMask) ? newFlags : prevFlags) & matrixMask;
442*35238bceSAndroid Build Coastguard Worker
443*35238bceSAndroid Build Coastguard Worker return mergedFlags;
444*35238bceSAndroid Build Coastguard Worker }
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker //! Appends all child elements to layout, returns value that should be appended to offset.
computeReferenceLayout(BufferLayout & layout,int curBlockNdx,int baseOffset,const std::string & curPrefix,const VarType & type,uint32_t layoutFlags)447*35238bceSAndroid Build Coastguard Worker int computeReferenceLayout(BufferLayout &layout, int curBlockNdx, int baseOffset, const std::string &curPrefix,
448*35238bceSAndroid Build Coastguard Worker const VarType &type, uint32_t layoutFlags)
449*35238bceSAndroid Build Coastguard Worker {
450*35238bceSAndroid Build Coastguard Worker // Reference layout uses std430 rules by default. std140 rules are
451*35238bceSAndroid Build Coastguard Worker // choosen only for blocks that have std140 layout.
452*35238bceSAndroid Build Coastguard Worker const bool isStd140 = (layoutFlags & LAYOUT_STD140) != 0;
453*35238bceSAndroid Build Coastguard Worker const int baseAlignment =
454*35238bceSAndroid Build Coastguard Worker isStd140 ? computeStd140BaseAlignment(type, layoutFlags) : computeStd430BaseAlignment(type, layoutFlags);
455*35238bceSAndroid Build Coastguard Worker int curOffset = deAlign32(baseOffset, baseAlignment);
456*35238bceSAndroid Build Coastguard Worker const int topLevelArraySize = 1; // Default values
457*35238bceSAndroid Build Coastguard Worker const int topLevelArrayStride = 0;
458*35238bceSAndroid Build Coastguard Worker
459*35238bceSAndroid Build Coastguard Worker if (type.isBasicType())
460*35238bceSAndroid Build Coastguard Worker {
461*35238bceSAndroid Build Coastguard Worker const glu::DataType basicType = type.getBasicType();
462*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry entry;
463*35238bceSAndroid Build Coastguard Worker
464*35238bceSAndroid Build Coastguard Worker entry.name = curPrefix;
465*35238bceSAndroid Build Coastguard Worker entry.type = basicType;
466*35238bceSAndroid Build Coastguard Worker entry.arraySize = 1;
467*35238bceSAndroid Build Coastguard Worker entry.arrayStride = 0;
468*35238bceSAndroid Build Coastguard Worker entry.matrixStride = 0;
469*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = topLevelArraySize;
470*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = topLevelArrayStride;
471*35238bceSAndroid Build Coastguard Worker entry.blockNdx = curBlockNdx;
472*35238bceSAndroid Build Coastguard Worker
473*35238bceSAndroid Build Coastguard Worker if (glu::isDataTypeMatrix(basicType))
474*35238bceSAndroid Build Coastguard Worker {
475*35238bceSAndroid Build Coastguard Worker // Array of vectors as specified in rules 5 & 7.
476*35238bceSAndroid Build Coastguard Worker const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR);
477*35238bceSAndroid Build Coastguard Worker const int numVecs =
478*35238bceSAndroid Build Coastguard Worker isRowMajor ? glu::getDataTypeMatrixNumRows(basicType) : glu::getDataTypeMatrixNumColumns(basicType);
479*35238bceSAndroid Build Coastguard Worker
480*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
481*35238bceSAndroid Build Coastguard Worker entry.matrixStride = baseAlignment;
482*35238bceSAndroid Build Coastguard Worker entry.isRowMajor = isRowMajor;
483*35238bceSAndroid Build Coastguard Worker
484*35238bceSAndroid Build Coastguard Worker curOffset += numVecs * baseAlignment;
485*35238bceSAndroid Build Coastguard Worker }
486*35238bceSAndroid Build Coastguard Worker else
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker // Scalar or vector.
489*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
490*35238bceSAndroid Build Coastguard Worker
491*35238bceSAndroid Build Coastguard Worker curOffset += getDataTypeByteSize(basicType);
492*35238bceSAndroid Build Coastguard Worker }
493*35238bceSAndroid Build Coastguard Worker
494*35238bceSAndroid Build Coastguard Worker layout.bufferVars.push_back(entry);
495*35238bceSAndroid Build Coastguard Worker }
496*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker const VarType &elemType = type.getElementType();
499*35238bceSAndroid Build Coastguard Worker
500*35238bceSAndroid Build Coastguard Worker if (elemType.isBasicType() && !glu::isDataTypeMatrix(elemType.getBasicType()))
501*35238bceSAndroid Build Coastguard Worker {
502*35238bceSAndroid Build Coastguard Worker // Array of scalars or vectors.
503*35238bceSAndroid Build Coastguard Worker const glu::DataType elemBasicType = elemType.getBasicType();
504*35238bceSAndroid Build Coastguard Worker const int stride = baseAlignment;
505*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry entry;
506*35238bceSAndroid Build Coastguard Worker
507*35238bceSAndroid Build Coastguard Worker entry.name = curPrefix + "[0]"; // Array variables are always postfixed with [0]
508*35238bceSAndroid Build Coastguard Worker entry.type = elemBasicType;
509*35238bceSAndroid Build Coastguard Worker entry.blockNdx = curBlockNdx;
510*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
511*35238bceSAndroid Build Coastguard Worker entry.arraySize = type.getArraySize();
512*35238bceSAndroid Build Coastguard Worker entry.arrayStride = stride;
513*35238bceSAndroid Build Coastguard Worker entry.matrixStride = 0;
514*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = topLevelArraySize;
515*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = topLevelArrayStride;
516*35238bceSAndroid Build Coastguard Worker
517*35238bceSAndroid Build Coastguard Worker curOffset += stride * type.getArraySize();
518*35238bceSAndroid Build Coastguard Worker
519*35238bceSAndroid Build Coastguard Worker layout.bufferVars.push_back(entry);
520*35238bceSAndroid Build Coastguard Worker }
521*35238bceSAndroid Build Coastguard Worker else if (elemType.isBasicType() && glu::isDataTypeMatrix(elemType.getBasicType()))
522*35238bceSAndroid Build Coastguard Worker {
523*35238bceSAndroid Build Coastguard Worker // Array of matrices.
524*35238bceSAndroid Build Coastguard Worker const glu::DataType elemBasicType = elemType.getBasicType();
525*35238bceSAndroid Build Coastguard Worker const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR);
526*35238bceSAndroid Build Coastguard Worker const int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(elemBasicType) :
527*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumColumns(elemBasicType);
528*35238bceSAndroid Build Coastguard Worker const int vecStride = baseAlignment;
529*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry entry;
530*35238bceSAndroid Build Coastguard Worker
531*35238bceSAndroid Build Coastguard Worker entry.name = curPrefix + "[0]"; // Array variables are always postfixed with [0]
532*35238bceSAndroid Build Coastguard Worker entry.type = elemBasicType;
533*35238bceSAndroid Build Coastguard Worker entry.blockNdx = curBlockNdx;
534*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
535*35238bceSAndroid Build Coastguard Worker entry.arraySize = type.getArraySize();
536*35238bceSAndroid Build Coastguard Worker entry.arrayStride = vecStride * numVecs;
537*35238bceSAndroid Build Coastguard Worker entry.matrixStride = vecStride;
538*35238bceSAndroid Build Coastguard Worker entry.isRowMajor = isRowMajor;
539*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = topLevelArraySize;
540*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = topLevelArrayStride;
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker curOffset += numVecs * vecStride * type.getArraySize();
543*35238bceSAndroid Build Coastguard Worker
544*35238bceSAndroid Build Coastguard Worker layout.bufferVars.push_back(entry);
545*35238bceSAndroid Build Coastguard Worker }
546*35238bceSAndroid Build Coastguard Worker else
547*35238bceSAndroid Build Coastguard Worker {
548*35238bceSAndroid Build Coastguard Worker DE_ASSERT(elemType.isStructType() || elemType.isArrayType());
549*35238bceSAndroid Build Coastguard Worker
550*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < type.getArraySize(); elemNdx++)
551*35238bceSAndroid Build Coastguard Worker curOffset += computeReferenceLayout(layout, curBlockNdx, curOffset,
552*35238bceSAndroid Build Coastguard Worker curPrefix + "[" + de::toString(elemNdx) + "]",
553*35238bceSAndroid Build Coastguard Worker type.getElementType(), layoutFlags);
554*35238bceSAndroid Build Coastguard Worker }
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker else
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type.isStructType());
559*35238bceSAndroid Build Coastguard Worker
560*35238bceSAndroid Build Coastguard Worker for (StructType::ConstIterator memberIter = type.getStructPtr()->begin();
561*35238bceSAndroid Build Coastguard Worker memberIter != type.getStructPtr()->end(); memberIter++)
562*35238bceSAndroid Build Coastguard Worker curOffset += computeReferenceLayout(layout, curBlockNdx, curOffset, curPrefix + "." + memberIter->getName(),
563*35238bceSAndroid Build Coastguard Worker memberIter->getType(), layoutFlags);
564*35238bceSAndroid Build Coastguard Worker
565*35238bceSAndroid Build Coastguard Worker curOffset = deAlign32(curOffset, baseAlignment);
566*35238bceSAndroid Build Coastguard Worker }
567*35238bceSAndroid Build Coastguard Worker
568*35238bceSAndroid Build Coastguard Worker return curOffset - baseOffset;
569*35238bceSAndroid Build Coastguard Worker }
570*35238bceSAndroid Build Coastguard Worker
571*35238bceSAndroid Build Coastguard Worker //! Appends all child elements to layout, returns offset increment.
computeReferenceLayout(BufferLayout & layout,int curBlockNdx,const std::string & blockPrefix,int baseOffset,const BufferVar & bufVar,uint32_t blockLayoutFlags)572*35238bceSAndroid Build Coastguard Worker int computeReferenceLayout(BufferLayout &layout, int curBlockNdx, const std::string &blockPrefix, int baseOffset,
573*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar, uint32_t blockLayoutFlags)
574*35238bceSAndroid Build Coastguard Worker {
575*35238bceSAndroid Build Coastguard Worker const VarType &varType = bufVar.getType();
576*35238bceSAndroid Build Coastguard Worker const uint32_t combinedFlags = mergeLayoutFlags(blockLayoutFlags, bufVar.getFlags());
577*35238bceSAndroid Build Coastguard Worker
578*35238bceSAndroid Build Coastguard Worker if (varType.isArrayType())
579*35238bceSAndroid Build Coastguard Worker {
580*35238bceSAndroid Build Coastguard Worker // Top-level arrays need special care.
581*35238bceSAndroid Build Coastguard Worker const int topLevelArraySize = varType.getArraySize() == VarType::UNSIZED_ARRAY ? 0 : varType.getArraySize();
582*35238bceSAndroid Build Coastguard Worker const string prefix = blockPrefix + bufVar.getName() + "[0]";
583*35238bceSAndroid Build Coastguard Worker const bool isStd140 = (blockLayoutFlags & LAYOUT_STD140) != 0;
584*35238bceSAndroid Build Coastguard Worker const int vec4Align = (int)sizeof(uint32_t) * 4;
585*35238bceSAndroid Build Coastguard Worker const int baseAlignment = isStd140 ? computeStd140BaseAlignment(varType, combinedFlags) :
586*35238bceSAndroid Build Coastguard Worker computeStd430BaseAlignment(varType, combinedFlags);
587*35238bceSAndroid Build Coastguard Worker int curOffset = deAlign32(baseOffset, baseAlignment);
588*35238bceSAndroid Build Coastguard Worker const VarType &elemType = varType.getElementType();
589*35238bceSAndroid Build Coastguard Worker
590*35238bceSAndroid Build Coastguard Worker if (elemType.isBasicType() && !glu::isDataTypeMatrix(elemType.getBasicType()))
591*35238bceSAndroid Build Coastguard Worker {
592*35238bceSAndroid Build Coastguard Worker // Array of scalars or vectors.
593*35238bceSAndroid Build Coastguard Worker const glu::DataType elemBasicType = elemType.getBasicType();
594*35238bceSAndroid Build Coastguard Worker const int elemBaseAlign = getDataTypeByteAlignment(elemBasicType);
595*35238bceSAndroid Build Coastguard Worker const int stride = isStd140 ? deAlign32(elemBaseAlign, vec4Align) : elemBaseAlign;
596*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry entry;
597*35238bceSAndroid Build Coastguard Worker
598*35238bceSAndroid Build Coastguard Worker entry.name = prefix;
599*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = 1;
600*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = 0;
601*35238bceSAndroid Build Coastguard Worker entry.type = elemBasicType;
602*35238bceSAndroid Build Coastguard Worker entry.blockNdx = curBlockNdx;
603*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
604*35238bceSAndroid Build Coastguard Worker entry.arraySize = topLevelArraySize;
605*35238bceSAndroid Build Coastguard Worker entry.arrayStride = stride;
606*35238bceSAndroid Build Coastguard Worker entry.matrixStride = 0;
607*35238bceSAndroid Build Coastguard Worker
608*35238bceSAndroid Build Coastguard Worker layout.bufferVars.push_back(entry);
609*35238bceSAndroid Build Coastguard Worker
610*35238bceSAndroid Build Coastguard Worker curOffset += stride * topLevelArraySize;
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker else if (elemType.isBasicType() && glu::isDataTypeMatrix(elemType.getBasicType()))
613*35238bceSAndroid Build Coastguard Worker {
614*35238bceSAndroid Build Coastguard Worker // Array of matrices.
615*35238bceSAndroid Build Coastguard Worker const glu::DataType elemBasicType = elemType.getBasicType();
616*35238bceSAndroid Build Coastguard Worker const bool isRowMajor = !!(combinedFlags & LAYOUT_ROW_MAJOR);
617*35238bceSAndroid Build Coastguard Worker const int vecSize = isRowMajor ? glu::getDataTypeMatrixNumColumns(elemBasicType) :
618*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumRows(elemBasicType);
619*35238bceSAndroid Build Coastguard Worker const int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(elemBasicType) :
620*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumColumns(elemBasicType);
621*35238bceSAndroid Build Coastguard Worker const glu::DataType vecType = glu::getDataTypeFloatVec(vecSize);
622*35238bceSAndroid Build Coastguard Worker const int vecBaseAlign = getDataTypeByteAlignment(vecType);
623*35238bceSAndroid Build Coastguard Worker const int stride = isStd140 ? deAlign32(vecBaseAlign, vec4Align) : vecBaseAlign;
624*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry entry;
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker entry.name = prefix;
627*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = 1;
628*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = 0;
629*35238bceSAndroid Build Coastguard Worker entry.type = elemBasicType;
630*35238bceSAndroid Build Coastguard Worker entry.blockNdx = curBlockNdx;
631*35238bceSAndroid Build Coastguard Worker entry.offset = curOffset;
632*35238bceSAndroid Build Coastguard Worker entry.arraySize = topLevelArraySize;
633*35238bceSAndroid Build Coastguard Worker entry.arrayStride = stride * numVecs;
634*35238bceSAndroid Build Coastguard Worker entry.matrixStride = stride;
635*35238bceSAndroid Build Coastguard Worker entry.isRowMajor = isRowMajor;
636*35238bceSAndroid Build Coastguard Worker
637*35238bceSAndroid Build Coastguard Worker layout.bufferVars.push_back(entry);
638*35238bceSAndroid Build Coastguard Worker
639*35238bceSAndroid Build Coastguard Worker curOffset += stride * numVecs * topLevelArraySize;
640*35238bceSAndroid Build Coastguard Worker }
641*35238bceSAndroid Build Coastguard Worker else
642*35238bceSAndroid Build Coastguard Worker {
643*35238bceSAndroid Build Coastguard Worker DE_ASSERT(elemType.isStructType() || elemType.isArrayType());
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker // Struct base alignment is not added multiple times as curOffset supplied to computeReferenceLayout
646*35238bceSAndroid Build Coastguard Worker // was already aligned correctly. Thus computeReferenceLayout should not add any extra padding
647*35238bceSAndroid Build Coastguard Worker // before struct. Padding after struct will be added as it should.
648*35238bceSAndroid Build Coastguard Worker //
649*35238bceSAndroid Build Coastguard Worker // Stride could be computed prior to creating child elements, but it would essentially require running
650*35238bceSAndroid Build Coastguard Worker // the layout computation twice. Instead we fix stride to child elements afterwards.
651*35238bceSAndroid Build Coastguard Worker
652*35238bceSAndroid Build Coastguard Worker const int firstChildNdx = (int)layout.bufferVars.size();
653*35238bceSAndroid Build Coastguard Worker const int stride =
654*35238bceSAndroid Build Coastguard Worker computeReferenceLayout(layout, curBlockNdx, curOffset, prefix, varType.getElementType(), combinedFlags);
655*35238bceSAndroid Build Coastguard Worker
656*35238bceSAndroid Build Coastguard Worker for (int childNdx = firstChildNdx; childNdx < (int)layout.bufferVars.size(); childNdx++)
657*35238bceSAndroid Build Coastguard Worker {
658*35238bceSAndroid Build Coastguard Worker layout.bufferVars[childNdx].topLevelArraySize = topLevelArraySize;
659*35238bceSAndroid Build Coastguard Worker layout.bufferVars[childNdx].topLevelArrayStride = stride;
660*35238bceSAndroid Build Coastguard Worker }
661*35238bceSAndroid Build Coastguard Worker
662*35238bceSAndroid Build Coastguard Worker curOffset += stride * topLevelArraySize;
663*35238bceSAndroid Build Coastguard Worker }
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker return curOffset - baseOffset;
666*35238bceSAndroid Build Coastguard Worker }
667*35238bceSAndroid Build Coastguard Worker else
668*35238bceSAndroid Build Coastguard Worker return computeReferenceLayout(layout, curBlockNdx, baseOffset, blockPrefix + bufVar.getName(), varType,
669*35238bceSAndroid Build Coastguard Worker combinedFlags);
670*35238bceSAndroid Build Coastguard Worker }
671*35238bceSAndroid Build Coastguard Worker
computeReferenceLayout(BufferLayout & layout,const ShaderInterface & interface)672*35238bceSAndroid Build Coastguard Worker void computeReferenceLayout(BufferLayout &layout, const ShaderInterface &interface)
673*35238bceSAndroid Build Coastguard Worker {
674*35238bceSAndroid Build Coastguard Worker int numBlocks = interface.getNumBlocks();
675*35238bceSAndroid Build Coastguard Worker
676*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
677*35238bceSAndroid Build Coastguard Worker {
678*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(blockNdx);
679*35238bceSAndroid Build Coastguard Worker bool hasInstanceName = block.getInstanceName() != DE_NULL;
680*35238bceSAndroid Build Coastguard Worker std::string blockPrefix = hasInstanceName ? (std::string(block.getBlockName()) + ".") : std::string("");
681*35238bceSAndroid Build Coastguard Worker int curOffset = 0;
682*35238bceSAndroid Build Coastguard Worker int activeBlockNdx = (int)layout.blocks.size();
683*35238bceSAndroid Build Coastguard Worker int firstVarNdx = (int)layout.bufferVars.size();
684*35238bceSAndroid Build Coastguard Worker
685*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++)
686*35238bceSAndroid Build Coastguard Worker {
687*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar = *varIter;
688*35238bceSAndroid Build Coastguard Worker curOffset +=
689*35238bceSAndroid Build Coastguard Worker computeReferenceLayout(layout, activeBlockNdx, blockPrefix, curOffset, bufVar, block.getFlags());
690*35238bceSAndroid Build Coastguard Worker }
691*35238bceSAndroid Build Coastguard Worker
692*35238bceSAndroid Build Coastguard Worker int varIndicesEnd = (int)layout.bufferVars.size();
693*35238bceSAndroid Build Coastguard Worker int blockSize = curOffset;
694*35238bceSAndroid Build Coastguard Worker int numInstances = block.isArray() ? block.getArraySize() : 1;
695*35238bceSAndroid Build Coastguard Worker
696*35238bceSAndroid Build Coastguard Worker // Create block layout entries for each instance.
697*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
698*35238bceSAndroid Build Coastguard Worker {
699*35238bceSAndroid Build Coastguard Worker // Allocate entry for instance.
700*35238bceSAndroid Build Coastguard Worker layout.blocks.push_back(BlockLayoutEntry());
701*35238bceSAndroid Build Coastguard Worker BlockLayoutEntry &blockEntry = layout.blocks.back();
702*35238bceSAndroid Build Coastguard Worker
703*35238bceSAndroid Build Coastguard Worker blockEntry.name = block.getBlockName();
704*35238bceSAndroid Build Coastguard Worker blockEntry.size = blockSize;
705*35238bceSAndroid Build Coastguard Worker
706*35238bceSAndroid Build Coastguard Worker // Compute active variable set for block.
707*35238bceSAndroid Build Coastguard Worker for (int varNdx = firstVarNdx; varNdx < varIndicesEnd; varNdx++)
708*35238bceSAndroid Build Coastguard Worker blockEntry.activeVarIndices.push_back(varNdx);
709*35238bceSAndroid Build Coastguard Worker
710*35238bceSAndroid Build Coastguard Worker if (block.isArray())
711*35238bceSAndroid Build Coastguard Worker blockEntry.name += "[" + de::toString(instanceNdx) + "]";
712*35238bceSAndroid Build Coastguard Worker }
713*35238bceSAndroid Build Coastguard Worker }
714*35238bceSAndroid Build Coastguard Worker }
715*35238bceSAndroid Build Coastguard Worker
716*35238bceSAndroid Build Coastguard Worker // Value generator.
717*35238bceSAndroid Build Coastguard Worker
generateValue(const BufferVarLayoutEntry & entry,int unsizedArraySize,void * basePtr,de::Random & rnd)718*35238bceSAndroid Build Coastguard Worker void generateValue(const BufferVarLayoutEntry &entry, int unsizedArraySize, void *basePtr, de::Random &rnd)
719*35238bceSAndroid Build Coastguard Worker {
720*35238bceSAndroid Build Coastguard Worker const glu::DataType scalarType = glu::getDataTypeScalarType(entry.type);
721*35238bceSAndroid Build Coastguard Worker const int scalarSize = glu::getDataTypeScalarSize(entry.type);
722*35238bceSAndroid Build Coastguard Worker const int arraySize = entry.arraySize == 0 ? unsizedArraySize : entry.arraySize;
723*35238bceSAndroid Build Coastguard Worker const int arrayStride = entry.arrayStride;
724*35238bceSAndroid Build Coastguard Worker const int topLevelSize = entry.topLevelArraySize == 0 ? unsizedArraySize : entry.topLevelArraySize;
725*35238bceSAndroid Build Coastguard Worker const int topLevelStride = entry.topLevelArrayStride;
726*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(entry.type);
727*35238bceSAndroid Build Coastguard Worker const int numVecs = isMatrix ? (entry.isRowMajor ? glu::getDataTypeMatrixNumRows(entry.type) :
728*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumColumns(entry.type)) :
729*35238bceSAndroid Build Coastguard Worker 1;
730*35238bceSAndroid Build Coastguard Worker const int vecSize = scalarSize / numVecs;
731*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
732*35238bceSAndroid Build Coastguard Worker
733*35238bceSAndroid Build Coastguard Worker DE_ASSERT(scalarSize % numVecs == 0);
734*35238bceSAndroid Build Coastguard Worker DE_ASSERT(topLevelSize >= 0);
735*35238bceSAndroid Build Coastguard Worker DE_ASSERT(arraySize >= 0);
736*35238bceSAndroid Build Coastguard Worker
737*35238bceSAndroid Build Coastguard Worker for (int topElemNdx = 0; topElemNdx < topLevelSize; topElemNdx++)
738*35238bceSAndroid Build Coastguard Worker {
739*35238bceSAndroid Build Coastguard Worker uint8_t *const topElemPtr = (uint8_t *)basePtr + entry.offset + topElemNdx * topLevelStride;
740*35238bceSAndroid Build Coastguard Worker
741*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < arraySize; elemNdx++)
742*35238bceSAndroid Build Coastguard Worker {
743*35238bceSAndroid Build Coastguard Worker uint8_t *const elemPtr = topElemPtr + elemNdx * arrayStride;
744*35238bceSAndroid Build Coastguard Worker
745*35238bceSAndroid Build Coastguard Worker for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
746*35238bceSAndroid Build Coastguard Worker {
747*35238bceSAndroid Build Coastguard Worker uint8_t *const vecPtr = elemPtr + (isMatrix ? vecNdx * entry.matrixStride : 0);
748*35238bceSAndroid Build Coastguard Worker
749*35238bceSAndroid Build Coastguard Worker for (int compNdx = 0; compNdx < vecSize; compNdx++)
750*35238bceSAndroid Build Coastguard Worker {
751*35238bceSAndroid Build Coastguard Worker uint8_t *const compPtr = vecPtr + compSize * compNdx;
752*35238bceSAndroid Build Coastguard Worker
753*35238bceSAndroid Build Coastguard Worker switch (scalarType)
754*35238bceSAndroid Build Coastguard Worker {
755*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
756*35238bceSAndroid Build Coastguard Worker *((float *)compPtr) = (float)rnd.getInt(-9, 9);
757*35238bceSAndroid Build Coastguard Worker break;
758*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT:
759*35238bceSAndroid Build Coastguard Worker *((int *)compPtr) = rnd.getInt(-9, 9);
760*35238bceSAndroid Build Coastguard Worker break;
761*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT:
762*35238bceSAndroid Build Coastguard Worker *((uint32_t *)compPtr) = (uint32_t)rnd.getInt(0, 9);
763*35238bceSAndroid Build Coastguard Worker break;
764*35238bceSAndroid Build Coastguard Worker // \note Random bit pattern is used for true values. Spec states that all non-zero values are
765*35238bceSAndroid Build Coastguard Worker // interpreted as true but some implementations fail this.
766*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL:
767*35238bceSAndroid Build Coastguard Worker *((uint32_t *)compPtr) = rnd.getBool() ? rnd.getUint32() | 1u : 0u;
768*35238bceSAndroid Build Coastguard Worker break;
769*35238bceSAndroid Build Coastguard Worker default:
770*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker }
773*35238bceSAndroid Build Coastguard Worker }
774*35238bceSAndroid Build Coastguard Worker }
775*35238bceSAndroid Build Coastguard Worker }
776*35238bceSAndroid Build Coastguard Worker }
777*35238bceSAndroid Build Coastguard Worker
generateValues(const BufferLayout & layout,const vector<BlockDataPtr> & blockPointers,uint32_t seed)778*35238bceSAndroid Build Coastguard Worker void generateValues(const BufferLayout &layout, const vector<BlockDataPtr> &blockPointers, uint32_t seed)
779*35238bceSAndroid Build Coastguard Worker {
780*35238bceSAndroid Build Coastguard Worker de::Random rnd(seed);
781*35238bceSAndroid Build Coastguard Worker const int numBlocks = (int)layout.blocks.size();
782*35238bceSAndroid Build Coastguard Worker
783*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numBlocks == (int)blockPointers.size());
784*35238bceSAndroid Build Coastguard Worker
785*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
786*35238bceSAndroid Build Coastguard Worker {
787*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &blockLayout = layout.blocks[blockNdx];
788*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &blockPtr = blockPointers[blockNdx];
789*35238bceSAndroid Build Coastguard Worker const int numEntries = (int)layout.blocks[blockNdx].activeVarIndices.size();
790*35238bceSAndroid Build Coastguard Worker
791*35238bceSAndroid Build Coastguard Worker for (int entryNdx = 0; entryNdx < numEntries; entryNdx++)
792*35238bceSAndroid Build Coastguard Worker {
793*35238bceSAndroid Build Coastguard Worker const int varNdx = blockLayout.activeVarIndices[entryNdx];
794*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &varEntry = layout.bufferVars[varNdx];
795*35238bceSAndroid Build Coastguard Worker
796*35238bceSAndroid Build Coastguard Worker generateValue(varEntry, blockPtr.lastUnsizedArraySize, blockPtr.ptr, rnd);
797*35238bceSAndroid Build Coastguard Worker }
798*35238bceSAndroid Build Coastguard Worker }
799*35238bceSAndroid Build Coastguard Worker }
800*35238bceSAndroid Build Coastguard Worker
801*35238bceSAndroid Build Coastguard Worker // Shader generator.
802*35238bceSAndroid Build Coastguard Worker
getCompareFuncForType(glu::DataType type)803*35238bceSAndroid Build Coastguard Worker const char *getCompareFuncForType(glu::DataType type)
804*35238bceSAndroid Build Coastguard Worker {
805*35238bceSAndroid Build Coastguard Worker switch (type)
806*35238bceSAndroid Build Coastguard Worker {
807*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
808*35238bceSAndroid Build Coastguard Worker return "bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }\n";
809*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC2:
810*35238bceSAndroid Build Coastguard Worker return "bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, "
811*35238bceSAndroid Build Coastguard Worker "b.x)&&compare_float(a.y, b.y); }\n";
812*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC3:
813*35238bceSAndroid Build Coastguard Worker return "bool compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, "
814*35238bceSAndroid Build Coastguard Worker "b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z); }\n";
815*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC4:
816*35238bceSAndroid Build Coastguard Worker return "bool compare_vec4 (highp vec4 a, highp vec4 b) { return compare_float(a.x, "
817*35238bceSAndroid Build Coastguard Worker "b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z)&&compare_float(a.w, b.w); }\n";
818*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2:
819*35238bceSAndroid Build Coastguard Worker return "bool compare_mat2 (highp mat2 a, highp mat2 b) { return compare_vec2(a[0], "
820*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec2(a[1], b[1]); }\n";
821*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2X3:
822*35238bceSAndroid Build Coastguard Worker return "bool compare_mat2x3 (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], "
823*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec3(a[1], b[1]); }\n";
824*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2X4:
825*35238bceSAndroid Build Coastguard Worker return "bool compare_mat2x4 (highp mat2x4 a, highp mat2x4 b){ return compare_vec4(a[0], "
826*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec4(a[1], b[1]); }\n";
827*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3X2:
828*35238bceSAndroid Build Coastguard Worker return "bool compare_mat3x2 (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], "
829*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2]); }\n";
830*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3:
831*35238bceSAndroid Build Coastguard Worker return "bool compare_mat3 (highp mat3 a, highp mat3 b) { return compare_vec3(a[0], "
832*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2]); }\n";
833*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3X4:
834*35238bceSAndroid Build Coastguard Worker return "bool compare_mat3x4 (highp mat3x4 a, highp mat3x4 b){ return compare_vec4(a[0], "
835*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec4(a[1], b[1])&&compare_vec4(a[2], b[2]); }\n";
836*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4X2:
837*35238bceSAndroid Build Coastguard Worker return "bool compare_mat4x2 (highp mat4x2 a, highp mat4x2 b){ return compare_vec2(a[0], "
838*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2])&&compare_vec2(a[3], b[3]); }\n";
839*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4X3:
840*35238bceSAndroid Build Coastguard Worker return "bool compare_mat4x3 (highp mat4x3 a, highp mat4x3 b){ return compare_vec3(a[0], "
841*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2])&&compare_vec3(a[3], b[3]); }\n";
842*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4:
843*35238bceSAndroid Build Coastguard Worker return "bool compare_mat4 (highp mat4 a, highp mat4 b) { return compare_vec4(a[0], "
844*35238bceSAndroid Build Coastguard Worker "b[0])&&compare_vec4(a[1], b[1])&&compare_vec4(a[2], b[2])&&compare_vec4(a[3], b[3]); }\n";
845*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT:
846*35238bceSAndroid Build Coastguard Worker return "bool compare_int (highp int a, highp int b) { return a == b; }\n";
847*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC2:
848*35238bceSAndroid Build Coastguard Worker return "bool compare_ivec2 (highp ivec2 a, highp ivec2 b) { return a == b; }\n";
849*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC3:
850*35238bceSAndroid Build Coastguard Worker return "bool compare_ivec3 (highp ivec3 a, highp ivec3 b) { return a == b; }\n";
851*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT_VEC4:
852*35238bceSAndroid Build Coastguard Worker return "bool compare_ivec4 (highp ivec4 a, highp ivec4 b) { return a == b; }\n";
853*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT:
854*35238bceSAndroid Build Coastguard Worker return "bool compare_uint (highp uint a, highp uint b) { return a == b; }\n";
855*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC2:
856*35238bceSAndroid Build Coastguard Worker return "bool compare_uvec2 (highp uvec2 a, highp uvec2 b) { return a == b; }\n";
857*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC3:
858*35238bceSAndroid Build Coastguard Worker return "bool compare_uvec3 (highp uvec3 a, highp uvec3 b) { return a == b; }\n";
859*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT_VEC4:
860*35238bceSAndroid Build Coastguard Worker return "bool compare_uvec4 (highp uvec4 a, highp uvec4 b) { return a == b; }\n";
861*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL:
862*35238bceSAndroid Build Coastguard Worker return "bool compare_bool (bool a, bool b) { return a == b; }\n";
863*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC2:
864*35238bceSAndroid Build Coastguard Worker return "bool compare_bvec2 (bvec2 a, bvec2 b) { return a == b; }\n";
865*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC3:
866*35238bceSAndroid Build Coastguard Worker return "bool compare_bvec3 (bvec3 a, bvec3 b) { return a == b; }\n";
867*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL_VEC4:
868*35238bceSAndroid Build Coastguard Worker return "bool compare_bvec4 (bvec4 a, bvec4 b) { return a == b; }\n";
869*35238bceSAndroid Build Coastguard Worker default:
870*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
871*35238bceSAndroid Build Coastguard Worker return DE_NULL;
872*35238bceSAndroid Build Coastguard Worker }
873*35238bceSAndroid Build Coastguard Worker }
874*35238bceSAndroid Build Coastguard Worker
getCompareDependencies(std::set<glu::DataType> & compareFuncs,glu::DataType basicType)875*35238bceSAndroid Build Coastguard Worker void getCompareDependencies(std::set<glu::DataType> &compareFuncs, glu::DataType basicType)
876*35238bceSAndroid Build Coastguard Worker {
877*35238bceSAndroid Build Coastguard Worker switch (basicType)
878*35238bceSAndroid Build Coastguard Worker {
879*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC2:
880*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC3:
881*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC4:
882*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(glu::TYPE_FLOAT);
883*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(basicType);
884*35238bceSAndroid Build Coastguard Worker break;
885*35238bceSAndroid Build Coastguard Worker
886*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2:
887*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2X3:
888*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT2X4:
889*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3X2:
890*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3:
891*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT3X4:
892*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4X2:
893*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4X3:
894*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_MAT4:
895*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(glu::TYPE_FLOAT);
896*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType)));
897*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(basicType);
898*35238bceSAndroid Build Coastguard Worker break;
899*35238bceSAndroid Build Coastguard Worker
900*35238bceSAndroid Build Coastguard Worker default:
901*35238bceSAndroid Build Coastguard Worker compareFuncs.insert(basicType);
902*35238bceSAndroid Build Coastguard Worker break;
903*35238bceSAndroid Build Coastguard Worker }
904*35238bceSAndroid Build Coastguard Worker }
905*35238bceSAndroid Build Coastguard Worker
collectUniqueBasicTypes(std::set<glu::DataType> & basicTypes,const VarType & type)906*35238bceSAndroid Build Coastguard Worker void collectUniqueBasicTypes(std::set<glu::DataType> &basicTypes, const VarType &type)
907*35238bceSAndroid Build Coastguard Worker {
908*35238bceSAndroid Build Coastguard Worker if (type.isStructType())
909*35238bceSAndroid Build Coastguard Worker {
910*35238bceSAndroid Build Coastguard Worker for (StructType::ConstIterator iter = type.getStructPtr()->begin(); iter != type.getStructPtr()->end(); ++iter)
911*35238bceSAndroid Build Coastguard Worker collectUniqueBasicTypes(basicTypes, iter->getType());
912*35238bceSAndroid Build Coastguard Worker }
913*35238bceSAndroid Build Coastguard Worker else if (type.isArrayType())
914*35238bceSAndroid Build Coastguard Worker collectUniqueBasicTypes(basicTypes, type.getElementType());
915*35238bceSAndroid Build Coastguard Worker else
916*35238bceSAndroid Build Coastguard Worker {
917*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type.isBasicType());
918*35238bceSAndroid Build Coastguard Worker basicTypes.insert(type.getBasicType());
919*35238bceSAndroid Build Coastguard Worker }
920*35238bceSAndroid Build Coastguard Worker }
921*35238bceSAndroid Build Coastguard Worker
collectUniqueBasicTypes(std::set<glu::DataType> & basicTypes,const BufferBlock & bufferBlock)922*35238bceSAndroid Build Coastguard Worker void collectUniqueBasicTypes(std::set<glu::DataType> &basicTypes, const BufferBlock &bufferBlock)
923*35238bceSAndroid Build Coastguard Worker {
924*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator iter = bufferBlock.begin(); iter != bufferBlock.end(); ++iter)
925*35238bceSAndroid Build Coastguard Worker collectUniqueBasicTypes(basicTypes, iter->getType());
926*35238bceSAndroid Build Coastguard Worker }
927*35238bceSAndroid Build Coastguard Worker
collectUniqueBasicTypes(std::set<glu::DataType> & basicTypes,const ShaderInterface & interface)928*35238bceSAndroid Build Coastguard Worker void collectUniqueBasicTypes(std::set<glu::DataType> &basicTypes, const ShaderInterface &interface)
929*35238bceSAndroid Build Coastguard Worker {
930*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < interface.getNumBlocks(); ++ndx)
931*35238bceSAndroid Build Coastguard Worker collectUniqueBasicTypes(basicTypes, interface.getBlock(ndx));
932*35238bceSAndroid Build Coastguard Worker }
933*35238bceSAndroid Build Coastguard Worker
generateCompareFuncs(std::ostream & str,const ShaderInterface & interface)934*35238bceSAndroid Build Coastguard Worker void generateCompareFuncs(std::ostream &str, const ShaderInterface &interface)
935*35238bceSAndroid Build Coastguard Worker {
936*35238bceSAndroid Build Coastguard Worker std::set<glu::DataType> types;
937*35238bceSAndroid Build Coastguard Worker std::set<glu::DataType> compareFuncs;
938*35238bceSAndroid Build Coastguard Worker
939*35238bceSAndroid Build Coastguard Worker // Collect unique basic types
940*35238bceSAndroid Build Coastguard Worker collectUniqueBasicTypes(types, interface);
941*35238bceSAndroid Build Coastguard Worker
942*35238bceSAndroid Build Coastguard Worker // Set of compare functions required
943*35238bceSAndroid Build Coastguard Worker for (std::set<glu::DataType>::const_iterator iter = types.begin(); iter != types.end(); ++iter)
944*35238bceSAndroid Build Coastguard Worker {
945*35238bceSAndroid Build Coastguard Worker getCompareDependencies(compareFuncs, *iter);
946*35238bceSAndroid Build Coastguard Worker }
947*35238bceSAndroid Build Coastguard Worker
948*35238bceSAndroid Build Coastguard Worker for (int type = 0; type < glu::TYPE_LAST; ++type)
949*35238bceSAndroid Build Coastguard Worker {
950*35238bceSAndroid Build Coastguard Worker if (compareFuncs.find(glu::DataType(type)) != compareFuncs.end())
951*35238bceSAndroid Build Coastguard Worker str << getCompareFuncForType(glu::DataType(type));
952*35238bceSAndroid Build Coastguard Worker }
953*35238bceSAndroid Build Coastguard Worker }
954*35238bceSAndroid Build Coastguard Worker
955*35238bceSAndroid Build Coastguard Worker struct Indent
956*35238bceSAndroid Build Coastguard Worker {
957*35238bceSAndroid Build Coastguard Worker int level;
Indentdeqp::gles31::bb::__anonc1049a2c0211::Indent958*35238bceSAndroid Build Coastguard Worker Indent(int level_) : level(level_)
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker }
961*35238bceSAndroid Build Coastguard Worker };
962*35238bceSAndroid Build Coastguard Worker
operator <<(std::ostream & str,const Indent & indent)963*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &str, const Indent &indent)
964*35238bceSAndroid Build Coastguard Worker {
965*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < indent.level; i++)
966*35238bceSAndroid Build Coastguard Worker str << "\t";
967*35238bceSAndroid Build Coastguard Worker return str;
968*35238bceSAndroid Build Coastguard Worker }
969*35238bceSAndroid Build Coastguard Worker
generateDeclaration(std::ostream & src,const BufferVar & bufferVar,int indentLevel)970*35238bceSAndroid Build Coastguard Worker void generateDeclaration(std::ostream &src, const BufferVar &bufferVar, int indentLevel)
971*35238bceSAndroid Build Coastguard Worker {
972*35238bceSAndroid Build Coastguard Worker // \todo [pyry] Qualifiers
973*35238bceSAndroid Build Coastguard Worker
974*35238bceSAndroid Build Coastguard Worker if ((bufferVar.getFlags() & LAYOUT_MASK) != 0)
975*35238bceSAndroid Build Coastguard Worker src << "layout(" << LayoutFlagsFmt(bufferVar.getFlags() & LAYOUT_MASK) << ") ";
976*35238bceSAndroid Build Coastguard Worker
977*35238bceSAndroid Build Coastguard Worker src << glu::declare(bufferVar.getType(), bufferVar.getName(), indentLevel);
978*35238bceSAndroid Build Coastguard Worker }
979*35238bceSAndroid Build Coastguard Worker
generateDeclaration(std::ostream & src,const BufferBlock & block,int bindingPoint)980*35238bceSAndroid Build Coastguard Worker void generateDeclaration(std::ostream &src, const BufferBlock &block, int bindingPoint)
981*35238bceSAndroid Build Coastguard Worker {
982*35238bceSAndroid Build Coastguard Worker src << "layout(";
983*35238bceSAndroid Build Coastguard Worker
984*35238bceSAndroid Build Coastguard Worker if ((block.getFlags() & LAYOUT_MASK) != 0)
985*35238bceSAndroid Build Coastguard Worker src << LayoutFlagsFmt(block.getFlags() & LAYOUT_MASK) << ", ";
986*35238bceSAndroid Build Coastguard Worker
987*35238bceSAndroid Build Coastguard Worker src << "binding = " << bindingPoint;
988*35238bceSAndroid Build Coastguard Worker
989*35238bceSAndroid Build Coastguard Worker src << ") ";
990*35238bceSAndroid Build Coastguard Worker
991*35238bceSAndroid Build Coastguard Worker src << "buffer " << block.getBlockName();
992*35238bceSAndroid Build Coastguard Worker src << "\n{\n";
993*35238bceSAndroid Build Coastguard Worker
994*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++)
995*35238bceSAndroid Build Coastguard Worker {
996*35238bceSAndroid Build Coastguard Worker src << Indent(1);
997*35238bceSAndroid Build Coastguard Worker generateDeclaration(src, *varIter, 1 /* indent level */);
998*35238bceSAndroid Build Coastguard Worker src << ";\n";
999*35238bceSAndroid Build Coastguard Worker }
1000*35238bceSAndroid Build Coastguard Worker
1001*35238bceSAndroid Build Coastguard Worker src << "}";
1002*35238bceSAndroid Build Coastguard Worker
1003*35238bceSAndroid Build Coastguard Worker if (block.getInstanceName() != DE_NULL)
1004*35238bceSAndroid Build Coastguard Worker {
1005*35238bceSAndroid Build Coastguard Worker src << " " << block.getInstanceName();
1006*35238bceSAndroid Build Coastguard Worker if (block.isArray())
1007*35238bceSAndroid Build Coastguard Worker src << "[" << block.getArraySize() << "]";
1008*35238bceSAndroid Build Coastguard Worker }
1009*35238bceSAndroid Build Coastguard Worker else
1010*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!block.isArray());
1011*35238bceSAndroid Build Coastguard Worker
1012*35238bceSAndroid Build Coastguard Worker src << ";\n";
1013*35238bceSAndroid Build Coastguard Worker }
1014*35238bceSAndroid Build Coastguard Worker
generateImmMatrixSrc(std::ostream & src,glu::DataType basicType,int matrixStride,bool isRowMajor,const void * valuePtr)1015*35238bceSAndroid Build Coastguard Worker void generateImmMatrixSrc(std::ostream &src, glu::DataType basicType, int matrixStride, bool isRowMajor,
1016*35238bceSAndroid Build Coastguard Worker const void *valuePtr)
1017*35238bceSAndroid Build Coastguard Worker {
1018*35238bceSAndroid Build Coastguard Worker DE_ASSERT(glu::isDataTypeMatrix(basicType));
1019*35238bceSAndroid Build Coastguard Worker
1020*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
1021*35238bceSAndroid Build Coastguard Worker const int numRows = glu::getDataTypeMatrixNumRows(basicType);
1022*35238bceSAndroid Build Coastguard Worker const int numCols = glu::getDataTypeMatrixNumColumns(basicType);
1023*35238bceSAndroid Build Coastguard Worker
1024*35238bceSAndroid Build Coastguard Worker src << glu::getDataTypeName(basicType) << "(";
1025*35238bceSAndroid Build Coastguard Worker
1026*35238bceSAndroid Build Coastguard Worker // Constructed in column-wise order.
1027*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < numCols; colNdx++)
1028*35238bceSAndroid Build Coastguard Worker {
1029*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
1030*35238bceSAndroid Build Coastguard Worker {
1031*35238bceSAndroid Build Coastguard Worker const uint8_t *compPtr =
1032*35238bceSAndroid Build Coastguard Worker (const uint8_t *)valuePtr +
1033*35238bceSAndroid Build Coastguard Worker (isRowMajor ? rowNdx * matrixStride + colNdx * compSize : colNdx * matrixStride + rowNdx * compSize);
1034*35238bceSAndroid Build Coastguard Worker
1035*35238bceSAndroid Build Coastguard Worker if (colNdx > 0 || rowNdx > 0)
1036*35238bceSAndroid Build Coastguard Worker src << ", ";
1037*35238bceSAndroid Build Coastguard Worker
1038*35238bceSAndroid Build Coastguard Worker src << de::floatToString(*((const float *)compPtr), 1);
1039*35238bceSAndroid Build Coastguard Worker }
1040*35238bceSAndroid Build Coastguard Worker }
1041*35238bceSAndroid Build Coastguard Worker
1042*35238bceSAndroid Build Coastguard Worker src << ")";
1043*35238bceSAndroid Build Coastguard Worker }
1044*35238bceSAndroid Build Coastguard Worker
generateImmScalarVectorSrc(std::ostream & src,glu::DataType basicType,const void * valuePtr)1045*35238bceSAndroid Build Coastguard Worker void generateImmScalarVectorSrc(std::ostream &src, glu::DataType basicType, const void *valuePtr)
1046*35238bceSAndroid Build Coastguard Worker {
1047*35238bceSAndroid Build Coastguard Worker DE_ASSERT(glu::isDataTypeFloatOrVec(basicType) || glu::isDataTypeIntOrIVec(basicType) ||
1048*35238bceSAndroid Build Coastguard Worker glu::isDataTypeUintOrUVec(basicType) || glu::isDataTypeBoolOrBVec(basicType));
1049*35238bceSAndroid Build Coastguard Worker
1050*35238bceSAndroid Build Coastguard Worker const glu::DataType scalarType = glu::getDataTypeScalarType(basicType);
1051*35238bceSAndroid Build Coastguard Worker const int scalarSize = glu::getDataTypeScalarSize(basicType);
1052*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker if (scalarSize > 1)
1055*35238bceSAndroid Build Coastguard Worker src << glu::getDataTypeName(basicType) << "(";
1056*35238bceSAndroid Build Coastguard Worker
1057*35238bceSAndroid Build Coastguard Worker for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
1058*35238bceSAndroid Build Coastguard Worker {
1059*35238bceSAndroid Build Coastguard Worker const uint8_t *compPtr = (const uint8_t *)valuePtr + scalarNdx * compSize;
1060*35238bceSAndroid Build Coastguard Worker
1061*35238bceSAndroid Build Coastguard Worker if (scalarNdx > 0)
1062*35238bceSAndroid Build Coastguard Worker src << ", ";
1063*35238bceSAndroid Build Coastguard Worker
1064*35238bceSAndroid Build Coastguard Worker switch (scalarType)
1065*35238bceSAndroid Build Coastguard Worker {
1066*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
1067*35238bceSAndroid Build Coastguard Worker src << de::floatToString(*((const float *)compPtr), 1);
1068*35238bceSAndroid Build Coastguard Worker break;
1069*35238bceSAndroid Build Coastguard Worker case glu::TYPE_INT:
1070*35238bceSAndroid Build Coastguard Worker src << *((const int *)compPtr);
1071*35238bceSAndroid Build Coastguard Worker break;
1072*35238bceSAndroid Build Coastguard Worker case glu::TYPE_UINT:
1073*35238bceSAndroid Build Coastguard Worker src << *((const uint32_t *)compPtr) << "u";
1074*35238bceSAndroid Build Coastguard Worker break;
1075*35238bceSAndroid Build Coastguard Worker case glu::TYPE_BOOL:
1076*35238bceSAndroid Build Coastguard Worker src << (*((const uint32_t *)compPtr) != 0u ? "true" : "false");
1077*35238bceSAndroid Build Coastguard Worker break;
1078*35238bceSAndroid Build Coastguard Worker default:
1079*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1080*35238bceSAndroid Build Coastguard Worker }
1081*35238bceSAndroid Build Coastguard Worker }
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker if (scalarSize > 1)
1084*35238bceSAndroid Build Coastguard Worker src << ")";
1085*35238bceSAndroid Build Coastguard Worker }
1086*35238bceSAndroid Build Coastguard Worker
getAPIName(const BufferBlock & block,const BufferVar & var,const glu::TypeComponentVector & accessPath)1087*35238bceSAndroid Build Coastguard Worker string getAPIName(const BufferBlock &block, const BufferVar &var, const glu::TypeComponentVector &accessPath)
1088*35238bceSAndroid Build Coastguard Worker {
1089*35238bceSAndroid Build Coastguard Worker std::ostringstream name;
1090*35238bceSAndroid Build Coastguard Worker
1091*35238bceSAndroid Build Coastguard Worker if (block.getInstanceName())
1092*35238bceSAndroid Build Coastguard Worker name << block.getBlockName() << ".";
1093*35238bceSAndroid Build Coastguard Worker
1094*35238bceSAndroid Build Coastguard Worker name << var.getName();
1095*35238bceSAndroid Build Coastguard Worker
1096*35238bceSAndroid Build Coastguard Worker for (glu::TypeComponentVector::const_iterator pathComp = accessPath.begin(); pathComp != accessPath.end();
1097*35238bceSAndroid Build Coastguard Worker pathComp++)
1098*35238bceSAndroid Build Coastguard Worker {
1099*35238bceSAndroid Build Coastguard Worker if (pathComp->type == glu::VarTypeComponent::STRUCT_MEMBER)
1100*35238bceSAndroid Build Coastguard Worker {
1101*35238bceSAndroid Build Coastguard Worker const VarType curType = glu::getVarType(var.getType(), accessPath.begin(), pathComp);
1102*35238bceSAndroid Build Coastguard Worker const StructType *structPtr = curType.getStructPtr();
1103*35238bceSAndroid Build Coastguard Worker
1104*35238bceSAndroid Build Coastguard Worker name << "." << structPtr->getMember(pathComp->index).getName();
1105*35238bceSAndroid Build Coastguard Worker }
1106*35238bceSAndroid Build Coastguard Worker else if (pathComp->type == glu::VarTypeComponent::ARRAY_ELEMENT)
1107*35238bceSAndroid Build Coastguard Worker {
1108*35238bceSAndroid Build Coastguard Worker if (pathComp == accessPath.begin() || (pathComp + 1) == accessPath.end())
1109*35238bceSAndroid Build Coastguard Worker name << "[0]"; // Top- / bottom-level array
1110*35238bceSAndroid Build Coastguard Worker else
1111*35238bceSAndroid Build Coastguard Worker name << "[" << pathComp->index << "]";
1112*35238bceSAndroid Build Coastguard Worker }
1113*35238bceSAndroid Build Coastguard Worker else
1114*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1115*35238bceSAndroid Build Coastguard Worker }
1116*35238bceSAndroid Build Coastguard Worker
1117*35238bceSAndroid Build Coastguard Worker return name.str();
1118*35238bceSAndroid Build Coastguard Worker }
1119*35238bceSAndroid Build Coastguard Worker
getShaderName(const BufferBlock & block,int instanceNdx,const BufferVar & var,const glu::TypeComponentVector & accessPath)1120*35238bceSAndroid Build Coastguard Worker string getShaderName(const BufferBlock &block, int instanceNdx, const BufferVar &var,
1121*35238bceSAndroid Build Coastguard Worker const glu::TypeComponentVector &accessPath)
1122*35238bceSAndroid Build Coastguard Worker {
1123*35238bceSAndroid Build Coastguard Worker std::ostringstream name;
1124*35238bceSAndroid Build Coastguard Worker
1125*35238bceSAndroid Build Coastguard Worker if (block.getInstanceName())
1126*35238bceSAndroid Build Coastguard Worker {
1127*35238bceSAndroid Build Coastguard Worker name << block.getInstanceName();
1128*35238bceSAndroid Build Coastguard Worker
1129*35238bceSAndroid Build Coastguard Worker if (block.isArray())
1130*35238bceSAndroid Build Coastguard Worker name << "[" << instanceNdx << "]";
1131*35238bceSAndroid Build Coastguard Worker
1132*35238bceSAndroid Build Coastguard Worker name << ".";
1133*35238bceSAndroid Build Coastguard Worker }
1134*35238bceSAndroid Build Coastguard Worker else
1135*35238bceSAndroid Build Coastguard Worker DE_ASSERT(instanceNdx == 0);
1136*35238bceSAndroid Build Coastguard Worker
1137*35238bceSAndroid Build Coastguard Worker name << var.getName();
1138*35238bceSAndroid Build Coastguard Worker
1139*35238bceSAndroid Build Coastguard Worker for (glu::TypeComponentVector::const_iterator pathComp = accessPath.begin(); pathComp != accessPath.end();
1140*35238bceSAndroid Build Coastguard Worker pathComp++)
1141*35238bceSAndroid Build Coastguard Worker {
1142*35238bceSAndroid Build Coastguard Worker if (pathComp->type == glu::VarTypeComponent::STRUCT_MEMBER)
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker const VarType curType = glu::getVarType(var.getType(), accessPath.begin(), pathComp);
1145*35238bceSAndroid Build Coastguard Worker const StructType *structPtr = curType.getStructPtr();
1146*35238bceSAndroid Build Coastguard Worker
1147*35238bceSAndroid Build Coastguard Worker name << "." << structPtr->getMember(pathComp->index).getName();
1148*35238bceSAndroid Build Coastguard Worker }
1149*35238bceSAndroid Build Coastguard Worker else if (pathComp->type == glu::VarTypeComponent::ARRAY_ELEMENT)
1150*35238bceSAndroid Build Coastguard Worker name << "[" << pathComp->index << "]";
1151*35238bceSAndroid Build Coastguard Worker else
1152*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1153*35238bceSAndroid Build Coastguard Worker }
1154*35238bceSAndroid Build Coastguard Worker
1155*35238bceSAndroid Build Coastguard Worker return name.str();
1156*35238bceSAndroid Build Coastguard Worker }
1157*35238bceSAndroid Build Coastguard Worker
computeOffset(const BufferVarLayoutEntry & varLayout,const glu::TypeComponentVector & accessPath)1158*35238bceSAndroid Build Coastguard Worker int computeOffset(const BufferVarLayoutEntry &varLayout, const glu::TypeComponentVector &accessPath)
1159*35238bceSAndroid Build Coastguard Worker {
1160*35238bceSAndroid Build Coastguard Worker const int topLevelNdx = (accessPath.size() > 1 && accessPath.front().type == glu::VarTypeComponent::ARRAY_ELEMENT) ?
1161*35238bceSAndroid Build Coastguard Worker accessPath.front().index :
1162*35238bceSAndroid Build Coastguard Worker 0;
1163*35238bceSAndroid Build Coastguard Worker const int bottomLevelNdx = (!accessPath.empty() && accessPath.back().type == glu::VarTypeComponent::ARRAY_ELEMENT) ?
1164*35238bceSAndroid Build Coastguard Worker accessPath.back().index :
1165*35238bceSAndroid Build Coastguard Worker 0;
1166*35238bceSAndroid Build Coastguard Worker
1167*35238bceSAndroid Build Coastguard Worker return varLayout.offset + varLayout.topLevelArrayStride * topLevelNdx + varLayout.arrayStride * bottomLevelNdx;
1168*35238bceSAndroid Build Coastguard Worker }
1169*35238bceSAndroid Build Coastguard Worker
generateCompareSrc(std::ostream & src,const char * resultVar,const BufferLayout & bufferLayout,const BufferBlock & block,int instanceNdx,const BlockDataPtr & blockPtr,const BufferVar & bufVar,const glu::SubTypeAccess & accessPath)1170*35238bceSAndroid Build Coastguard Worker void generateCompareSrc(std::ostream &src, const char *resultVar, const BufferLayout &bufferLayout,
1171*35238bceSAndroid Build Coastguard Worker const BufferBlock &block, int instanceNdx, const BlockDataPtr &blockPtr,
1172*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar, const glu::SubTypeAccess &accessPath)
1173*35238bceSAndroid Build Coastguard Worker {
1174*35238bceSAndroid Build Coastguard Worker const VarType curType = accessPath.getType();
1175*35238bceSAndroid Build Coastguard Worker
1176*35238bceSAndroid Build Coastguard Worker if (curType.isArrayType())
1177*35238bceSAndroid Build Coastguard Worker {
1178*35238bceSAndroid Build Coastguard Worker const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ?
1179*35238bceSAndroid Build Coastguard Worker block.getLastUnsizedArraySize(instanceNdx) :
1180*35238bceSAndroid Build Coastguard Worker curType.getArraySize();
1181*35238bceSAndroid Build Coastguard Worker
1182*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < arraySize; elemNdx++)
1183*35238bceSAndroid Build Coastguard Worker generateCompareSrc(src, resultVar, bufferLayout, block, instanceNdx, blockPtr, bufVar,
1184*35238bceSAndroid Build Coastguard Worker accessPath.element(elemNdx));
1185*35238bceSAndroid Build Coastguard Worker }
1186*35238bceSAndroid Build Coastguard Worker else if (curType.isStructType())
1187*35238bceSAndroid Build Coastguard Worker {
1188*35238bceSAndroid Build Coastguard Worker const int numMembers = curType.getStructPtr()->getNumMembers();
1189*35238bceSAndroid Build Coastguard Worker
1190*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < numMembers; memberNdx++)
1191*35238bceSAndroid Build Coastguard Worker generateCompareSrc(src, resultVar, bufferLayout, block, instanceNdx, blockPtr, bufVar,
1192*35238bceSAndroid Build Coastguard Worker accessPath.member(memberNdx));
1193*35238bceSAndroid Build Coastguard Worker }
1194*35238bceSAndroid Build Coastguard Worker else
1195*35238bceSAndroid Build Coastguard Worker {
1196*35238bceSAndroid Build Coastguard Worker DE_ASSERT(curType.isBasicType());
1197*35238bceSAndroid Build Coastguard Worker
1198*35238bceSAndroid Build Coastguard Worker const string apiName = getAPIName(block, bufVar, accessPath.getPath());
1199*35238bceSAndroid Build Coastguard Worker const int varNdx = bufferLayout.getVariableIndex(apiName);
1200*35238bceSAndroid Build Coastguard Worker
1201*35238bceSAndroid Build Coastguard Worker DE_ASSERT(varNdx >= 0);
1202*35238bceSAndroid Build Coastguard Worker {
1203*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &varLayout = bufferLayout.bufferVars[varNdx];
1204*35238bceSAndroid Build Coastguard Worker const string shaderName = getShaderName(block, instanceNdx, bufVar, accessPath.getPath());
1205*35238bceSAndroid Build Coastguard Worker const glu::DataType basicType = curType.getBasicType();
1206*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(basicType);
1207*35238bceSAndroid Build Coastguard Worker const char *typeName = glu::getDataTypeName(basicType);
1208*35238bceSAndroid Build Coastguard Worker const void *valuePtr = (const uint8_t *)blockPtr.ptr + computeOffset(varLayout, accessPath.getPath());
1209*35238bceSAndroid Build Coastguard Worker
1210*35238bceSAndroid Build Coastguard Worker src << "\t" << resultVar << " = " << resultVar << " && compare_" << typeName << "(" << shaderName << ", ";
1211*35238bceSAndroid Build Coastguard Worker
1212*35238bceSAndroid Build Coastguard Worker if (isMatrix)
1213*35238bceSAndroid Build Coastguard Worker generateImmMatrixSrc(src, basicType, varLayout.matrixStride, varLayout.isRowMajor, valuePtr);
1214*35238bceSAndroid Build Coastguard Worker else
1215*35238bceSAndroid Build Coastguard Worker generateImmScalarVectorSrc(src, basicType, valuePtr);
1216*35238bceSAndroid Build Coastguard Worker
1217*35238bceSAndroid Build Coastguard Worker src << ");\n";
1218*35238bceSAndroid Build Coastguard Worker }
1219*35238bceSAndroid Build Coastguard Worker }
1220*35238bceSAndroid Build Coastguard Worker }
1221*35238bceSAndroid Build Coastguard Worker
generateCompareSrc(std::ostream & src,const char * resultVar,const ShaderInterface & interface,const BufferLayout & layout,const vector<BlockDataPtr> & blockPointers)1222*35238bceSAndroid Build Coastguard Worker void generateCompareSrc(std::ostream &src, const char *resultVar, const ShaderInterface &interface,
1223*35238bceSAndroid Build Coastguard Worker const BufferLayout &layout, const vector<BlockDataPtr> &blockPointers)
1224*35238bceSAndroid Build Coastguard Worker {
1225*35238bceSAndroid Build Coastguard Worker for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++)
1226*35238bceSAndroid Build Coastguard Worker {
1227*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(declNdx);
1228*35238bceSAndroid Build Coastguard Worker const bool isArray = block.isArray();
1229*35238bceSAndroid Build Coastguard Worker const int numInstances = isArray ? block.getArraySize() : 1;
1230*35238bceSAndroid Build Coastguard Worker
1231*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!isArray || block.getInstanceName());
1232*35238bceSAndroid Build Coastguard Worker
1233*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
1234*35238bceSAndroid Build Coastguard Worker {
1235*35238bceSAndroid Build Coastguard Worker const string instanceName =
1236*35238bceSAndroid Build Coastguard Worker block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string(""));
1237*35238bceSAndroid Build Coastguard Worker const int blockNdx = layout.getBlockIndex(instanceName);
1238*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &blockPtr = blockPointers[blockNdx];
1239*35238bceSAndroid Build Coastguard Worker
1240*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++)
1241*35238bceSAndroid Build Coastguard Worker {
1242*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar = *varIter;
1243*35238bceSAndroid Build Coastguard Worker
1244*35238bceSAndroid Build Coastguard Worker if ((bufVar.getFlags() & ACCESS_READ) == 0)
1245*35238bceSAndroid Build Coastguard Worker continue; // Don't read from that variable.
1246*35238bceSAndroid Build Coastguard Worker
1247*35238bceSAndroid Build Coastguard Worker generateCompareSrc(src, resultVar, layout, block, instanceNdx, blockPtr, bufVar,
1248*35238bceSAndroid Build Coastguard Worker glu::SubTypeAccess(bufVar.getType()));
1249*35238bceSAndroid Build Coastguard Worker }
1250*35238bceSAndroid Build Coastguard Worker }
1251*35238bceSAndroid Build Coastguard Worker }
1252*35238bceSAndroid Build Coastguard Worker }
1253*35238bceSAndroid Build Coastguard Worker
1254*35238bceSAndroid Build Coastguard Worker // \todo [2013-10-14 pyry] Almost identical to generateCompareSrc - unify?
1255*35238bceSAndroid Build Coastguard Worker
generateWriteSrc(std::ostream & src,const BufferLayout & bufferLayout,const BufferBlock & block,int instanceNdx,const BlockDataPtr & blockPtr,const BufferVar & bufVar,const glu::SubTypeAccess & accessPath)1256*35238bceSAndroid Build Coastguard Worker void generateWriteSrc(std::ostream &src, const BufferLayout &bufferLayout, const BufferBlock &block, int instanceNdx,
1257*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &blockPtr, const BufferVar &bufVar, const glu::SubTypeAccess &accessPath)
1258*35238bceSAndroid Build Coastguard Worker {
1259*35238bceSAndroid Build Coastguard Worker const VarType curType = accessPath.getType();
1260*35238bceSAndroid Build Coastguard Worker
1261*35238bceSAndroid Build Coastguard Worker if (curType.isArrayType())
1262*35238bceSAndroid Build Coastguard Worker {
1263*35238bceSAndroid Build Coastguard Worker const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ?
1264*35238bceSAndroid Build Coastguard Worker block.getLastUnsizedArraySize(instanceNdx) :
1265*35238bceSAndroid Build Coastguard Worker curType.getArraySize();
1266*35238bceSAndroid Build Coastguard Worker
1267*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < arraySize; elemNdx++)
1268*35238bceSAndroid Build Coastguard Worker generateWriteSrc(src, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.element(elemNdx));
1269*35238bceSAndroid Build Coastguard Worker }
1270*35238bceSAndroid Build Coastguard Worker else if (curType.isStructType())
1271*35238bceSAndroid Build Coastguard Worker {
1272*35238bceSAndroid Build Coastguard Worker const int numMembers = curType.getStructPtr()->getNumMembers();
1273*35238bceSAndroid Build Coastguard Worker
1274*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < numMembers; memberNdx++)
1275*35238bceSAndroid Build Coastguard Worker generateWriteSrc(src, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.member(memberNdx));
1276*35238bceSAndroid Build Coastguard Worker }
1277*35238bceSAndroid Build Coastguard Worker else
1278*35238bceSAndroid Build Coastguard Worker {
1279*35238bceSAndroid Build Coastguard Worker DE_ASSERT(curType.isBasicType());
1280*35238bceSAndroid Build Coastguard Worker
1281*35238bceSAndroid Build Coastguard Worker const string apiName = getAPIName(block, bufVar, accessPath.getPath());
1282*35238bceSAndroid Build Coastguard Worker const int varNdx = bufferLayout.getVariableIndex(apiName);
1283*35238bceSAndroid Build Coastguard Worker
1284*35238bceSAndroid Build Coastguard Worker DE_ASSERT(varNdx >= 0);
1285*35238bceSAndroid Build Coastguard Worker {
1286*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &varLayout = bufferLayout.bufferVars[varNdx];
1287*35238bceSAndroid Build Coastguard Worker const string shaderName = getShaderName(block, instanceNdx, bufVar, accessPath.getPath());
1288*35238bceSAndroid Build Coastguard Worker const glu::DataType basicType = curType.getBasicType();
1289*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(basicType);
1290*35238bceSAndroid Build Coastguard Worker const void *valuePtr = (const uint8_t *)blockPtr.ptr + computeOffset(varLayout, accessPath.getPath());
1291*35238bceSAndroid Build Coastguard Worker
1292*35238bceSAndroid Build Coastguard Worker src << "\t" << shaderName << " = ";
1293*35238bceSAndroid Build Coastguard Worker
1294*35238bceSAndroid Build Coastguard Worker if (isMatrix)
1295*35238bceSAndroid Build Coastguard Worker generateImmMatrixSrc(src, basicType, varLayout.matrixStride, varLayout.isRowMajor, valuePtr);
1296*35238bceSAndroid Build Coastguard Worker else
1297*35238bceSAndroid Build Coastguard Worker generateImmScalarVectorSrc(src, basicType, valuePtr);
1298*35238bceSAndroid Build Coastguard Worker
1299*35238bceSAndroid Build Coastguard Worker src << ";\n";
1300*35238bceSAndroid Build Coastguard Worker }
1301*35238bceSAndroid Build Coastguard Worker }
1302*35238bceSAndroid Build Coastguard Worker }
1303*35238bceSAndroid Build Coastguard Worker
generateWriteSrc(std::ostream & src,const ShaderInterface & interface,const BufferLayout & layout,const vector<BlockDataPtr> & blockPointers)1304*35238bceSAndroid Build Coastguard Worker void generateWriteSrc(std::ostream &src, const ShaderInterface &interface, const BufferLayout &layout,
1305*35238bceSAndroid Build Coastguard Worker const vector<BlockDataPtr> &blockPointers)
1306*35238bceSAndroid Build Coastguard Worker {
1307*35238bceSAndroid Build Coastguard Worker for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++)
1308*35238bceSAndroid Build Coastguard Worker {
1309*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(declNdx);
1310*35238bceSAndroid Build Coastguard Worker const bool isArray = block.isArray();
1311*35238bceSAndroid Build Coastguard Worker const int numInstances = isArray ? block.getArraySize() : 1;
1312*35238bceSAndroid Build Coastguard Worker
1313*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!isArray || block.getInstanceName());
1314*35238bceSAndroid Build Coastguard Worker
1315*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
1316*35238bceSAndroid Build Coastguard Worker {
1317*35238bceSAndroid Build Coastguard Worker const string instanceName =
1318*35238bceSAndroid Build Coastguard Worker block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string(""));
1319*35238bceSAndroid Build Coastguard Worker const int blockNdx = layout.getBlockIndex(instanceName);
1320*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &blockPtr = blockPointers[blockNdx];
1321*35238bceSAndroid Build Coastguard Worker
1322*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++)
1323*35238bceSAndroid Build Coastguard Worker {
1324*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar = *varIter;
1325*35238bceSAndroid Build Coastguard Worker
1326*35238bceSAndroid Build Coastguard Worker if ((bufVar.getFlags() & ACCESS_WRITE) == 0)
1327*35238bceSAndroid Build Coastguard Worker continue; // Don't write to that variable.
1328*35238bceSAndroid Build Coastguard Worker
1329*35238bceSAndroid Build Coastguard Worker generateWriteSrc(src, layout, block, instanceNdx, blockPtr, bufVar,
1330*35238bceSAndroid Build Coastguard Worker glu::SubTypeAccess(bufVar.getType()));
1331*35238bceSAndroid Build Coastguard Worker }
1332*35238bceSAndroid Build Coastguard Worker }
1333*35238bceSAndroid Build Coastguard Worker }
1334*35238bceSAndroid Build Coastguard Worker }
1335*35238bceSAndroid Build Coastguard Worker
generateComputeShader(const glw::Functions & gl,glu::GLSLVersion glslVersion,const ShaderInterface & interface,const BufferLayout & layout,const vector<BlockDataPtr> & comparePtrs,const vector<BlockDataPtr> & writePtrs)1336*35238bceSAndroid Build Coastguard Worker string generateComputeShader(const glw::Functions &gl, glu::GLSLVersion glslVersion, const ShaderInterface &interface,
1337*35238bceSAndroid Build Coastguard Worker const BufferLayout &layout, const vector<BlockDataPtr> &comparePtrs,
1338*35238bceSAndroid Build Coastguard Worker const vector<BlockDataPtr> &writePtrs)
1339*35238bceSAndroid Build Coastguard Worker {
1340*35238bceSAndroid Build Coastguard Worker std::ostringstream src;
1341*35238bceSAndroid Build Coastguard Worker glw::GLint maxShaderStorageBufferBindings;
1342*35238bceSAndroid Build Coastguard Worker glw::GLint maxComputeShaderStorageBlocks;
1343*35238bceSAndroid Build Coastguard Worker
1344*35238bceSAndroid Build Coastguard Worker DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion == glu::GLSL_VERSION_430);
1345*35238bceSAndroid Build Coastguard Worker
1346*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
1347*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &maxComputeShaderStorageBlocks);
1348*35238bceSAndroid Build Coastguard Worker
1349*35238bceSAndroid Build Coastguard Worker src << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
1350*35238bceSAndroid Build Coastguard Worker src << "layout(local_size_x = 1) in;\n";
1351*35238bceSAndroid Build Coastguard Worker src << "\n";
1352*35238bceSAndroid Build Coastguard Worker
1353*35238bceSAndroid Build Coastguard Worker std::vector<const StructType *> namedStructs;
1354*35238bceSAndroid Build Coastguard Worker interface.getNamedStructs(namedStructs);
1355*35238bceSAndroid Build Coastguard Worker for (std::vector<const StructType *>::const_iterator structIter = namedStructs.begin();
1356*35238bceSAndroid Build Coastguard Worker structIter != namedStructs.end(); structIter++)
1357*35238bceSAndroid Build Coastguard Worker src << glu::declare(*structIter) << ";\n";
1358*35238bceSAndroid Build Coastguard Worker
1359*35238bceSAndroid Build Coastguard Worker {
1360*35238bceSAndroid Build Coastguard Worker int bindingPoint = 0;
1361*35238bceSAndroid Build Coastguard Worker
1362*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < interface.getNumBlocks(); blockNdx++)
1363*35238bceSAndroid Build Coastguard Worker {
1364*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(blockNdx);
1365*35238bceSAndroid Build Coastguard Worker generateDeclaration(src, block, bindingPoint);
1366*35238bceSAndroid Build Coastguard Worker
1367*35238bceSAndroid Build Coastguard Worker bindingPoint += block.isArray() ? block.getArraySize() : 1;
1368*35238bceSAndroid Build Coastguard Worker }
1369*35238bceSAndroid Build Coastguard Worker
1370*35238bceSAndroid Build Coastguard Worker if (bindingPoint > maxShaderStorageBufferBindings)
1371*35238bceSAndroid Build Coastguard Worker {
1372*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires support for more SSBO bindings than implementation exposes");
1373*35238bceSAndroid Build Coastguard Worker }
1374*35238bceSAndroid Build Coastguard Worker if (bindingPoint > maxComputeShaderStorageBlocks)
1375*35238bceSAndroid Build Coastguard Worker {
1376*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError(
1377*35238bceSAndroid Build Coastguard Worker "Test requires support for more compute shader storage blocks than implementation exposes");
1378*35238bceSAndroid Build Coastguard Worker }
1379*35238bceSAndroid Build Coastguard Worker }
1380*35238bceSAndroid Build Coastguard Worker
1381*35238bceSAndroid Build Coastguard Worker // Atomic counter for counting passed invocations.
1382*35238bceSAndroid Build Coastguard Worker src << "\nlayout(binding = 0) uniform atomic_uint ac_numPassed;\n";
1383*35238bceSAndroid Build Coastguard Worker
1384*35238bceSAndroid Build Coastguard Worker // Comparison utilities.
1385*35238bceSAndroid Build Coastguard Worker src << "\n";
1386*35238bceSAndroid Build Coastguard Worker generateCompareFuncs(src, interface);
1387*35238bceSAndroid Build Coastguard Worker
1388*35238bceSAndroid Build Coastguard Worker src << "\n"
1389*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1390*35238bceSAndroid Build Coastguard Worker "{\n"
1391*35238bceSAndroid Build Coastguard Worker " bool allOk = true;\n";
1392*35238bceSAndroid Build Coastguard Worker
1393*35238bceSAndroid Build Coastguard Worker // Value compare.
1394*35238bceSAndroid Build Coastguard Worker generateCompareSrc(src, "allOk", interface, layout, comparePtrs);
1395*35238bceSAndroid Build Coastguard Worker
1396*35238bceSAndroid Build Coastguard Worker src << " if (allOk)\n"
1397*35238bceSAndroid Build Coastguard Worker << " atomicCounterIncrement(ac_numPassed);\n"
1398*35238bceSAndroid Build Coastguard Worker << "\n";
1399*35238bceSAndroid Build Coastguard Worker
1400*35238bceSAndroid Build Coastguard Worker // Value write.
1401*35238bceSAndroid Build Coastguard Worker generateWriteSrc(src, interface, layout, writePtrs);
1402*35238bceSAndroid Build Coastguard Worker
1403*35238bceSAndroid Build Coastguard Worker src << "}\n";
1404*35238bceSAndroid Build Coastguard Worker
1405*35238bceSAndroid Build Coastguard Worker return src.str();
1406*35238bceSAndroid Build Coastguard Worker }
1407*35238bceSAndroid Build Coastguard Worker
getGLBufferLayout(const glw::Functions & gl,BufferLayout & layout,uint32_t program)1408*35238bceSAndroid Build Coastguard Worker void getGLBufferLayout(const glw::Functions &gl, BufferLayout &layout, uint32_t program)
1409*35238bceSAndroid Build Coastguard Worker {
1410*35238bceSAndroid Build Coastguard Worker int numActiveBufferVars = 0;
1411*35238bceSAndroid Build Coastguard Worker int numActiveBlocks = 0;
1412*35238bceSAndroid Build Coastguard Worker
1413*35238bceSAndroid Build Coastguard Worker gl.getProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &numActiveBufferVars);
1414*35238bceSAndroid Build Coastguard Worker gl.getProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveBlocks);
1415*35238bceSAndroid Build Coastguard Worker
1416*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get number of buffer variables and buffer blocks");
1417*35238bceSAndroid Build Coastguard Worker
1418*35238bceSAndroid Build Coastguard Worker // Block entries.
1419*35238bceSAndroid Build Coastguard Worker layout.blocks.resize(numActiveBlocks);
1420*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numActiveBlocks; blockNdx++)
1421*35238bceSAndroid Build Coastguard Worker {
1422*35238bceSAndroid Build Coastguard Worker BlockLayoutEntry &entry = layout.blocks[blockNdx];
1423*35238bceSAndroid Build Coastguard Worker const uint32_t queryParams[] = {GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_NAME_LENGTH};
1424*35238bceSAndroid Build Coastguard Worker int returnValues[] = {0, 0, 0};
1425*35238bceSAndroid Build Coastguard Worker
1426*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(queryParams) == DE_LENGTH_OF_ARRAY(returnValues));
1427*35238bceSAndroid Build Coastguard Worker
1428*35238bceSAndroid Build Coastguard Worker {
1429*35238bceSAndroid Build Coastguard Worker int returnLength = 0;
1430*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, (uint32_t)blockNdx,
1431*35238bceSAndroid Build Coastguard Worker DE_LENGTH_OF_ARRAY(queryParams), &queryParams[0], DE_LENGTH_OF_ARRAY(returnValues),
1432*35238bceSAndroid Build Coastguard Worker &returnLength, &returnValues[0]);
1433*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK) failed");
1434*35238bceSAndroid Build Coastguard Worker
1435*35238bceSAndroid Build Coastguard Worker if (returnLength != DE_LENGTH_OF_ARRAY(returnValues))
1436*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK) returned wrong number of values");
1437*35238bceSAndroid Build Coastguard Worker }
1438*35238bceSAndroid Build Coastguard Worker
1439*35238bceSAndroid Build Coastguard Worker entry.size = returnValues[0];
1440*35238bceSAndroid Build Coastguard Worker
1441*35238bceSAndroid Build Coastguard Worker // Query active variables
1442*35238bceSAndroid Build Coastguard Worker if (returnValues[1] > 0)
1443*35238bceSAndroid Build Coastguard Worker {
1444*35238bceSAndroid Build Coastguard Worker const int numBlockVars = returnValues[1];
1445*35238bceSAndroid Build Coastguard Worker const uint32_t queryArg = GL_ACTIVE_VARIABLES;
1446*35238bceSAndroid Build Coastguard Worker int retLength = 0;
1447*35238bceSAndroid Build Coastguard Worker
1448*35238bceSAndroid Build Coastguard Worker entry.activeVarIndices.resize(numBlockVars);
1449*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, (uint32_t)blockNdx, 1, &queryArg, numBlockVars,
1450*35238bceSAndroid Build Coastguard Worker &retLength, &entry.activeVarIndices[0]);
1451*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(),
1452*35238bceSAndroid Build Coastguard Worker "glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_VARIABLES) failed");
1453*35238bceSAndroid Build Coastguard Worker
1454*35238bceSAndroid Build Coastguard Worker if (retLength != numBlockVars)
1455*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_VARIABLES) returned "
1456*35238bceSAndroid Build Coastguard Worker "wrong number of values");
1457*35238bceSAndroid Build Coastguard Worker }
1458*35238bceSAndroid Build Coastguard Worker
1459*35238bceSAndroid Build Coastguard Worker // Query name
1460*35238bceSAndroid Build Coastguard Worker if (returnValues[2] > 0)
1461*35238bceSAndroid Build Coastguard Worker {
1462*35238bceSAndroid Build Coastguard Worker const int nameLen = returnValues[2];
1463*35238bceSAndroid Build Coastguard Worker int retLen = 0;
1464*35238bceSAndroid Build Coastguard Worker vector<char> name(nameLen);
1465*35238bceSAndroid Build Coastguard Worker
1466*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, (uint32_t)blockNdx, (glw::GLsizei)name.size(),
1467*35238bceSAndroid Build Coastguard Worker &retLen, &name[0]);
1468*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) failed");
1469*35238bceSAndroid Build Coastguard Worker
1470*35238bceSAndroid Build Coastguard Worker if (retLen + 1 != nameLen)
1471*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) returned invalid name. Number "
1472*35238bceSAndroid Build Coastguard Worker "of characters written is inconsistent with NAME_LENGTH property.");
1473*35238bceSAndroid Build Coastguard Worker if (name[nameLen - 1] != 0)
1474*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) returned invalid name. "
1475*35238bceSAndroid Build Coastguard Worker "Expected null terminator at index " +
1476*35238bceSAndroid Build Coastguard Worker de::toString(nameLen - 1));
1477*35238bceSAndroid Build Coastguard Worker
1478*35238bceSAndroid Build Coastguard Worker entry.name = &name[0];
1479*35238bceSAndroid Build Coastguard Worker }
1480*35238bceSAndroid Build Coastguard Worker else
1481*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceiv() returned invalid GL_NAME_LENGTH");
1482*35238bceSAndroid Build Coastguard Worker }
1483*35238bceSAndroid Build Coastguard Worker
1484*35238bceSAndroid Build Coastguard Worker layout.bufferVars.resize(numActiveBufferVars);
1485*35238bceSAndroid Build Coastguard Worker for (int bufVarNdx = 0; bufVarNdx < numActiveBufferVars; bufVarNdx++)
1486*35238bceSAndroid Build Coastguard Worker {
1487*35238bceSAndroid Build Coastguard Worker BufferVarLayoutEntry &entry = layout.bufferVars[bufVarNdx];
1488*35238bceSAndroid Build Coastguard Worker const uint32_t queryParams[] = {
1489*35238bceSAndroid Build Coastguard Worker GL_BLOCK_INDEX, // 0
1490*35238bceSAndroid Build Coastguard Worker GL_TYPE, // 1
1491*35238bceSAndroid Build Coastguard Worker GL_OFFSET, // 2
1492*35238bceSAndroid Build Coastguard Worker GL_ARRAY_SIZE, // 3
1493*35238bceSAndroid Build Coastguard Worker GL_ARRAY_STRIDE, // 4
1494*35238bceSAndroid Build Coastguard Worker GL_MATRIX_STRIDE, // 5
1495*35238bceSAndroid Build Coastguard Worker GL_TOP_LEVEL_ARRAY_SIZE, // 6
1496*35238bceSAndroid Build Coastguard Worker GL_TOP_LEVEL_ARRAY_STRIDE, // 7
1497*35238bceSAndroid Build Coastguard Worker GL_IS_ROW_MAJOR, // 8
1498*35238bceSAndroid Build Coastguard Worker GL_NAME_LENGTH // 9
1499*35238bceSAndroid Build Coastguard Worker };
1500*35238bceSAndroid Build Coastguard Worker int returnValues[DE_LENGTH_OF_ARRAY(queryParams)];
1501*35238bceSAndroid Build Coastguard Worker
1502*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(queryParams) == DE_LENGTH_OF_ARRAY(returnValues));
1503*35238bceSAndroid Build Coastguard Worker
1504*35238bceSAndroid Build Coastguard Worker {
1505*35238bceSAndroid Build Coastguard Worker int returnLength = 0;
1506*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceiv(program, GL_BUFFER_VARIABLE, (uint32_t)bufVarNdx, DE_LENGTH_OF_ARRAY(queryParams),
1507*35238bceSAndroid Build Coastguard Worker &queryParams[0], DE_LENGTH_OF_ARRAY(returnValues), &returnLength, &returnValues[0]);
1508*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv(GL_BUFFER_VARIABLE) failed");
1509*35238bceSAndroid Build Coastguard Worker
1510*35238bceSAndroid Build Coastguard Worker if (returnLength != DE_LENGTH_OF_ARRAY(returnValues))
1511*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceiv(GL_BUFFER_VARIABLE) returned wrong number of values");
1512*35238bceSAndroid Build Coastguard Worker }
1513*35238bceSAndroid Build Coastguard Worker
1514*35238bceSAndroid Build Coastguard Worker // Map values
1515*35238bceSAndroid Build Coastguard Worker entry.blockNdx = returnValues[0];
1516*35238bceSAndroid Build Coastguard Worker entry.type = glu::getDataTypeFromGLType(returnValues[1]);
1517*35238bceSAndroid Build Coastguard Worker entry.offset = returnValues[2];
1518*35238bceSAndroid Build Coastguard Worker entry.arraySize = returnValues[3];
1519*35238bceSAndroid Build Coastguard Worker entry.arrayStride = returnValues[4];
1520*35238bceSAndroid Build Coastguard Worker entry.matrixStride = returnValues[5];
1521*35238bceSAndroid Build Coastguard Worker entry.topLevelArraySize = returnValues[6];
1522*35238bceSAndroid Build Coastguard Worker entry.topLevelArrayStride = returnValues[7];
1523*35238bceSAndroid Build Coastguard Worker entry.isRowMajor = returnValues[8] != 0;
1524*35238bceSAndroid Build Coastguard Worker
1525*35238bceSAndroid Build Coastguard Worker // Query name
1526*35238bceSAndroid Build Coastguard Worker DE_ASSERT(queryParams[9] == GL_NAME_LENGTH);
1527*35238bceSAndroid Build Coastguard Worker if (returnValues[9] > 0)
1528*35238bceSAndroid Build Coastguard Worker {
1529*35238bceSAndroid Build Coastguard Worker const int nameLen = returnValues[9];
1530*35238bceSAndroid Build Coastguard Worker int retLen = 0;
1531*35238bceSAndroid Build Coastguard Worker vector<char> name(nameLen);
1532*35238bceSAndroid Build Coastguard Worker
1533*35238bceSAndroid Build Coastguard Worker gl.getProgramResourceName(program, GL_BUFFER_VARIABLE, (uint32_t)bufVarNdx, (glw::GLsizei)name.size(),
1534*35238bceSAndroid Build Coastguard Worker &retLen, &name[0]);
1535*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName(GL_BUFFER_VARIABLE) failed");
1536*35238bceSAndroid Build Coastguard Worker
1537*35238bceSAndroid Build Coastguard Worker if (retLen + 1 != nameLen)
1538*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceName(GL_BUFFER_VARIABLE) returned invalid name. Number of "
1539*35238bceSAndroid Build Coastguard Worker "characters written is inconsistent with NAME_LENGTH property.");
1540*35238bceSAndroid Build Coastguard Worker if (name[nameLen - 1] != 0)
1541*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceName(GL_BUFFER_VARIABLE) returned invalid name. Expected "
1542*35238bceSAndroid Build Coastguard Worker "null terminator at index " +
1543*35238bceSAndroid Build Coastguard Worker de::toString(nameLen - 1));
1544*35238bceSAndroid Build Coastguard Worker
1545*35238bceSAndroid Build Coastguard Worker entry.name = &name[0];
1546*35238bceSAndroid Build Coastguard Worker }
1547*35238bceSAndroid Build Coastguard Worker else
1548*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("glGetProgramResourceiv() returned invalid GL_NAME_LENGTH");
1549*35238bceSAndroid Build Coastguard Worker }
1550*35238bceSAndroid Build Coastguard Worker }
1551*35238bceSAndroid Build Coastguard Worker
copyBufferVarData(const BufferVarLayoutEntry & dstEntry,const BlockDataPtr & dstBlockPtr,const BufferVarLayoutEntry & srcEntry,const BlockDataPtr & srcBlockPtr)1552*35238bceSAndroid Build Coastguard Worker void copyBufferVarData(const BufferVarLayoutEntry &dstEntry, const BlockDataPtr &dstBlockPtr,
1553*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &srcEntry, const BlockDataPtr &srcBlockPtr)
1554*35238bceSAndroid Build Coastguard Worker {
1555*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstEntry.arraySize <= srcEntry.arraySize);
1556*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstEntry.topLevelArraySize <= srcEntry.topLevelArraySize);
1557*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstBlockPtr.lastUnsizedArraySize <= srcBlockPtr.lastUnsizedArraySize);
1558*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstEntry.type == srcEntry.type);
1559*35238bceSAndroid Build Coastguard Worker
1560*35238bceSAndroid Build Coastguard Worker uint8_t *const dstBasePtr = (uint8_t *)dstBlockPtr.ptr + dstEntry.offset;
1561*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcBasePtr = (const uint8_t *)srcBlockPtr.ptr + srcEntry.offset;
1562*35238bceSAndroid Build Coastguard Worker const int scalarSize = glu::getDataTypeScalarSize(dstEntry.type);
1563*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(dstEntry.type);
1564*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
1565*35238bceSAndroid Build Coastguard Worker const int dstArraySize = dstEntry.arraySize == 0 ? dstBlockPtr.lastUnsizedArraySize : dstEntry.arraySize;
1566*35238bceSAndroid Build Coastguard Worker const int dstArrayStride = dstEntry.arrayStride;
1567*35238bceSAndroid Build Coastguard Worker const int dstTopLevelSize =
1568*35238bceSAndroid Build Coastguard Worker dstEntry.topLevelArraySize == 0 ? dstBlockPtr.lastUnsizedArraySize : dstEntry.topLevelArraySize;
1569*35238bceSAndroid Build Coastguard Worker const int dstTopLevelStride = dstEntry.topLevelArrayStride;
1570*35238bceSAndroid Build Coastguard Worker const int srcArraySize = srcEntry.arraySize == 0 ? srcBlockPtr.lastUnsizedArraySize : srcEntry.arraySize;
1571*35238bceSAndroid Build Coastguard Worker const int srcArrayStride = srcEntry.arrayStride;
1572*35238bceSAndroid Build Coastguard Worker const int srcTopLevelSize =
1573*35238bceSAndroid Build Coastguard Worker srcEntry.topLevelArraySize == 0 ? srcBlockPtr.lastUnsizedArraySize : srcEntry.topLevelArraySize;
1574*35238bceSAndroid Build Coastguard Worker const int srcTopLevelStride = srcEntry.topLevelArrayStride;
1575*35238bceSAndroid Build Coastguard Worker
1576*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstArraySize <= srcArraySize && dstTopLevelSize <= srcTopLevelSize);
1577*35238bceSAndroid Build Coastguard Worker DE_UNREF(srcArraySize && srcTopLevelSize);
1578*35238bceSAndroid Build Coastguard Worker
1579*35238bceSAndroid Build Coastguard Worker for (int topElemNdx = 0; topElemNdx < dstTopLevelSize; topElemNdx++)
1580*35238bceSAndroid Build Coastguard Worker {
1581*35238bceSAndroid Build Coastguard Worker uint8_t *const dstTopPtr = dstBasePtr + topElemNdx * dstTopLevelStride;
1582*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcTopPtr = srcBasePtr + topElemNdx * srcTopLevelStride;
1583*35238bceSAndroid Build Coastguard Worker
1584*35238bceSAndroid Build Coastguard Worker for (int elementNdx = 0; elementNdx < dstArraySize; elementNdx++)
1585*35238bceSAndroid Build Coastguard Worker {
1586*35238bceSAndroid Build Coastguard Worker uint8_t *const dstElemPtr = dstTopPtr + elementNdx * dstArrayStride;
1587*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcElemPtr = srcTopPtr + elementNdx * srcArrayStride;
1588*35238bceSAndroid Build Coastguard Worker
1589*35238bceSAndroid Build Coastguard Worker if (isMatrix)
1590*35238bceSAndroid Build Coastguard Worker {
1591*35238bceSAndroid Build Coastguard Worker const int numRows = glu::getDataTypeMatrixNumRows(dstEntry.type);
1592*35238bceSAndroid Build Coastguard Worker const int numCols = glu::getDataTypeMatrixNumColumns(dstEntry.type);
1593*35238bceSAndroid Build Coastguard Worker
1594*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < numCols; colNdx++)
1595*35238bceSAndroid Build Coastguard Worker {
1596*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
1597*35238bceSAndroid Build Coastguard Worker {
1598*35238bceSAndroid Build Coastguard Worker uint8_t *dstCompPtr =
1599*35238bceSAndroid Build Coastguard Worker dstElemPtr + (dstEntry.isRowMajor ? rowNdx * dstEntry.matrixStride + colNdx * compSize :
1600*35238bceSAndroid Build Coastguard Worker colNdx * dstEntry.matrixStride + rowNdx * compSize);
1601*35238bceSAndroid Build Coastguard Worker const uint8_t *srcCompPtr =
1602*35238bceSAndroid Build Coastguard Worker srcElemPtr + (srcEntry.isRowMajor ? rowNdx * srcEntry.matrixStride + colNdx * compSize :
1603*35238bceSAndroid Build Coastguard Worker colNdx * srcEntry.matrixStride + rowNdx * compSize);
1604*35238bceSAndroid Build Coastguard Worker
1605*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(srcCompPtr + compSize) - (intptr_t)srcBlockPtr.ptr <=
1606*35238bceSAndroid Build Coastguard Worker (intptr_t)srcBlockPtr.size);
1607*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(dstCompPtr + compSize) - (intptr_t)dstBlockPtr.ptr <=
1608*35238bceSAndroid Build Coastguard Worker (intptr_t)dstBlockPtr.size);
1609*35238bceSAndroid Build Coastguard Worker deMemcpy(dstCompPtr, srcCompPtr, compSize);
1610*35238bceSAndroid Build Coastguard Worker }
1611*35238bceSAndroid Build Coastguard Worker }
1612*35238bceSAndroid Build Coastguard Worker }
1613*35238bceSAndroid Build Coastguard Worker else
1614*35238bceSAndroid Build Coastguard Worker {
1615*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(srcElemPtr + scalarSize * compSize) - (intptr_t)srcBlockPtr.ptr <=
1616*35238bceSAndroid Build Coastguard Worker (intptr_t)srcBlockPtr.size);
1617*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(dstElemPtr + scalarSize * compSize) - (intptr_t)dstBlockPtr.ptr <=
1618*35238bceSAndroid Build Coastguard Worker (intptr_t)dstBlockPtr.size);
1619*35238bceSAndroid Build Coastguard Worker deMemcpy(dstElemPtr, srcElemPtr, scalarSize * compSize);
1620*35238bceSAndroid Build Coastguard Worker }
1621*35238bceSAndroid Build Coastguard Worker }
1622*35238bceSAndroid Build Coastguard Worker }
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker
copyData(const BufferLayout & dstLayout,const vector<BlockDataPtr> & dstBlockPointers,const BufferLayout & srcLayout,const vector<BlockDataPtr> & srcBlockPointers)1625*35238bceSAndroid Build Coastguard Worker void copyData(const BufferLayout &dstLayout, const vector<BlockDataPtr> &dstBlockPointers,
1626*35238bceSAndroid Build Coastguard Worker const BufferLayout &srcLayout, const vector<BlockDataPtr> &srcBlockPointers)
1627*35238bceSAndroid Build Coastguard Worker {
1628*35238bceSAndroid Build Coastguard Worker // \note Src layout is used as reference in case of activeVarIndices happens to be incorrect in dstLayout blocks.
1629*35238bceSAndroid Build Coastguard Worker int numBlocks = (int)srcLayout.blocks.size();
1630*35238bceSAndroid Build Coastguard Worker
1631*35238bceSAndroid Build Coastguard Worker for (int srcBlockNdx = 0; srcBlockNdx < numBlocks; srcBlockNdx++)
1632*35238bceSAndroid Build Coastguard Worker {
1633*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &srcBlock = srcLayout.blocks[srcBlockNdx];
1634*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &srcBlockPtr = srcBlockPointers[srcBlockNdx];
1635*35238bceSAndroid Build Coastguard Worker int dstBlockNdx = dstLayout.getBlockIndex(srcBlock.name.c_str());
1636*35238bceSAndroid Build Coastguard Worker
1637*35238bceSAndroid Build Coastguard Worker if (dstBlockNdx >= 0)
1638*35238bceSAndroid Build Coastguard Worker {
1639*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(dstBlockNdx, 0, (int)dstBlockPointers.size()));
1640*35238bceSAndroid Build Coastguard Worker
1641*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &dstBlockPtr = dstBlockPointers[dstBlockNdx];
1642*35238bceSAndroid Build Coastguard Worker
1643*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator srcVarNdxIter = srcBlock.activeVarIndices.begin();
1644*35238bceSAndroid Build Coastguard Worker srcVarNdxIter != srcBlock.activeVarIndices.end(); srcVarNdxIter++)
1645*35238bceSAndroid Build Coastguard Worker {
1646*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &srcEntry = srcLayout.bufferVars[*srcVarNdxIter];
1647*35238bceSAndroid Build Coastguard Worker int dstVarNdx = dstLayout.getVariableIndex(srcEntry.name.c_str());
1648*35238bceSAndroid Build Coastguard Worker
1649*35238bceSAndroid Build Coastguard Worker if (dstVarNdx >= 0)
1650*35238bceSAndroid Build Coastguard Worker copyBufferVarData(dstLayout.bufferVars[dstVarNdx], dstBlockPtr, srcEntry, srcBlockPtr);
1651*35238bceSAndroid Build Coastguard Worker }
1652*35238bceSAndroid Build Coastguard Worker }
1653*35238bceSAndroid Build Coastguard Worker }
1654*35238bceSAndroid Build Coastguard Worker }
1655*35238bceSAndroid Build Coastguard Worker
copyNonWrittenData(const BufferLayout & layout,const BufferBlock & block,int instanceNdx,const BlockDataPtr & srcBlockPtr,const BlockDataPtr & dstBlockPtr,const BufferVar & bufVar,const glu::SubTypeAccess & accessPath)1656*35238bceSAndroid Build Coastguard Worker void copyNonWrittenData(const BufferLayout &layout, const BufferBlock &block, int instanceNdx,
1657*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &srcBlockPtr, const BlockDataPtr &dstBlockPtr, const BufferVar &bufVar,
1658*35238bceSAndroid Build Coastguard Worker const glu::SubTypeAccess &accessPath)
1659*35238bceSAndroid Build Coastguard Worker {
1660*35238bceSAndroid Build Coastguard Worker const VarType curType = accessPath.getType();
1661*35238bceSAndroid Build Coastguard Worker
1662*35238bceSAndroid Build Coastguard Worker if (curType.isArrayType())
1663*35238bceSAndroid Build Coastguard Worker {
1664*35238bceSAndroid Build Coastguard Worker const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ?
1665*35238bceSAndroid Build Coastguard Worker block.getLastUnsizedArraySize(instanceNdx) :
1666*35238bceSAndroid Build Coastguard Worker curType.getArraySize();
1667*35238bceSAndroid Build Coastguard Worker
1668*35238bceSAndroid Build Coastguard Worker for (int elemNdx = 0; elemNdx < arraySize; elemNdx++)
1669*35238bceSAndroid Build Coastguard Worker copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar,
1670*35238bceSAndroid Build Coastguard Worker accessPath.element(elemNdx));
1671*35238bceSAndroid Build Coastguard Worker }
1672*35238bceSAndroid Build Coastguard Worker else if (curType.isStructType())
1673*35238bceSAndroid Build Coastguard Worker {
1674*35238bceSAndroid Build Coastguard Worker const int numMembers = curType.getStructPtr()->getNumMembers();
1675*35238bceSAndroid Build Coastguard Worker
1676*35238bceSAndroid Build Coastguard Worker for (int memberNdx = 0; memberNdx < numMembers; memberNdx++)
1677*35238bceSAndroid Build Coastguard Worker copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar,
1678*35238bceSAndroid Build Coastguard Worker accessPath.member(memberNdx));
1679*35238bceSAndroid Build Coastguard Worker }
1680*35238bceSAndroid Build Coastguard Worker else
1681*35238bceSAndroid Build Coastguard Worker {
1682*35238bceSAndroid Build Coastguard Worker DE_ASSERT(curType.isBasicType());
1683*35238bceSAndroid Build Coastguard Worker
1684*35238bceSAndroid Build Coastguard Worker const string apiName = getAPIName(block, bufVar, accessPath.getPath());
1685*35238bceSAndroid Build Coastguard Worker const int varNdx = layout.getVariableIndex(apiName);
1686*35238bceSAndroid Build Coastguard Worker
1687*35238bceSAndroid Build Coastguard Worker DE_ASSERT(varNdx >= 0);
1688*35238bceSAndroid Build Coastguard Worker {
1689*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &varLayout = layout.bufferVars[varNdx];
1690*35238bceSAndroid Build Coastguard Worker copyBufferVarData(varLayout, dstBlockPtr, varLayout, srcBlockPtr);
1691*35238bceSAndroid Build Coastguard Worker }
1692*35238bceSAndroid Build Coastguard Worker }
1693*35238bceSAndroid Build Coastguard Worker }
1694*35238bceSAndroid Build Coastguard Worker
copyNonWrittenData(const ShaderInterface & interface,const BufferLayout & layout,const vector<BlockDataPtr> & srcPtrs,const vector<BlockDataPtr> & dstPtrs)1695*35238bceSAndroid Build Coastguard Worker void copyNonWrittenData(const ShaderInterface &interface, const BufferLayout &layout,
1696*35238bceSAndroid Build Coastguard Worker const vector<BlockDataPtr> &srcPtrs, const vector<BlockDataPtr> &dstPtrs)
1697*35238bceSAndroid Build Coastguard Worker {
1698*35238bceSAndroid Build Coastguard Worker for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++)
1699*35238bceSAndroid Build Coastguard Worker {
1700*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(declNdx);
1701*35238bceSAndroid Build Coastguard Worker const bool isArray = block.isArray();
1702*35238bceSAndroid Build Coastguard Worker const int numInstances = isArray ? block.getArraySize() : 1;
1703*35238bceSAndroid Build Coastguard Worker
1704*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!isArray || block.getInstanceName());
1705*35238bceSAndroid Build Coastguard Worker
1706*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
1707*35238bceSAndroid Build Coastguard Worker {
1708*35238bceSAndroid Build Coastguard Worker const string instanceName =
1709*35238bceSAndroid Build Coastguard Worker block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string(""));
1710*35238bceSAndroid Build Coastguard Worker const int blockNdx = layout.getBlockIndex(instanceName);
1711*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &srcBlockPtr = srcPtrs[blockNdx];
1712*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &dstBlockPtr = dstPtrs[blockNdx];
1713*35238bceSAndroid Build Coastguard Worker
1714*35238bceSAndroid Build Coastguard Worker for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++)
1715*35238bceSAndroid Build Coastguard Worker {
1716*35238bceSAndroid Build Coastguard Worker const BufferVar &bufVar = *varIter;
1717*35238bceSAndroid Build Coastguard Worker
1718*35238bceSAndroid Build Coastguard Worker if (bufVar.getFlags() & ACCESS_WRITE)
1719*35238bceSAndroid Build Coastguard Worker continue;
1720*35238bceSAndroid Build Coastguard Worker
1721*35238bceSAndroid Build Coastguard Worker copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar,
1722*35238bceSAndroid Build Coastguard Worker glu::SubTypeAccess(bufVar.getType()));
1723*35238bceSAndroid Build Coastguard Worker }
1724*35238bceSAndroid Build Coastguard Worker }
1725*35238bceSAndroid Build Coastguard Worker }
1726*35238bceSAndroid Build Coastguard Worker }
1727*35238bceSAndroid Build Coastguard Worker
compareComponents(glu::DataType scalarType,const void * ref,const void * res,int numComps)1728*35238bceSAndroid Build Coastguard Worker bool compareComponents(glu::DataType scalarType, const void *ref, const void *res, int numComps)
1729*35238bceSAndroid Build Coastguard Worker {
1730*35238bceSAndroid Build Coastguard Worker if (scalarType == glu::TYPE_FLOAT)
1731*35238bceSAndroid Build Coastguard Worker {
1732*35238bceSAndroid Build Coastguard Worker const float threshold = 0.05f; // Same as used in shaders - should be fine for values being used.
1733*35238bceSAndroid Build Coastguard Worker
1734*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numComps; ndx++)
1735*35238bceSAndroid Build Coastguard Worker {
1736*35238bceSAndroid Build Coastguard Worker const float refVal = *((const float *)ref + ndx);
1737*35238bceSAndroid Build Coastguard Worker const float resVal = *((const float *)res + ndx);
1738*35238bceSAndroid Build Coastguard Worker
1739*35238bceSAndroid Build Coastguard Worker if (!(deFloatAbs(resVal - refVal) <= threshold))
1740*35238bceSAndroid Build Coastguard Worker return false;
1741*35238bceSAndroid Build Coastguard Worker }
1742*35238bceSAndroid Build Coastguard Worker }
1743*35238bceSAndroid Build Coastguard Worker else if (scalarType == glu::TYPE_BOOL)
1744*35238bceSAndroid Build Coastguard Worker {
1745*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numComps; ndx++)
1746*35238bceSAndroid Build Coastguard Worker {
1747*35238bceSAndroid Build Coastguard Worker const uint32_t refVal = *((const uint32_t *)ref + ndx);
1748*35238bceSAndroid Build Coastguard Worker const uint32_t resVal = *((const uint32_t *)res + ndx);
1749*35238bceSAndroid Build Coastguard Worker
1750*35238bceSAndroid Build Coastguard Worker if ((refVal != 0) != (resVal != 0))
1751*35238bceSAndroid Build Coastguard Worker return false;
1752*35238bceSAndroid Build Coastguard Worker }
1753*35238bceSAndroid Build Coastguard Worker }
1754*35238bceSAndroid Build Coastguard Worker else
1755*35238bceSAndroid Build Coastguard Worker {
1756*35238bceSAndroid Build Coastguard Worker DE_ASSERT(scalarType == glu::TYPE_INT || scalarType == glu::TYPE_UINT);
1757*35238bceSAndroid Build Coastguard Worker
1758*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numComps; ndx++)
1759*35238bceSAndroid Build Coastguard Worker {
1760*35238bceSAndroid Build Coastguard Worker const uint32_t refVal = *((const uint32_t *)ref + ndx);
1761*35238bceSAndroid Build Coastguard Worker const uint32_t resVal = *((const uint32_t *)res + ndx);
1762*35238bceSAndroid Build Coastguard Worker
1763*35238bceSAndroid Build Coastguard Worker if (refVal != resVal)
1764*35238bceSAndroid Build Coastguard Worker return false;
1765*35238bceSAndroid Build Coastguard Worker }
1766*35238bceSAndroid Build Coastguard Worker }
1767*35238bceSAndroid Build Coastguard Worker
1768*35238bceSAndroid Build Coastguard Worker return true;
1769*35238bceSAndroid Build Coastguard Worker }
1770*35238bceSAndroid Build Coastguard Worker
compareBufferVarData(tcu::TestLog & log,const BufferVarLayoutEntry & refEntry,const BlockDataPtr & refBlockPtr,const BufferVarLayoutEntry & resEntry,const BlockDataPtr & resBlockPtr)1771*35238bceSAndroid Build Coastguard Worker bool compareBufferVarData(tcu::TestLog &log, const BufferVarLayoutEntry &refEntry, const BlockDataPtr &refBlockPtr,
1772*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &resEntry, const BlockDataPtr &resBlockPtr)
1773*35238bceSAndroid Build Coastguard Worker {
1774*35238bceSAndroid Build Coastguard Worker DE_ASSERT(resEntry.arraySize <= refEntry.arraySize);
1775*35238bceSAndroid Build Coastguard Worker DE_ASSERT(resEntry.topLevelArraySize <= refEntry.topLevelArraySize);
1776*35238bceSAndroid Build Coastguard Worker DE_ASSERT(resBlockPtr.lastUnsizedArraySize <= refBlockPtr.lastUnsizedArraySize);
1777*35238bceSAndroid Build Coastguard Worker DE_ASSERT(resEntry.type == refEntry.type);
1778*35238bceSAndroid Build Coastguard Worker
1779*35238bceSAndroid Build Coastguard Worker uint8_t *const resBasePtr = (uint8_t *)resBlockPtr.ptr + resEntry.offset;
1780*35238bceSAndroid Build Coastguard Worker const uint8_t *const refBasePtr = (const uint8_t *)refBlockPtr.ptr + refEntry.offset;
1781*35238bceSAndroid Build Coastguard Worker const glu::DataType scalarType = glu::getDataTypeScalarType(refEntry.type);
1782*35238bceSAndroid Build Coastguard Worker const int scalarSize = glu::getDataTypeScalarSize(resEntry.type);
1783*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(resEntry.type);
1784*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
1785*35238bceSAndroid Build Coastguard Worker const int maxPrints = 3;
1786*35238bceSAndroid Build Coastguard Worker int numFailed = 0;
1787*35238bceSAndroid Build Coastguard Worker
1788*35238bceSAndroid Build Coastguard Worker const int resArraySize = resEntry.arraySize == 0 ? resBlockPtr.lastUnsizedArraySize : resEntry.arraySize;
1789*35238bceSAndroid Build Coastguard Worker const int resArrayStride = resEntry.arrayStride;
1790*35238bceSAndroid Build Coastguard Worker const int resTopLevelSize =
1791*35238bceSAndroid Build Coastguard Worker resEntry.topLevelArraySize == 0 ? resBlockPtr.lastUnsizedArraySize : resEntry.topLevelArraySize;
1792*35238bceSAndroid Build Coastguard Worker const int resTopLevelStride = resEntry.topLevelArrayStride;
1793*35238bceSAndroid Build Coastguard Worker const int refArraySize = refEntry.arraySize == 0 ? refBlockPtr.lastUnsizedArraySize : refEntry.arraySize;
1794*35238bceSAndroid Build Coastguard Worker const int refArrayStride = refEntry.arrayStride;
1795*35238bceSAndroid Build Coastguard Worker const int refTopLevelSize =
1796*35238bceSAndroid Build Coastguard Worker refEntry.topLevelArraySize == 0 ? refBlockPtr.lastUnsizedArraySize : refEntry.topLevelArraySize;
1797*35238bceSAndroid Build Coastguard Worker const int refTopLevelStride = refEntry.topLevelArrayStride;
1798*35238bceSAndroid Build Coastguard Worker
1799*35238bceSAndroid Build Coastguard Worker DE_ASSERT(resArraySize <= refArraySize && resTopLevelSize <= refTopLevelSize);
1800*35238bceSAndroid Build Coastguard Worker DE_UNREF(refArraySize && refTopLevelSize);
1801*35238bceSAndroid Build Coastguard Worker
1802*35238bceSAndroid Build Coastguard Worker for (int topElemNdx = 0; topElemNdx < resTopLevelSize; topElemNdx++)
1803*35238bceSAndroid Build Coastguard Worker {
1804*35238bceSAndroid Build Coastguard Worker uint8_t *const resTopPtr = resBasePtr + topElemNdx * resTopLevelStride;
1805*35238bceSAndroid Build Coastguard Worker const uint8_t *const refTopPtr = refBasePtr + topElemNdx * refTopLevelStride;
1806*35238bceSAndroid Build Coastguard Worker
1807*35238bceSAndroid Build Coastguard Worker for (int elementNdx = 0; elementNdx < resArraySize; elementNdx++)
1808*35238bceSAndroid Build Coastguard Worker {
1809*35238bceSAndroid Build Coastguard Worker uint8_t *const resElemPtr = resTopPtr + elementNdx * resArrayStride;
1810*35238bceSAndroid Build Coastguard Worker const uint8_t *const refElemPtr = refTopPtr + elementNdx * refArrayStride;
1811*35238bceSAndroid Build Coastguard Worker
1812*35238bceSAndroid Build Coastguard Worker if (isMatrix)
1813*35238bceSAndroid Build Coastguard Worker {
1814*35238bceSAndroid Build Coastguard Worker const int numRows = glu::getDataTypeMatrixNumRows(resEntry.type);
1815*35238bceSAndroid Build Coastguard Worker const int numCols = glu::getDataTypeMatrixNumColumns(resEntry.type);
1816*35238bceSAndroid Build Coastguard Worker bool isOk = true;
1817*35238bceSAndroid Build Coastguard Worker
1818*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < numCols; colNdx++)
1819*35238bceSAndroid Build Coastguard Worker {
1820*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
1821*35238bceSAndroid Build Coastguard Worker {
1822*35238bceSAndroid Build Coastguard Worker uint8_t *resCompPtr =
1823*35238bceSAndroid Build Coastguard Worker resElemPtr + (resEntry.isRowMajor ? rowNdx * resEntry.matrixStride + colNdx * compSize :
1824*35238bceSAndroid Build Coastguard Worker colNdx * resEntry.matrixStride + rowNdx * compSize);
1825*35238bceSAndroid Build Coastguard Worker const uint8_t *refCompPtr =
1826*35238bceSAndroid Build Coastguard Worker refElemPtr + (refEntry.isRowMajor ? rowNdx * refEntry.matrixStride + colNdx * compSize :
1827*35238bceSAndroid Build Coastguard Worker colNdx * refEntry.matrixStride + rowNdx * compSize);
1828*35238bceSAndroid Build Coastguard Worker
1829*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(refCompPtr + compSize) - (intptr_t)refBlockPtr.ptr <=
1830*35238bceSAndroid Build Coastguard Worker (intptr_t)refBlockPtr.size);
1831*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(resCompPtr + compSize) - (intptr_t)resBlockPtr.ptr <=
1832*35238bceSAndroid Build Coastguard Worker (intptr_t)resBlockPtr.size);
1833*35238bceSAndroid Build Coastguard Worker
1834*35238bceSAndroid Build Coastguard Worker isOk = isOk && compareComponents(scalarType, resCompPtr, refCompPtr, 1);
1835*35238bceSAndroid Build Coastguard Worker }
1836*35238bceSAndroid Build Coastguard Worker }
1837*35238bceSAndroid Build Coastguard Worker
1838*35238bceSAndroid Build Coastguard Worker if (!isOk)
1839*35238bceSAndroid Build Coastguard Worker {
1840*35238bceSAndroid Build Coastguard Worker numFailed += 1;
1841*35238bceSAndroid Build Coastguard Worker if (numFailed < maxPrints)
1842*35238bceSAndroid Build Coastguard Worker {
1843*35238bceSAndroid Build Coastguard Worker std::ostringstream expected, got;
1844*35238bceSAndroid Build Coastguard Worker generateImmMatrixSrc(expected, refEntry.type, refEntry.matrixStride, refEntry.isRowMajor,
1845*35238bceSAndroid Build Coastguard Worker refElemPtr);
1846*35238bceSAndroid Build Coastguard Worker generateImmMatrixSrc(got, resEntry.type, resEntry.matrixStride, resEntry.isRowMajor,
1847*35238bceSAndroid Build Coastguard Worker resElemPtr);
1848*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "ERROR: mismatch in " << refEntry.name << ", top-level ndx "
1849*35238bceSAndroid Build Coastguard Worker << topElemNdx << ", bottom-level ndx " << elementNdx << ":\n"
1850*35238bceSAndroid Build Coastguard Worker << " expected " << expected.str() << "\n"
1851*35238bceSAndroid Build Coastguard Worker << " got " << got.str() << TestLog::EndMessage;
1852*35238bceSAndroid Build Coastguard Worker }
1853*35238bceSAndroid Build Coastguard Worker }
1854*35238bceSAndroid Build Coastguard Worker }
1855*35238bceSAndroid Build Coastguard Worker else
1856*35238bceSAndroid Build Coastguard Worker {
1857*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(refElemPtr + scalarSize * compSize) - (intptr_t)refBlockPtr.ptr <=
1858*35238bceSAndroid Build Coastguard Worker (intptr_t)refBlockPtr.size);
1859*35238bceSAndroid Build Coastguard Worker DE_ASSERT((intptr_t)(resElemPtr + scalarSize * compSize) - (intptr_t)resBlockPtr.ptr <=
1860*35238bceSAndroid Build Coastguard Worker (intptr_t)resBlockPtr.size);
1861*35238bceSAndroid Build Coastguard Worker
1862*35238bceSAndroid Build Coastguard Worker const bool isOk = compareComponents(scalarType, resElemPtr, refElemPtr, scalarSize);
1863*35238bceSAndroid Build Coastguard Worker
1864*35238bceSAndroid Build Coastguard Worker if (!isOk)
1865*35238bceSAndroid Build Coastguard Worker {
1866*35238bceSAndroid Build Coastguard Worker numFailed += 1;
1867*35238bceSAndroid Build Coastguard Worker if (numFailed < maxPrints)
1868*35238bceSAndroid Build Coastguard Worker {
1869*35238bceSAndroid Build Coastguard Worker std::ostringstream expected, got;
1870*35238bceSAndroid Build Coastguard Worker generateImmScalarVectorSrc(expected, refEntry.type, refElemPtr);
1871*35238bceSAndroid Build Coastguard Worker generateImmScalarVectorSrc(got, resEntry.type, resElemPtr);
1872*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "ERROR: mismatch in " << refEntry.name << ", top-level ndx "
1873*35238bceSAndroid Build Coastguard Worker << topElemNdx << ", bottom-level ndx " << elementNdx << ":\n"
1874*35238bceSAndroid Build Coastguard Worker << " expected " << expected.str() << "\n"
1875*35238bceSAndroid Build Coastguard Worker << " got " << got.str() << TestLog::EndMessage;
1876*35238bceSAndroid Build Coastguard Worker }
1877*35238bceSAndroid Build Coastguard Worker }
1878*35238bceSAndroid Build Coastguard Worker }
1879*35238bceSAndroid Build Coastguard Worker }
1880*35238bceSAndroid Build Coastguard Worker }
1881*35238bceSAndroid Build Coastguard Worker
1882*35238bceSAndroid Build Coastguard Worker if (numFailed >= maxPrints)
1883*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "... (" << numFailed << " failures for " << refEntry.name << " in total)"
1884*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1885*35238bceSAndroid Build Coastguard Worker
1886*35238bceSAndroid Build Coastguard Worker return numFailed == 0;
1887*35238bceSAndroid Build Coastguard Worker }
1888*35238bceSAndroid Build Coastguard Worker
compareData(tcu::TestLog & log,const BufferLayout & refLayout,const vector<BlockDataPtr> & refBlockPointers,const BufferLayout & resLayout,const vector<BlockDataPtr> & resBlockPointers)1889*35238bceSAndroid Build Coastguard Worker bool compareData(tcu::TestLog &log, const BufferLayout &refLayout, const vector<BlockDataPtr> &refBlockPointers,
1890*35238bceSAndroid Build Coastguard Worker const BufferLayout &resLayout, const vector<BlockDataPtr> &resBlockPointers)
1891*35238bceSAndroid Build Coastguard Worker {
1892*35238bceSAndroid Build Coastguard Worker const int numBlocks = (int)refLayout.blocks.size();
1893*35238bceSAndroid Build Coastguard Worker bool allOk = true;
1894*35238bceSAndroid Build Coastguard Worker
1895*35238bceSAndroid Build Coastguard Worker for (int refBlockNdx = 0; refBlockNdx < numBlocks; refBlockNdx++)
1896*35238bceSAndroid Build Coastguard Worker {
1897*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &refBlock = refLayout.blocks[refBlockNdx];
1898*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &refBlockPtr = refBlockPointers[refBlockNdx];
1899*35238bceSAndroid Build Coastguard Worker int resBlockNdx = resLayout.getBlockIndex(refBlock.name.c_str());
1900*35238bceSAndroid Build Coastguard Worker
1901*35238bceSAndroid Build Coastguard Worker if (resBlockNdx >= 0)
1902*35238bceSAndroid Build Coastguard Worker {
1903*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(resBlockNdx, 0, (int)resBlockPointers.size()));
1904*35238bceSAndroid Build Coastguard Worker
1905*35238bceSAndroid Build Coastguard Worker const BlockDataPtr &resBlockPtr = resBlockPointers[resBlockNdx];
1906*35238bceSAndroid Build Coastguard Worker
1907*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator refVarNdxIter = refBlock.activeVarIndices.begin();
1908*35238bceSAndroid Build Coastguard Worker refVarNdxIter != refBlock.activeVarIndices.end(); refVarNdxIter++)
1909*35238bceSAndroid Build Coastguard Worker {
1910*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &refEntry = refLayout.bufferVars[*refVarNdxIter];
1911*35238bceSAndroid Build Coastguard Worker int resVarNdx = resLayout.getVariableIndex(refEntry.name.c_str());
1912*35238bceSAndroid Build Coastguard Worker
1913*35238bceSAndroid Build Coastguard Worker if (resVarNdx >= 0)
1914*35238bceSAndroid Build Coastguard Worker {
1915*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &resEntry = resLayout.bufferVars[resVarNdx];
1916*35238bceSAndroid Build Coastguard Worker allOk = compareBufferVarData(log, refEntry, refBlockPtr, resEntry, resBlockPtr) && allOk;
1917*35238bceSAndroid Build Coastguard Worker }
1918*35238bceSAndroid Build Coastguard Worker }
1919*35238bceSAndroid Build Coastguard Worker }
1920*35238bceSAndroid Build Coastguard Worker }
1921*35238bceSAndroid Build Coastguard Worker
1922*35238bceSAndroid Build Coastguard Worker return allOk;
1923*35238bceSAndroid Build Coastguard Worker }
1924*35238bceSAndroid Build Coastguard Worker
getBlockAPIName(const BufferBlock & block,int instanceNdx)1925*35238bceSAndroid Build Coastguard Worker string getBlockAPIName(const BufferBlock &block, int instanceNdx)
1926*35238bceSAndroid Build Coastguard Worker {
1927*35238bceSAndroid Build Coastguard Worker DE_ASSERT(block.isArray() || instanceNdx == 0);
1928*35238bceSAndroid Build Coastguard Worker return block.getBlockName() + (block.isArray() ? ("[" + de::toString(instanceNdx) + "]") : string());
1929*35238bceSAndroid Build Coastguard Worker }
1930*35238bceSAndroid Build Coastguard Worker
1931*35238bceSAndroid Build Coastguard Worker // \note Some implementations don't report block members in the order they are declared.
1932*35238bceSAndroid Build Coastguard Worker // For checking whether size has to be adjusted by some top-level array actual size,
1933*35238bceSAndroid Build Coastguard Worker // we only need to know a) whether there is a unsized top-level array, and b)
1934*35238bceSAndroid Build Coastguard Worker // what is stride of that array.
1935*35238bceSAndroid Build Coastguard Worker
hasUnsizedArray(const BufferLayout & layout,const BlockLayoutEntry & entry)1936*35238bceSAndroid Build Coastguard Worker static bool hasUnsizedArray(const BufferLayout &layout, const BlockLayoutEntry &entry)
1937*35238bceSAndroid Build Coastguard Worker {
1938*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator varNdx = entry.activeVarIndices.begin(); varNdx != entry.activeVarIndices.end();
1939*35238bceSAndroid Build Coastguard Worker ++varNdx)
1940*35238bceSAndroid Build Coastguard Worker {
1941*35238bceSAndroid Build Coastguard Worker if (isUnsizedArray(layout.bufferVars[*varNdx]))
1942*35238bceSAndroid Build Coastguard Worker return true;
1943*35238bceSAndroid Build Coastguard Worker }
1944*35238bceSAndroid Build Coastguard Worker
1945*35238bceSAndroid Build Coastguard Worker return false;
1946*35238bceSAndroid Build Coastguard Worker }
1947*35238bceSAndroid Build Coastguard Worker
getUnsizedArrayStride(const BufferLayout & layout,const BlockLayoutEntry & entry)1948*35238bceSAndroid Build Coastguard Worker static int getUnsizedArrayStride(const BufferLayout &layout, const BlockLayoutEntry &entry)
1949*35238bceSAndroid Build Coastguard Worker {
1950*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator varNdx = entry.activeVarIndices.begin(); varNdx != entry.activeVarIndices.end();
1951*35238bceSAndroid Build Coastguard Worker ++varNdx)
1952*35238bceSAndroid Build Coastguard Worker {
1953*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &varEntry = layout.bufferVars[*varNdx];
1954*35238bceSAndroid Build Coastguard Worker
1955*35238bceSAndroid Build Coastguard Worker if (varEntry.arraySize == 0)
1956*35238bceSAndroid Build Coastguard Worker return varEntry.arrayStride;
1957*35238bceSAndroid Build Coastguard Worker else if (varEntry.topLevelArraySize == 0)
1958*35238bceSAndroid Build Coastguard Worker return varEntry.topLevelArrayStride;
1959*35238bceSAndroid Build Coastguard Worker }
1960*35238bceSAndroid Build Coastguard Worker
1961*35238bceSAndroid Build Coastguard Worker return 0;
1962*35238bceSAndroid Build Coastguard Worker }
1963*35238bceSAndroid Build Coastguard Worker
computeBufferSizes(const ShaderInterface & interface,const BufferLayout & layout)1964*35238bceSAndroid Build Coastguard Worker vector<int> computeBufferSizes(const ShaderInterface &interface, const BufferLayout &layout)
1965*35238bceSAndroid Build Coastguard Worker {
1966*35238bceSAndroid Build Coastguard Worker vector<int> sizes(layout.blocks.size());
1967*35238bceSAndroid Build Coastguard Worker
1968*35238bceSAndroid Build Coastguard Worker for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++)
1969*35238bceSAndroid Build Coastguard Worker {
1970*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = interface.getBlock(declNdx);
1971*35238bceSAndroid Build Coastguard Worker const bool isArray = block.isArray();
1972*35238bceSAndroid Build Coastguard Worker const int numInstances = isArray ? block.getArraySize() : 1;
1973*35238bceSAndroid Build Coastguard Worker
1974*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
1975*35238bceSAndroid Build Coastguard Worker {
1976*35238bceSAndroid Build Coastguard Worker const string apiName = getBlockAPIName(block, instanceNdx);
1977*35238bceSAndroid Build Coastguard Worker const int blockNdx = layout.getBlockIndex(apiName);
1978*35238bceSAndroid Build Coastguard Worker
1979*35238bceSAndroid Build Coastguard Worker if (blockNdx >= 0)
1980*35238bceSAndroid Build Coastguard Worker {
1981*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &blockLayout = layout.blocks[blockNdx];
1982*35238bceSAndroid Build Coastguard Worker const int baseSize = blockLayout.size;
1983*35238bceSAndroid Build Coastguard Worker const bool isLastUnsized = hasUnsizedArray(layout, blockLayout);
1984*35238bceSAndroid Build Coastguard Worker const int lastArraySize = isLastUnsized ? block.getLastUnsizedArraySize(instanceNdx) : 0;
1985*35238bceSAndroid Build Coastguard Worker const int stride = isLastUnsized ? getUnsizedArrayStride(layout, blockLayout) : 0;
1986*35238bceSAndroid Build Coastguard Worker
1987*35238bceSAndroid Build Coastguard Worker sizes[blockNdx] = baseSize + lastArraySize * stride;
1988*35238bceSAndroid Build Coastguard Worker }
1989*35238bceSAndroid Build Coastguard Worker }
1990*35238bceSAndroid Build Coastguard Worker }
1991*35238bceSAndroid Build Coastguard Worker
1992*35238bceSAndroid Build Coastguard Worker return sizes;
1993*35238bceSAndroid Build Coastguard Worker }
1994*35238bceSAndroid Build Coastguard Worker
getBlockDataPtr(const BufferLayout & layout,const BlockLayoutEntry & blockLayout,void * ptr,int bufferSize)1995*35238bceSAndroid Build Coastguard Worker BlockDataPtr getBlockDataPtr(const BufferLayout &layout, const BlockLayoutEntry &blockLayout, void *ptr, int bufferSize)
1996*35238bceSAndroid Build Coastguard Worker {
1997*35238bceSAndroid Build Coastguard Worker const bool isLastUnsized = hasUnsizedArray(layout, blockLayout);
1998*35238bceSAndroid Build Coastguard Worker const int baseSize = blockLayout.size;
1999*35238bceSAndroid Build Coastguard Worker
2000*35238bceSAndroid Build Coastguard Worker if (isLastUnsized)
2001*35238bceSAndroid Build Coastguard Worker {
2002*35238bceSAndroid Build Coastguard Worker const int lastArrayStride = getUnsizedArrayStride(layout, blockLayout);
2003*35238bceSAndroid Build Coastguard Worker const int lastArraySize = (bufferSize - baseSize) / (lastArrayStride ? lastArrayStride : 1);
2004*35238bceSAndroid Build Coastguard Worker
2005*35238bceSAndroid Build Coastguard Worker DE_ASSERT(baseSize + lastArraySize * lastArrayStride == bufferSize);
2006*35238bceSAndroid Build Coastguard Worker
2007*35238bceSAndroid Build Coastguard Worker return BlockDataPtr(ptr, bufferSize, lastArraySize);
2008*35238bceSAndroid Build Coastguard Worker }
2009*35238bceSAndroid Build Coastguard Worker else
2010*35238bceSAndroid Build Coastguard Worker return BlockDataPtr(ptr, bufferSize, 0);
2011*35238bceSAndroid Build Coastguard Worker }
2012*35238bceSAndroid Build Coastguard Worker
2013*35238bceSAndroid Build Coastguard Worker struct RefDataStorage
2014*35238bceSAndroid Build Coastguard Worker {
2015*35238bceSAndroid Build Coastguard Worker vector<uint8_t> data;
2016*35238bceSAndroid Build Coastguard Worker vector<BlockDataPtr> pointers;
2017*35238bceSAndroid Build Coastguard Worker };
2018*35238bceSAndroid Build Coastguard Worker
2019*35238bceSAndroid Build Coastguard Worker struct Buffer
2020*35238bceSAndroid Build Coastguard Worker {
2021*35238bceSAndroid Build Coastguard Worker uint32_t buffer;
2022*35238bceSAndroid Build Coastguard Worker int size;
2023*35238bceSAndroid Build Coastguard Worker
Bufferdeqp::gles31::bb::__anonc1049a2c0211::Buffer2024*35238bceSAndroid Build Coastguard Worker Buffer(uint32_t buffer_, int size_) : buffer(buffer_), size(size_)
2025*35238bceSAndroid Build Coastguard Worker {
2026*35238bceSAndroid Build Coastguard Worker }
Bufferdeqp::gles31::bb::__anonc1049a2c0211::Buffer2027*35238bceSAndroid Build Coastguard Worker Buffer(void) : buffer(0), size(0)
2028*35238bceSAndroid Build Coastguard Worker {
2029*35238bceSAndroid Build Coastguard Worker }
2030*35238bceSAndroid Build Coastguard Worker };
2031*35238bceSAndroid Build Coastguard Worker
2032*35238bceSAndroid Build Coastguard Worker struct BlockLocation
2033*35238bceSAndroid Build Coastguard Worker {
2034*35238bceSAndroid Build Coastguard Worker int index;
2035*35238bceSAndroid Build Coastguard Worker int offset;
2036*35238bceSAndroid Build Coastguard Worker int size;
2037*35238bceSAndroid Build Coastguard Worker
BlockLocationdeqp::gles31::bb::__anonc1049a2c0211::BlockLocation2038*35238bceSAndroid Build Coastguard Worker BlockLocation(int index_, int offset_, int size_) : index(index_), offset(offset_), size(size_)
2039*35238bceSAndroid Build Coastguard Worker {
2040*35238bceSAndroid Build Coastguard Worker }
BlockLocationdeqp::gles31::bb::__anonc1049a2c0211::BlockLocation2041*35238bceSAndroid Build Coastguard Worker BlockLocation(void) : index(0), offset(0), size(0)
2042*35238bceSAndroid Build Coastguard Worker {
2043*35238bceSAndroid Build Coastguard Worker }
2044*35238bceSAndroid Build Coastguard Worker };
2045*35238bceSAndroid Build Coastguard Worker
initRefDataStorage(const ShaderInterface & interface,const BufferLayout & layout,RefDataStorage & storage)2046*35238bceSAndroid Build Coastguard Worker void initRefDataStorage(const ShaderInterface &interface, const BufferLayout &layout, RefDataStorage &storage)
2047*35238bceSAndroid Build Coastguard Worker {
2048*35238bceSAndroid Build Coastguard Worker DE_ASSERT(storage.data.empty() && storage.pointers.empty());
2049*35238bceSAndroid Build Coastguard Worker
2050*35238bceSAndroid Build Coastguard Worker const vector<int> bufferSizes = computeBufferSizes(interface, layout);
2051*35238bceSAndroid Build Coastguard Worker int totalSize = 0;
2052*35238bceSAndroid Build Coastguard Worker
2053*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator sizeIter = bufferSizes.begin(); sizeIter != bufferSizes.end(); ++sizeIter)
2054*35238bceSAndroid Build Coastguard Worker totalSize += *sizeIter;
2055*35238bceSAndroid Build Coastguard Worker
2056*35238bceSAndroid Build Coastguard Worker storage.data.resize(totalSize);
2057*35238bceSAndroid Build Coastguard Worker
2058*35238bceSAndroid Build Coastguard Worker // Pointers for each block.
2059*35238bceSAndroid Build Coastguard Worker {
2060*35238bceSAndroid Build Coastguard Worker uint8_t *basePtr = storage.data.empty() ? DE_NULL : &storage.data[0];
2061*35238bceSAndroid Build Coastguard Worker int curOffset = 0;
2062*35238bceSAndroid Build Coastguard Worker
2063*35238bceSAndroid Build Coastguard Worker DE_ASSERT(bufferSizes.size() == layout.blocks.size());
2064*35238bceSAndroid Build Coastguard Worker DE_ASSERT(totalSize == 0 || basePtr);
2065*35238bceSAndroid Build Coastguard Worker
2066*35238bceSAndroid Build Coastguard Worker storage.pointers.resize(layout.blocks.size());
2067*35238bceSAndroid Build Coastguard Worker
2068*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++)
2069*35238bceSAndroid Build Coastguard Worker {
2070*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &blockLayout = layout.blocks[blockNdx];
2071*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferSizes[blockNdx];
2072*35238bceSAndroid Build Coastguard Worker
2073*35238bceSAndroid Build Coastguard Worker storage.pointers[blockNdx] = getBlockDataPtr(layout, blockLayout, basePtr + curOffset, bufferSize);
2074*35238bceSAndroid Build Coastguard Worker
2075*35238bceSAndroid Build Coastguard Worker curOffset += bufferSize;
2076*35238bceSAndroid Build Coastguard Worker }
2077*35238bceSAndroid Build Coastguard Worker }
2078*35238bceSAndroid Build Coastguard Worker }
2079*35238bceSAndroid Build Coastguard Worker
blockLocationsToPtrs(const BufferLayout & layout,const vector<BlockLocation> & blockLocations,const vector<void * > & bufPtrs)2080*35238bceSAndroid Build Coastguard Worker vector<BlockDataPtr> blockLocationsToPtrs(const BufferLayout &layout, const vector<BlockLocation> &blockLocations,
2081*35238bceSAndroid Build Coastguard Worker const vector<void *> &bufPtrs)
2082*35238bceSAndroid Build Coastguard Worker {
2083*35238bceSAndroid Build Coastguard Worker vector<BlockDataPtr> blockPtrs(blockLocations.size());
2084*35238bceSAndroid Build Coastguard Worker
2085*35238bceSAndroid Build Coastguard Worker DE_ASSERT(layout.blocks.size() == blockLocations.size());
2086*35238bceSAndroid Build Coastguard Worker
2087*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++)
2088*35238bceSAndroid Build Coastguard Worker {
2089*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &blockLayout = layout.blocks[blockNdx];
2090*35238bceSAndroid Build Coastguard Worker const BlockLocation &location = blockLocations[blockNdx];
2091*35238bceSAndroid Build Coastguard Worker
2092*35238bceSAndroid Build Coastguard Worker blockPtrs[blockNdx] =
2093*35238bceSAndroid Build Coastguard Worker getBlockDataPtr(layout, blockLayout, (uint8_t *)bufPtrs[location.index] + location.offset, location.size);
2094*35238bceSAndroid Build Coastguard Worker }
2095*35238bceSAndroid Build Coastguard Worker
2096*35238bceSAndroid Build Coastguard Worker return blockPtrs;
2097*35238bceSAndroid Build Coastguard Worker }
2098*35238bceSAndroid Build Coastguard Worker
mapBuffers(const glw::Functions & gl,const vector<Buffer> & buffers,uint32_t access)2099*35238bceSAndroid Build Coastguard Worker vector<void *> mapBuffers(const glw::Functions &gl, const vector<Buffer> &buffers, uint32_t access)
2100*35238bceSAndroid Build Coastguard Worker {
2101*35238bceSAndroid Build Coastguard Worker vector<void *> mapPtrs(buffers.size(), DE_NULL);
2102*35238bceSAndroid Build Coastguard Worker
2103*35238bceSAndroid Build Coastguard Worker try
2104*35238bceSAndroid Build Coastguard Worker {
2105*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)buffers.size(); ndx++)
2106*35238bceSAndroid Build Coastguard Worker {
2107*35238bceSAndroid Build Coastguard Worker if (buffers[ndx].size > 0)
2108*35238bceSAndroid Build Coastguard Worker {
2109*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer);
2110*35238bceSAndroid Build Coastguard Worker mapPtrs[ndx] = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffers[ndx].size, access);
2111*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to map buffer");
2112*35238bceSAndroid Build Coastguard Worker TCU_CHECK(mapPtrs[ndx]);
2113*35238bceSAndroid Build Coastguard Worker }
2114*35238bceSAndroid Build Coastguard Worker else
2115*35238bceSAndroid Build Coastguard Worker mapPtrs[ndx] = DE_NULL;
2116*35238bceSAndroid Build Coastguard Worker }
2117*35238bceSAndroid Build Coastguard Worker
2118*35238bceSAndroid Build Coastguard Worker return mapPtrs;
2119*35238bceSAndroid Build Coastguard Worker }
2120*35238bceSAndroid Build Coastguard Worker catch (...)
2121*35238bceSAndroid Build Coastguard Worker {
2122*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)buffers.size(); ndx++)
2123*35238bceSAndroid Build Coastguard Worker {
2124*35238bceSAndroid Build Coastguard Worker if (mapPtrs[ndx])
2125*35238bceSAndroid Build Coastguard Worker {
2126*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer);
2127*35238bceSAndroid Build Coastguard Worker gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
2128*35238bceSAndroid Build Coastguard Worker }
2129*35238bceSAndroid Build Coastguard Worker }
2130*35238bceSAndroid Build Coastguard Worker
2131*35238bceSAndroid Build Coastguard Worker throw;
2132*35238bceSAndroid Build Coastguard Worker }
2133*35238bceSAndroid Build Coastguard Worker }
2134*35238bceSAndroid Build Coastguard Worker
unmapBuffers(const glw::Functions & gl,const vector<Buffer> & buffers)2135*35238bceSAndroid Build Coastguard Worker void unmapBuffers(const glw::Functions &gl, const vector<Buffer> &buffers)
2136*35238bceSAndroid Build Coastguard Worker {
2137*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)buffers.size(); ndx++)
2138*35238bceSAndroid Build Coastguard Worker {
2139*35238bceSAndroid Build Coastguard Worker if (buffers[ndx].size > 0)
2140*35238bceSAndroid Build Coastguard Worker {
2141*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer);
2142*35238bceSAndroid Build Coastguard Worker gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
2143*35238bceSAndroid Build Coastguard Worker }
2144*35238bceSAndroid Build Coastguard Worker }
2145*35238bceSAndroid Build Coastguard Worker
2146*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer");
2147*35238bceSAndroid Build Coastguard Worker }
2148*35238bceSAndroid Build Coastguard Worker
2149*35238bceSAndroid Build Coastguard Worker } // namespace
2150*35238bceSAndroid Build Coastguard Worker
2151*35238bceSAndroid Build Coastguard Worker class BufferManager
2152*35238bceSAndroid Build Coastguard Worker {
2153*35238bceSAndroid Build Coastguard Worker public:
2154*35238bceSAndroid Build Coastguard Worker BufferManager(const glu::RenderContext &renderCtx);
2155*35238bceSAndroid Build Coastguard Worker ~BufferManager(void);
2156*35238bceSAndroid Build Coastguard Worker
2157*35238bceSAndroid Build Coastguard Worker uint32_t allocBuffer(void);
2158*35238bceSAndroid Build Coastguard Worker
2159*35238bceSAndroid Build Coastguard Worker private:
2160*35238bceSAndroid Build Coastguard Worker BufferManager(const BufferManager &other);
2161*35238bceSAndroid Build Coastguard Worker BufferManager &operator=(const BufferManager &other);
2162*35238bceSAndroid Build Coastguard Worker
2163*35238bceSAndroid Build Coastguard Worker const glu::RenderContext &m_renderCtx;
2164*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> m_buffers;
2165*35238bceSAndroid Build Coastguard Worker };
2166*35238bceSAndroid Build Coastguard Worker
BufferManager(const glu::RenderContext & renderCtx)2167*35238bceSAndroid Build Coastguard Worker BufferManager::BufferManager(const glu::RenderContext &renderCtx) : m_renderCtx(renderCtx)
2168*35238bceSAndroid Build Coastguard Worker {
2169*35238bceSAndroid Build Coastguard Worker }
2170*35238bceSAndroid Build Coastguard Worker
~BufferManager(void)2171*35238bceSAndroid Build Coastguard Worker BufferManager::~BufferManager(void)
2172*35238bceSAndroid Build Coastguard Worker {
2173*35238bceSAndroid Build Coastguard Worker if (!m_buffers.empty())
2174*35238bceSAndroid Build Coastguard Worker m_renderCtx.getFunctions().deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
2175*35238bceSAndroid Build Coastguard Worker }
2176*35238bceSAndroid Build Coastguard Worker
allocBuffer(void)2177*35238bceSAndroid Build Coastguard Worker uint32_t BufferManager::allocBuffer(void)
2178*35238bceSAndroid Build Coastguard Worker {
2179*35238bceSAndroid Build Coastguard Worker uint32_t buf = 0;
2180*35238bceSAndroid Build Coastguard Worker
2181*35238bceSAndroid Build Coastguard Worker m_buffers.reserve(m_buffers.size() + 1);
2182*35238bceSAndroid Build Coastguard Worker m_renderCtx.getFunctions().genBuffers(1, &buf);
2183*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_renderCtx.getFunctions().getError(), "Failed to allocate buffer");
2184*35238bceSAndroid Build Coastguard Worker m_buffers.push_back(buf);
2185*35238bceSAndroid Build Coastguard Worker
2186*35238bceSAndroid Build Coastguard Worker return buf;
2187*35238bceSAndroid Build Coastguard Worker }
2188*35238bceSAndroid Build Coastguard Worker
2189*35238bceSAndroid Build Coastguard Worker } // namespace bb
2190*35238bceSAndroid Build Coastguard Worker
2191*35238bceSAndroid Build Coastguard Worker using namespace bb;
2192*35238bceSAndroid Build Coastguard Worker
2193*35238bceSAndroid Build Coastguard Worker // SSBOLayoutCase.
2194*35238bceSAndroid Build Coastguard Worker
SSBOLayoutCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,glu::GLSLVersion glslVersion,BufferMode bufferMode)2195*35238bceSAndroid Build Coastguard Worker SSBOLayoutCase::SSBOLayoutCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
2196*35238bceSAndroid Build Coastguard Worker const char *description, glu::GLSLVersion glslVersion, BufferMode bufferMode)
2197*35238bceSAndroid Build Coastguard Worker : TestCase(testCtx, name, description)
2198*35238bceSAndroid Build Coastguard Worker , m_renderCtx(renderCtx)
2199*35238bceSAndroid Build Coastguard Worker , m_glslVersion(glslVersion)
2200*35238bceSAndroid Build Coastguard Worker , m_bufferMode(bufferMode)
2201*35238bceSAndroid Build Coastguard Worker {
2202*35238bceSAndroid Build Coastguard Worker DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion == glu::GLSL_VERSION_430);
2203*35238bceSAndroid Build Coastguard Worker }
2204*35238bceSAndroid Build Coastguard Worker
~SSBOLayoutCase(void)2205*35238bceSAndroid Build Coastguard Worker SSBOLayoutCase::~SSBOLayoutCase(void)
2206*35238bceSAndroid Build Coastguard Worker {
2207*35238bceSAndroid Build Coastguard Worker }
2208*35238bceSAndroid Build Coastguard Worker
iterate(void)2209*35238bceSAndroid Build Coastguard Worker SSBOLayoutCase::IterateResult SSBOLayoutCase::iterate(void)
2210*35238bceSAndroid Build Coastguard Worker {
2211*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2212*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
2213*35238bceSAndroid Build Coastguard Worker
2214*35238bceSAndroid Build Coastguard Worker BufferLayout refLayout; // std140 / std430 layout.
2215*35238bceSAndroid Build Coastguard Worker BufferLayout glLayout; // Layout reported by GL.
2216*35238bceSAndroid Build Coastguard Worker RefDataStorage initialData; // Initial data stored in buffer.
2217*35238bceSAndroid Build Coastguard Worker RefDataStorage writeData; // Data written by compute shader.
2218*35238bceSAndroid Build Coastguard Worker
2219*35238bceSAndroid Build Coastguard Worker BufferManager bufferManager(m_renderCtx);
2220*35238bceSAndroid Build Coastguard Worker vector<Buffer> buffers; // Buffers allocated for storage
2221*35238bceSAndroid Build Coastguard Worker vector<BlockLocation> blockLocations; // Block locations in storage (index, offset)
2222*35238bceSAndroid Build Coastguard Worker
2223*35238bceSAndroid Build Coastguard Worker // Initialize result to pass.
2224*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2225*35238bceSAndroid Build Coastguard Worker
2226*35238bceSAndroid Build Coastguard Worker computeReferenceLayout(refLayout, m_interface);
2227*35238bceSAndroid Build Coastguard Worker initRefDataStorage(m_interface, refLayout, initialData);
2228*35238bceSAndroid Build Coastguard Worker initRefDataStorage(m_interface, refLayout, writeData);
2229*35238bceSAndroid Build Coastguard Worker generateValues(refLayout, initialData.pointers, deStringHash(getName()) ^ 0xad2f7214);
2230*35238bceSAndroid Build Coastguard Worker generateValues(refLayout, writeData.pointers, deStringHash(getName()) ^ 0x25ca4e7);
2231*35238bceSAndroid Build Coastguard Worker copyNonWrittenData(m_interface, refLayout, initialData.pointers, writeData.pointers);
2232*35238bceSAndroid Build Coastguard Worker
2233*35238bceSAndroid Build Coastguard Worker const glu::ShaderProgram program(
2234*35238bceSAndroid Build Coastguard Worker m_renderCtx, glu::ProgramSources() << glu::ComputeSource(generateComputeShader(
2235*35238bceSAndroid Build Coastguard Worker gl, m_glslVersion, m_interface, refLayout, initialData.pointers, writeData.pointers)));
2236*35238bceSAndroid Build Coastguard Worker log << program;
2237*35238bceSAndroid Build Coastguard Worker
2238*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
2239*35238bceSAndroid Build Coastguard Worker {
2240*35238bceSAndroid Build Coastguard Worker // Compile failed.
2241*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
2242*35238bceSAndroid Build Coastguard Worker return STOP;
2243*35238bceSAndroid Build Coastguard Worker }
2244*35238bceSAndroid Build Coastguard Worker
2245*35238bceSAndroid Build Coastguard Worker // Query layout from GL.
2246*35238bceSAndroid Build Coastguard Worker getGLBufferLayout(gl, glLayout, program.getProgram());
2247*35238bceSAndroid Build Coastguard Worker
2248*35238bceSAndroid Build Coastguard Worker // Print layout to log.
2249*35238bceSAndroid Build Coastguard Worker {
2250*35238bceSAndroid Build Coastguard Worker tcu::ScopedLogSection section(log, "ActiveBufferBlocks", "Active Buffer Blocks");
2251*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)glLayout.blocks.size(); blockNdx++)
2252*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << blockNdx << ": " << glLayout.blocks[blockNdx] << TestLog::EndMessage;
2253*35238bceSAndroid Build Coastguard Worker }
2254*35238bceSAndroid Build Coastguard Worker
2255*35238bceSAndroid Build Coastguard Worker {
2256*35238bceSAndroid Build Coastguard Worker tcu::ScopedLogSection section(log, "ActiveBufferVars", "Active Buffer Variables");
2257*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < (int)glLayout.bufferVars.size(); varNdx++)
2258*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << varNdx << ": " << glLayout.bufferVars[varNdx] << TestLog::EndMessage;
2259*35238bceSAndroid Build Coastguard Worker }
2260*35238bceSAndroid Build Coastguard Worker
2261*35238bceSAndroid Build Coastguard Worker // Verify layouts.
2262*35238bceSAndroid Build Coastguard Worker {
2263*35238bceSAndroid Build Coastguard Worker if (!checkLayoutIndices(glLayout) || !checkLayoutBounds(glLayout) || !compareTypes(refLayout, glLayout))
2264*35238bceSAndroid Build Coastguard Worker {
2265*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid layout");
2266*35238bceSAndroid Build Coastguard Worker return STOP; // It is not safe to use the given layout.
2267*35238bceSAndroid Build Coastguard Worker }
2268*35238bceSAndroid Build Coastguard Worker
2269*35238bceSAndroid Build Coastguard Worker if (!compareStdBlocks(refLayout, glLayout))
2270*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid std140 or std430 layout");
2271*35238bceSAndroid Build Coastguard Worker
2272*35238bceSAndroid Build Coastguard Worker if (!compareSharedBlocks(refLayout, glLayout))
2273*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid shared layout");
2274*35238bceSAndroid Build Coastguard Worker
2275*35238bceSAndroid Build Coastguard Worker if (!checkIndexQueries(program.getProgram(), glLayout))
2276*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsintent block index query results");
2277*35238bceSAndroid Build Coastguard Worker }
2278*35238bceSAndroid Build Coastguard Worker
2279*35238bceSAndroid Build Coastguard Worker // Allocate GL buffers & compute placement.
2280*35238bceSAndroid Build Coastguard Worker {
2281*35238bceSAndroid Build Coastguard Worker const int numBlocks = (int)glLayout.blocks.size();
2282*35238bceSAndroid Build Coastguard Worker const vector<int> bufferSizes = computeBufferSizes(m_interface, glLayout);
2283*35238bceSAndroid Build Coastguard Worker
2284*35238bceSAndroid Build Coastguard Worker DE_ASSERT(bufferSizes.size() == glLayout.blocks.size());
2285*35238bceSAndroid Build Coastguard Worker
2286*35238bceSAndroid Build Coastguard Worker blockLocations.resize(numBlocks);
2287*35238bceSAndroid Build Coastguard Worker
2288*35238bceSAndroid Build Coastguard Worker if (m_bufferMode == BUFFERMODE_PER_BLOCK)
2289*35238bceSAndroid Build Coastguard Worker {
2290*35238bceSAndroid Build Coastguard Worker buffers.resize(numBlocks);
2291*35238bceSAndroid Build Coastguard Worker
2292*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2293*35238bceSAndroid Build Coastguard Worker {
2294*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferSizes[blockNdx];
2295*35238bceSAndroid Build Coastguard Worker
2296*35238bceSAndroid Build Coastguard Worker buffers[blockNdx].size = bufferSize;
2297*35238bceSAndroid Build Coastguard Worker blockLocations[blockNdx] = BlockLocation(blockNdx, 0, bufferSize);
2298*35238bceSAndroid Build Coastguard Worker }
2299*35238bceSAndroid Build Coastguard Worker }
2300*35238bceSAndroid Build Coastguard Worker else
2301*35238bceSAndroid Build Coastguard Worker {
2302*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_bufferMode == BUFFERMODE_SINGLE);
2303*35238bceSAndroid Build Coastguard Worker
2304*35238bceSAndroid Build Coastguard Worker int bindingAlignment = 0;
2305*35238bceSAndroid Build Coastguard Worker int totalSize = 0;
2306*35238bceSAndroid Build Coastguard Worker
2307*35238bceSAndroid Build Coastguard Worker gl.getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bindingAlignment);
2308*35238bceSAndroid Build Coastguard Worker
2309*35238bceSAndroid Build Coastguard Worker {
2310*35238bceSAndroid Build Coastguard Worker int curOffset = 0;
2311*35238bceSAndroid Build Coastguard Worker DE_ASSERT(bufferSizes.size() == glLayout.blocks.size());
2312*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2313*35238bceSAndroid Build Coastguard Worker {
2314*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferSizes[blockNdx];
2315*35238bceSAndroid Build Coastguard Worker
2316*35238bceSAndroid Build Coastguard Worker if (bindingAlignment > 0)
2317*35238bceSAndroid Build Coastguard Worker curOffset = deRoundUp32(curOffset, bindingAlignment);
2318*35238bceSAndroid Build Coastguard Worker
2319*35238bceSAndroid Build Coastguard Worker blockLocations[blockNdx] = BlockLocation(0, curOffset, bufferSize);
2320*35238bceSAndroid Build Coastguard Worker curOffset += bufferSize;
2321*35238bceSAndroid Build Coastguard Worker }
2322*35238bceSAndroid Build Coastguard Worker totalSize = curOffset;
2323*35238bceSAndroid Build Coastguard Worker }
2324*35238bceSAndroid Build Coastguard Worker
2325*35238bceSAndroid Build Coastguard Worker buffers.resize(1);
2326*35238bceSAndroid Build Coastguard Worker buffers[0].size = totalSize;
2327*35238bceSAndroid Build Coastguard Worker }
2328*35238bceSAndroid Build Coastguard Worker
2329*35238bceSAndroid Build Coastguard Worker for (int bufNdx = 0; bufNdx < (int)buffers.size(); bufNdx++)
2330*35238bceSAndroid Build Coastguard Worker {
2331*35238bceSAndroid Build Coastguard Worker const int bufferSize = buffers[bufNdx].size;
2332*35238bceSAndroid Build Coastguard Worker const uint32_t buffer = bufferManager.allocBuffer();
2333*35238bceSAndroid Build Coastguard Worker
2334*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2335*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_STATIC_DRAW);
2336*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to allocate buffer");
2337*35238bceSAndroid Build Coastguard Worker
2338*35238bceSAndroid Build Coastguard Worker buffers[bufNdx].buffer = buffer;
2339*35238bceSAndroid Build Coastguard Worker }
2340*35238bceSAndroid Build Coastguard Worker }
2341*35238bceSAndroid Build Coastguard Worker
2342*35238bceSAndroid Build Coastguard Worker {
2343*35238bceSAndroid Build Coastguard Worker const vector<void *> mapPtrs = mapBuffers(gl, buffers, GL_MAP_WRITE_BIT);
2344*35238bceSAndroid Build Coastguard Worker const vector<BlockDataPtr> mappedBlockPtrs = blockLocationsToPtrs(glLayout, blockLocations, mapPtrs);
2345*35238bceSAndroid Build Coastguard Worker
2346*35238bceSAndroid Build Coastguard Worker copyData(glLayout, mappedBlockPtrs, refLayout, initialData.pointers);
2347*35238bceSAndroid Build Coastguard Worker
2348*35238bceSAndroid Build Coastguard Worker unmapBuffers(gl, buffers);
2349*35238bceSAndroid Build Coastguard Worker }
2350*35238bceSAndroid Build Coastguard Worker
2351*35238bceSAndroid Build Coastguard Worker {
2352*35238bceSAndroid Build Coastguard Worker int bindingPoint = 0;
2353*35238bceSAndroid Build Coastguard Worker
2354*35238bceSAndroid Build Coastguard Worker for (int blockDeclNdx = 0; blockDeclNdx < m_interface.getNumBlocks(); blockDeclNdx++)
2355*35238bceSAndroid Build Coastguard Worker {
2356*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = m_interface.getBlock(blockDeclNdx);
2357*35238bceSAndroid Build Coastguard Worker const int numInst = block.isArray() ? block.getArraySize() : 1;
2358*35238bceSAndroid Build Coastguard Worker
2359*35238bceSAndroid Build Coastguard Worker for (int instNdx = 0; instNdx < numInst; instNdx++)
2360*35238bceSAndroid Build Coastguard Worker {
2361*35238bceSAndroid Build Coastguard Worker const string instName = getBlockAPIName(block, instNdx);
2362*35238bceSAndroid Build Coastguard Worker const int layoutNdx = findBlockIndex(glLayout, instName);
2363*35238bceSAndroid Build Coastguard Worker
2364*35238bceSAndroid Build Coastguard Worker if (layoutNdx >= 0)
2365*35238bceSAndroid Build Coastguard Worker {
2366*35238bceSAndroid Build Coastguard Worker const BlockLocation &blockLoc = blockLocations[layoutNdx];
2367*35238bceSAndroid Build Coastguard Worker
2368*35238bceSAndroid Build Coastguard Worker if (blockLoc.size > 0)
2369*35238bceSAndroid Build Coastguard Worker gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, bindingPoint, buffers[blockLoc.index].buffer,
2370*35238bceSAndroid Build Coastguard Worker blockLoc.offset, blockLoc.size);
2371*35238bceSAndroid Build Coastguard Worker }
2372*35238bceSAndroid Build Coastguard Worker
2373*35238bceSAndroid Build Coastguard Worker bindingPoint += 1;
2374*35238bceSAndroid Build Coastguard Worker }
2375*35238bceSAndroid Build Coastguard Worker }
2376*35238bceSAndroid Build Coastguard Worker }
2377*35238bceSAndroid Build Coastguard Worker
2378*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffers");
2379*35238bceSAndroid Build Coastguard Worker
2380*35238bceSAndroid Build Coastguard Worker {
2381*35238bceSAndroid Build Coastguard Worker const bool execOk = execute(program.getProgram());
2382*35238bceSAndroid Build Coastguard Worker
2383*35238bceSAndroid Build Coastguard Worker if (execOk)
2384*35238bceSAndroid Build Coastguard Worker {
2385*35238bceSAndroid Build Coastguard Worker const vector<void *> mapPtrs = mapBuffers(gl, buffers, GL_MAP_READ_BIT);
2386*35238bceSAndroid Build Coastguard Worker const vector<BlockDataPtr> mappedBlockPtrs = blockLocationsToPtrs(glLayout, blockLocations, mapPtrs);
2387*35238bceSAndroid Build Coastguard Worker
2388*35238bceSAndroid Build Coastguard Worker const bool compareOk =
2389*35238bceSAndroid Build Coastguard Worker compareData(m_testCtx.getLog(), refLayout, writeData.pointers, glLayout, mappedBlockPtrs);
2390*35238bceSAndroid Build Coastguard Worker
2391*35238bceSAndroid Build Coastguard Worker unmapBuffers(gl, buffers);
2392*35238bceSAndroid Build Coastguard Worker
2393*35238bceSAndroid Build Coastguard Worker if (!compareOk)
2394*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
2395*35238bceSAndroid Build Coastguard Worker }
2396*35238bceSAndroid Build Coastguard Worker else
2397*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader execution failed");
2398*35238bceSAndroid Build Coastguard Worker }
2399*35238bceSAndroid Build Coastguard Worker
2400*35238bceSAndroid Build Coastguard Worker return STOP;
2401*35238bceSAndroid Build Coastguard Worker }
2402*35238bceSAndroid Build Coastguard Worker
compareStdBlocks(const BufferLayout & refLayout,const BufferLayout & cmpLayout) const2403*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::compareStdBlocks(const BufferLayout &refLayout, const BufferLayout &cmpLayout) const
2404*35238bceSAndroid Build Coastguard Worker {
2405*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2406*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2407*35238bceSAndroid Build Coastguard Worker int numBlocks = m_interface.getNumBlocks();
2408*35238bceSAndroid Build Coastguard Worker
2409*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2410*35238bceSAndroid Build Coastguard Worker {
2411*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = m_interface.getBlock(blockNdx);
2412*35238bceSAndroid Build Coastguard Worker bool isArray = block.isArray();
2413*35238bceSAndroid Build Coastguard Worker std::string instanceName = string(block.getBlockName()) + (isArray ? "[0]" : "");
2414*35238bceSAndroid Build Coastguard Worker int refBlockNdx = refLayout.getBlockIndex(instanceName.c_str());
2415*35238bceSAndroid Build Coastguard Worker int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.c_str());
2416*35238bceSAndroid Build Coastguard Worker
2417*35238bceSAndroid Build Coastguard Worker if ((block.getFlags() & (LAYOUT_STD140 | LAYOUT_STD430)) == 0)
2418*35238bceSAndroid Build Coastguard Worker continue; // Not std* layout.
2419*35238bceSAndroid Build Coastguard Worker
2420*35238bceSAndroid Build Coastguard Worker DE_ASSERT(refBlockNdx >= 0);
2421*35238bceSAndroid Build Coastguard Worker
2422*35238bceSAndroid Build Coastguard Worker if (cmpBlockNdx < 0)
2423*35238bceSAndroid Build Coastguard Worker {
2424*35238bceSAndroid Build Coastguard Worker // Not found.
2425*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer block '" << instanceName << "' not found" << TestLog::EndMessage;
2426*35238bceSAndroid Build Coastguard Worker isOk = false;
2427*35238bceSAndroid Build Coastguard Worker continue;
2428*35238bceSAndroid Build Coastguard Worker }
2429*35238bceSAndroid Build Coastguard Worker
2430*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &refBlockLayout = refLayout.blocks[refBlockNdx];
2431*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];
2432*35238bceSAndroid Build Coastguard Worker
2433*35238bceSAndroid Build Coastguard Worker // \todo [2012-01-24 pyry] Verify that activeVarIndices is correct.
2434*35238bceSAndroid Build Coastguard Worker // \todo [2012-01-24 pyry] Verify all instances.
2435*35238bceSAndroid Build Coastguard Worker if (refBlockLayout.activeVarIndices.size() != cmpBlockLayout.activeVarIndices.size())
2436*35238bceSAndroid Build Coastguard Worker {
2437*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Number of active variables differ in block '" << instanceName
2438*35238bceSAndroid Build Coastguard Worker << "' (expected " << refBlockLayout.activeVarIndices.size() << ", got "
2439*35238bceSAndroid Build Coastguard Worker << cmpBlockLayout.activeVarIndices.size() << ")" << TestLog::EndMessage;
2440*35238bceSAndroid Build Coastguard Worker isOk = false;
2441*35238bceSAndroid Build Coastguard Worker }
2442*35238bceSAndroid Build Coastguard Worker
2443*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator ndxIter = refBlockLayout.activeVarIndices.begin();
2444*35238bceSAndroid Build Coastguard Worker ndxIter != refBlockLayout.activeVarIndices.end(); ndxIter++)
2445*35238bceSAndroid Build Coastguard Worker {
2446*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &refEntry = refLayout.bufferVars[*ndxIter];
2447*35238bceSAndroid Build Coastguard Worker int cmpEntryNdx = cmpLayout.getVariableIndex(refEntry.name.c_str());
2448*35238bceSAndroid Build Coastguard Worker
2449*35238bceSAndroid Build Coastguard Worker if (cmpEntryNdx < 0)
2450*35238bceSAndroid Build Coastguard Worker {
2451*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer variable '" << refEntry.name << "' not found"
2452*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
2453*35238bceSAndroid Build Coastguard Worker isOk = false;
2454*35238bceSAndroid Build Coastguard Worker continue;
2455*35238bceSAndroid Build Coastguard Worker }
2456*35238bceSAndroid Build Coastguard Worker
2457*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &cmpEntry = cmpLayout.bufferVars[cmpEntryNdx];
2458*35238bceSAndroid Build Coastguard Worker
2459*35238bceSAndroid Build Coastguard Worker if (refEntry.type != cmpEntry.type || refEntry.arraySize != cmpEntry.arraySize ||
2460*35238bceSAndroid Build Coastguard Worker refEntry.offset != cmpEntry.offset || refEntry.arrayStride != cmpEntry.arrayStride ||
2461*35238bceSAndroid Build Coastguard Worker refEntry.matrixStride != cmpEntry.matrixStride ||
2462*35238bceSAndroid Build Coastguard Worker refEntry.topLevelArraySize != cmpEntry.topLevelArraySize ||
2463*35238bceSAndroid Build Coastguard Worker refEntry.topLevelArrayStride != cmpEntry.topLevelArrayStride ||
2464*35238bceSAndroid Build Coastguard Worker refEntry.isRowMajor != cmpEntry.isRowMajor)
2465*35238bceSAndroid Build Coastguard Worker {
2466*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Layout mismatch in '" << refEntry.name << "':\n"
2467*35238bceSAndroid Build Coastguard Worker << " expected: " << refEntry << "\n"
2468*35238bceSAndroid Build Coastguard Worker << " got: " << cmpEntry << TestLog::EndMessage;
2469*35238bceSAndroid Build Coastguard Worker isOk = false;
2470*35238bceSAndroid Build Coastguard Worker }
2471*35238bceSAndroid Build Coastguard Worker }
2472*35238bceSAndroid Build Coastguard Worker }
2473*35238bceSAndroid Build Coastguard Worker
2474*35238bceSAndroid Build Coastguard Worker return isOk;
2475*35238bceSAndroid Build Coastguard Worker }
2476*35238bceSAndroid Build Coastguard Worker
compareSharedBlocks(const BufferLayout & refLayout,const BufferLayout & cmpLayout) const2477*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::compareSharedBlocks(const BufferLayout &refLayout, const BufferLayout &cmpLayout) const
2478*35238bceSAndroid Build Coastguard Worker {
2479*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2480*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2481*35238bceSAndroid Build Coastguard Worker int numBlocks = m_interface.getNumBlocks();
2482*35238bceSAndroid Build Coastguard Worker
2483*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2484*35238bceSAndroid Build Coastguard Worker {
2485*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = m_interface.getBlock(blockNdx);
2486*35238bceSAndroid Build Coastguard Worker bool isArray = block.isArray();
2487*35238bceSAndroid Build Coastguard Worker std::string instanceName = string(block.getBlockName()) + (isArray ? "[0]" : "");
2488*35238bceSAndroid Build Coastguard Worker int refBlockNdx = refLayout.getBlockIndex(instanceName.c_str());
2489*35238bceSAndroid Build Coastguard Worker int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.c_str());
2490*35238bceSAndroid Build Coastguard Worker
2491*35238bceSAndroid Build Coastguard Worker if ((block.getFlags() & LAYOUT_SHARED) == 0)
2492*35238bceSAndroid Build Coastguard Worker continue; // Not shared layout.
2493*35238bceSAndroid Build Coastguard Worker
2494*35238bceSAndroid Build Coastguard Worker DE_ASSERT(refBlockNdx >= 0);
2495*35238bceSAndroid Build Coastguard Worker
2496*35238bceSAndroid Build Coastguard Worker if (cmpBlockNdx < 0)
2497*35238bceSAndroid Build Coastguard Worker {
2498*35238bceSAndroid Build Coastguard Worker // Not found, should it?
2499*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer block '" << instanceName << "' not found" << TestLog::EndMessage;
2500*35238bceSAndroid Build Coastguard Worker isOk = false;
2501*35238bceSAndroid Build Coastguard Worker continue;
2502*35238bceSAndroid Build Coastguard Worker }
2503*35238bceSAndroid Build Coastguard Worker
2504*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &refBlockLayout = refLayout.blocks[refBlockNdx];
2505*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];
2506*35238bceSAndroid Build Coastguard Worker
2507*35238bceSAndroid Build Coastguard Worker if (refBlockLayout.activeVarIndices.size() != cmpBlockLayout.activeVarIndices.size())
2508*35238bceSAndroid Build Coastguard Worker {
2509*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Number of active variables differ in block '" << instanceName
2510*35238bceSAndroid Build Coastguard Worker << "' (expected " << refBlockLayout.activeVarIndices.size() << ", got "
2511*35238bceSAndroid Build Coastguard Worker << cmpBlockLayout.activeVarIndices.size() << ")" << TestLog::EndMessage;
2512*35238bceSAndroid Build Coastguard Worker isOk = false;
2513*35238bceSAndroid Build Coastguard Worker }
2514*35238bceSAndroid Build Coastguard Worker
2515*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator ndxIter = refBlockLayout.activeVarIndices.begin();
2516*35238bceSAndroid Build Coastguard Worker ndxIter != refBlockLayout.activeVarIndices.end(); ndxIter++)
2517*35238bceSAndroid Build Coastguard Worker {
2518*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &refEntry = refLayout.bufferVars[*ndxIter];
2519*35238bceSAndroid Build Coastguard Worker int cmpEntryNdx = cmpLayout.getVariableIndex(refEntry.name.c_str());
2520*35238bceSAndroid Build Coastguard Worker
2521*35238bceSAndroid Build Coastguard Worker if (cmpEntryNdx < 0)
2522*35238bceSAndroid Build Coastguard Worker {
2523*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer variable '" << refEntry.name << "' not found"
2524*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
2525*35238bceSAndroid Build Coastguard Worker isOk = false;
2526*35238bceSAndroid Build Coastguard Worker continue;
2527*35238bceSAndroid Build Coastguard Worker }
2528*35238bceSAndroid Build Coastguard Worker
2529*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &cmpEntry = cmpLayout.bufferVars[cmpEntryNdx];
2530*35238bceSAndroid Build Coastguard Worker
2531*35238bceSAndroid Build Coastguard Worker if (refEntry.type != cmpEntry.type || refEntry.arraySize != cmpEntry.arraySize ||
2532*35238bceSAndroid Build Coastguard Worker refEntry.topLevelArraySize != cmpEntry.topLevelArraySize || refEntry.isRowMajor != cmpEntry.isRowMajor)
2533*35238bceSAndroid Build Coastguard Worker {
2534*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Type / array size mismatch in '" << refEntry.name << "':\n"
2535*35238bceSAndroid Build Coastguard Worker << " expected: " << refEntry << "\n"
2536*35238bceSAndroid Build Coastguard Worker << " got: " << cmpEntry << TestLog::EndMessage;
2537*35238bceSAndroid Build Coastguard Worker isOk = false;
2538*35238bceSAndroid Build Coastguard Worker }
2539*35238bceSAndroid Build Coastguard Worker }
2540*35238bceSAndroid Build Coastguard Worker }
2541*35238bceSAndroid Build Coastguard Worker
2542*35238bceSAndroid Build Coastguard Worker return isOk;
2543*35238bceSAndroid Build Coastguard Worker }
2544*35238bceSAndroid Build Coastguard Worker
compareTypes(const BufferLayout & refLayout,const BufferLayout & cmpLayout) const2545*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::compareTypes(const BufferLayout &refLayout, const BufferLayout &cmpLayout) const
2546*35238bceSAndroid Build Coastguard Worker {
2547*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2548*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2549*35238bceSAndroid Build Coastguard Worker int numBlocks = m_interface.getNumBlocks();
2550*35238bceSAndroid Build Coastguard Worker
2551*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2552*35238bceSAndroid Build Coastguard Worker {
2553*35238bceSAndroid Build Coastguard Worker const BufferBlock &block = m_interface.getBlock(blockNdx);
2554*35238bceSAndroid Build Coastguard Worker bool isArray = block.isArray();
2555*35238bceSAndroid Build Coastguard Worker int numInstances = isArray ? block.getArraySize() : 1;
2556*35238bceSAndroid Build Coastguard Worker
2557*35238bceSAndroid Build Coastguard Worker for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
2558*35238bceSAndroid Build Coastguard Worker {
2559*35238bceSAndroid Build Coastguard Worker std::ostringstream instanceName;
2560*35238bceSAndroid Build Coastguard Worker
2561*35238bceSAndroid Build Coastguard Worker instanceName << block.getBlockName();
2562*35238bceSAndroid Build Coastguard Worker if (isArray)
2563*35238bceSAndroid Build Coastguard Worker instanceName << "[" << instanceNdx << "]";
2564*35238bceSAndroid Build Coastguard Worker
2565*35238bceSAndroid Build Coastguard Worker int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.str().c_str());
2566*35238bceSAndroid Build Coastguard Worker
2567*35238bceSAndroid Build Coastguard Worker if (cmpBlockNdx < 0)
2568*35238bceSAndroid Build Coastguard Worker continue;
2569*35238bceSAndroid Build Coastguard Worker
2570*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];
2571*35238bceSAndroid Build Coastguard Worker
2572*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator ndxIter = cmpBlockLayout.activeVarIndices.begin();
2573*35238bceSAndroid Build Coastguard Worker ndxIter != cmpBlockLayout.activeVarIndices.end(); ndxIter++)
2574*35238bceSAndroid Build Coastguard Worker {
2575*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &cmpEntry = cmpLayout.bufferVars[*ndxIter];
2576*35238bceSAndroid Build Coastguard Worker int refEntryNdx = refLayout.getVariableIndex(cmpEntry.name.c_str());
2577*35238bceSAndroid Build Coastguard Worker
2578*35238bceSAndroid Build Coastguard Worker if (refEntryNdx < 0)
2579*35238bceSAndroid Build Coastguard Worker {
2580*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer variable '" << cmpEntry.name
2581*35238bceSAndroid Build Coastguard Worker << "' not found in reference layout" << TestLog::EndMessage;
2582*35238bceSAndroid Build Coastguard Worker isOk = false;
2583*35238bceSAndroid Build Coastguard Worker continue;
2584*35238bceSAndroid Build Coastguard Worker }
2585*35238bceSAndroid Build Coastguard Worker
2586*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &refEntry = refLayout.bufferVars[refEntryNdx];
2587*35238bceSAndroid Build Coastguard Worker
2588*35238bceSAndroid Build Coastguard Worker if (refEntry.type != cmpEntry.type)
2589*35238bceSAndroid Build Coastguard Worker {
2590*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Buffer variable type mismatch in '" << refEntry.name << "':\n"
2591*35238bceSAndroid Build Coastguard Worker << " expected: " << glu::getDataTypeName(refEntry.type) << "\n"
2592*35238bceSAndroid Build Coastguard Worker << " got: " << glu::getDataTypeName(cmpEntry.type) << TestLog::EndMessage;
2593*35238bceSAndroid Build Coastguard Worker isOk = false;
2594*35238bceSAndroid Build Coastguard Worker }
2595*35238bceSAndroid Build Coastguard Worker
2596*35238bceSAndroid Build Coastguard Worker if (refEntry.arraySize < cmpEntry.arraySize)
2597*35238bceSAndroid Build Coastguard Worker {
2598*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Invalid array size in '" << refEntry.name
2599*35238bceSAndroid Build Coastguard Worker << "': expected <= " << refEntry.arraySize << TestLog::EndMessage;
2600*35238bceSAndroid Build Coastguard Worker isOk = false;
2601*35238bceSAndroid Build Coastguard Worker }
2602*35238bceSAndroid Build Coastguard Worker
2603*35238bceSAndroid Build Coastguard Worker if (refEntry.topLevelArraySize < cmpEntry.topLevelArraySize)
2604*35238bceSAndroid Build Coastguard Worker {
2605*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Invalid top-level array size in '" << refEntry.name
2606*35238bceSAndroid Build Coastguard Worker << "': expected <= " << refEntry.topLevelArraySize << TestLog::EndMessage;
2607*35238bceSAndroid Build Coastguard Worker isOk = false;
2608*35238bceSAndroid Build Coastguard Worker }
2609*35238bceSAndroid Build Coastguard Worker }
2610*35238bceSAndroid Build Coastguard Worker }
2611*35238bceSAndroid Build Coastguard Worker }
2612*35238bceSAndroid Build Coastguard Worker
2613*35238bceSAndroid Build Coastguard Worker return isOk;
2614*35238bceSAndroid Build Coastguard Worker }
2615*35238bceSAndroid Build Coastguard Worker
checkLayoutIndices(const BufferLayout & layout) const2616*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::checkLayoutIndices(const BufferLayout &layout) const
2617*35238bceSAndroid Build Coastguard Worker {
2618*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2619*35238bceSAndroid Build Coastguard Worker int numVars = (int)layout.bufferVars.size();
2620*35238bceSAndroid Build Coastguard Worker int numBlocks = (int)layout.blocks.size();
2621*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2622*35238bceSAndroid Build Coastguard Worker
2623*35238bceSAndroid Build Coastguard Worker // Check variable block indices.
2624*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < numVars; varNdx++)
2625*35238bceSAndroid Build Coastguard Worker {
2626*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &bufVar = layout.bufferVars[varNdx];
2627*35238bceSAndroid Build Coastguard Worker
2628*35238bceSAndroid Build Coastguard Worker if (bufVar.blockNdx < 0 || !deInBounds32(bufVar.blockNdx, 0, numBlocks))
2629*35238bceSAndroid Build Coastguard Worker {
2630*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Invalid block index in buffer variable '" << bufVar.name << "'"
2631*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
2632*35238bceSAndroid Build Coastguard Worker isOk = false;
2633*35238bceSAndroid Build Coastguard Worker }
2634*35238bceSAndroid Build Coastguard Worker }
2635*35238bceSAndroid Build Coastguard Worker
2636*35238bceSAndroid Build Coastguard Worker // Check active variables.
2637*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
2638*35238bceSAndroid Build Coastguard Worker {
2639*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &block = layout.blocks[blockNdx];
2640*35238bceSAndroid Build Coastguard Worker
2641*35238bceSAndroid Build Coastguard Worker for (vector<int>::const_iterator varNdxIter = block.activeVarIndices.begin();
2642*35238bceSAndroid Build Coastguard Worker varNdxIter != block.activeVarIndices.end(); varNdxIter++)
2643*35238bceSAndroid Build Coastguard Worker {
2644*35238bceSAndroid Build Coastguard Worker if (!deInBounds32(*varNdxIter, 0, numVars))
2645*35238bceSAndroid Build Coastguard Worker {
2646*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Invalid active variable index " << *varNdxIter << " in block '"
2647*35238bceSAndroid Build Coastguard Worker << block.name << "'" << TestLog::EndMessage;
2648*35238bceSAndroid Build Coastguard Worker isOk = false;
2649*35238bceSAndroid Build Coastguard Worker }
2650*35238bceSAndroid Build Coastguard Worker }
2651*35238bceSAndroid Build Coastguard Worker }
2652*35238bceSAndroid Build Coastguard Worker
2653*35238bceSAndroid Build Coastguard Worker return isOk;
2654*35238bceSAndroid Build Coastguard Worker }
2655*35238bceSAndroid Build Coastguard Worker
checkLayoutBounds(const BufferLayout & layout) const2656*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::checkLayoutBounds(const BufferLayout &layout) const
2657*35238bceSAndroid Build Coastguard Worker {
2658*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
2659*35238bceSAndroid Build Coastguard Worker const int numVars = (int)layout.bufferVars.size();
2660*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2661*35238bceSAndroid Build Coastguard Worker
2662*35238bceSAndroid Build Coastguard Worker for (int varNdx = 0; varNdx < numVars; varNdx++)
2663*35238bceSAndroid Build Coastguard Worker {
2664*35238bceSAndroid Build Coastguard Worker const BufferVarLayoutEntry &var = layout.bufferVars[varNdx];
2665*35238bceSAndroid Build Coastguard Worker
2666*35238bceSAndroid Build Coastguard Worker if (var.blockNdx < 0 || isUnsizedArray(var))
2667*35238bceSAndroid Build Coastguard Worker continue;
2668*35238bceSAndroid Build Coastguard Worker
2669*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &block = layout.blocks[var.blockNdx];
2670*35238bceSAndroid Build Coastguard Worker const bool isMatrix = glu::isDataTypeMatrix(var.type);
2671*35238bceSAndroid Build Coastguard Worker const int numVecs = isMatrix ? (var.isRowMajor ? glu::getDataTypeMatrixNumRows(var.type) :
2672*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumColumns(var.type)) :
2673*35238bceSAndroid Build Coastguard Worker 1;
2674*35238bceSAndroid Build Coastguard Worker const int numComps = isMatrix ? (var.isRowMajor ? glu::getDataTypeMatrixNumColumns(var.type) :
2675*35238bceSAndroid Build Coastguard Worker glu::getDataTypeMatrixNumRows(var.type)) :
2676*35238bceSAndroid Build Coastguard Worker glu::getDataTypeScalarSize(var.type);
2677*35238bceSAndroid Build Coastguard Worker const int numElements = var.arraySize;
2678*35238bceSAndroid Build Coastguard Worker const int topLevelSize = var.topLevelArraySize;
2679*35238bceSAndroid Build Coastguard Worker const int arrayStride = var.arrayStride;
2680*35238bceSAndroid Build Coastguard Worker const int topLevelStride = var.topLevelArrayStride;
2681*35238bceSAndroid Build Coastguard Worker const int compSize = sizeof(uint32_t);
2682*35238bceSAndroid Build Coastguard Worker const int vecSize = numComps * compSize;
2683*35238bceSAndroid Build Coastguard Worker
2684*35238bceSAndroid Build Coastguard Worker int minOffset = 0;
2685*35238bceSAndroid Build Coastguard Worker int maxOffset = 0;
2686*35238bceSAndroid Build Coastguard Worker
2687*35238bceSAndroid Build Coastguard Worker // For negative strides.
2688*35238bceSAndroid Build Coastguard Worker minOffset = de::min(minOffset, (numVecs - 1) * var.matrixStride);
2689*35238bceSAndroid Build Coastguard Worker minOffset = de::min(minOffset, (numElements - 1) * arrayStride);
2690*35238bceSAndroid Build Coastguard Worker minOffset = de::min(minOffset, (topLevelSize - 1) * topLevelStride + (numElements - 1) * arrayStride +
2691*35238bceSAndroid Build Coastguard Worker (numVecs - 1) * var.matrixStride);
2692*35238bceSAndroid Build Coastguard Worker
2693*35238bceSAndroid Build Coastguard Worker maxOffset = de::max(maxOffset, vecSize);
2694*35238bceSAndroid Build Coastguard Worker maxOffset = de::max(maxOffset, (numVecs - 1) * var.matrixStride + vecSize);
2695*35238bceSAndroid Build Coastguard Worker maxOffset = de::max(maxOffset, (numElements - 1) * arrayStride + vecSize);
2696*35238bceSAndroid Build Coastguard Worker maxOffset = de::max(maxOffset, (topLevelSize - 1) * topLevelStride + (numElements - 1) * arrayStride + vecSize);
2697*35238bceSAndroid Build Coastguard Worker maxOffset = de::max(maxOffset, (topLevelSize - 1) * topLevelStride + (numElements - 1) * arrayStride +
2698*35238bceSAndroid Build Coastguard Worker (numVecs - 1) * var.matrixStride + vecSize);
2699*35238bceSAndroid Build Coastguard Worker
2700*35238bceSAndroid Build Coastguard Worker if (var.offset + minOffset < 0 || var.offset + maxOffset > block.size)
2701*35238bceSAndroid Build Coastguard Worker {
2702*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Error: Variable '" << var.name << "' out of block bounds"
2703*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
2704*35238bceSAndroid Build Coastguard Worker isOk = false;
2705*35238bceSAndroid Build Coastguard Worker }
2706*35238bceSAndroid Build Coastguard Worker }
2707*35238bceSAndroid Build Coastguard Worker
2708*35238bceSAndroid Build Coastguard Worker return isOk;
2709*35238bceSAndroid Build Coastguard Worker }
2710*35238bceSAndroid Build Coastguard Worker
checkIndexQueries(uint32_t program,const BufferLayout & layout) const2711*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::checkIndexQueries(uint32_t program, const BufferLayout &layout) const
2712*35238bceSAndroid Build Coastguard Worker {
2713*35238bceSAndroid Build Coastguard Worker tcu::TestLog &log = m_testCtx.getLog();
2714*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
2715*35238bceSAndroid Build Coastguard Worker bool allOk = true;
2716*35238bceSAndroid Build Coastguard Worker
2717*35238bceSAndroid Build Coastguard Worker // \note Spec mandates that buffer blocks are assigned consecutive locations from 0.
2718*35238bceSAndroid Build Coastguard Worker // BlockLayoutEntries are stored in that order in UniformLayout.
2719*35238bceSAndroid Build Coastguard Worker for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++)
2720*35238bceSAndroid Build Coastguard Worker {
2721*35238bceSAndroid Build Coastguard Worker const BlockLayoutEntry &block = layout.blocks[blockNdx];
2722*35238bceSAndroid Build Coastguard Worker const int queriedNdx = gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, block.name.c_str());
2723*35238bceSAndroid Build Coastguard Worker
2724*35238bceSAndroid Build Coastguard Worker if (queriedNdx != blockNdx)
2725*35238bceSAndroid Build Coastguard Worker {
2726*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "ERROR: glGetProgramResourceIndex(" << block.name << ") returned " << queriedNdx
2727*35238bceSAndroid Build Coastguard Worker << ", expected " << blockNdx << "!" << TestLog::EndMessage;
2728*35238bceSAndroid Build Coastguard Worker allOk = false;
2729*35238bceSAndroid Build Coastguard Worker }
2730*35238bceSAndroid Build Coastguard Worker
2731*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex()");
2732*35238bceSAndroid Build Coastguard Worker }
2733*35238bceSAndroid Build Coastguard Worker
2734*35238bceSAndroid Build Coastguard Worker return allOk;
2735*35238bceSAndroid Build Coastguard Worker }
2736*35238bceSAndroid Build Coastguard Worker
execute(uint32_t program)2737*35238bceSAndroid Build Coastguard Worker bool SSBOLayoutCase::execute(uint32_t program)
2738*35238bceSAndroid Build Coastguard Worker {
2739*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
2740*35238bceSAndroid Build Coastguard Worker const uint32_t numPassedLoc = gl.getProgramResourceIndex(program, GL_UNIFORM, "ac_numPassed");
2741*35238bceSAndroid Build Coastguard Worker const glu::InterfaceVariableInfo acVarInfo =
2742*35238bceSAndroid Build Coastguard Worker numPassedLoc != GL_INVALID_INDEX ? glu::getProgramInterfaceVariableInfo(gl, program, GL_UNIFORM, numPassedLoc) :
2743*35238bceSAndroid Build Coastguard Worker glu::InterfaceVariableInfo();
2744*35238bceSAndroid Build Coastguard Worker const glu::InterfaceBlockInfo acBufferInfo =
2745*35238bceSAndroid Build Coastguard Worker acVarInfo.atomicCounterBufferIndex != GL_INVALID_INDEX ?
2746*35238bceSAndroid Build Coastguard Worker glu::getProgramInterfaceBlockInfo(gl, program, GL_ATOMIC_COUNTER_BUFFER,
2747*35238bceSAndroid Build Coastguard Worker acVarInfo.atomicCounterBufferIndex) :
2748*35238bceSAndroid Build Coastguard Worker glu::InterfaceBlockInfo();
2749*35238bceSAndroid Build Coastguard Worker const glu::Buffer acBuffer(m_renderCtx);
2750*35238bceSAndroid Build Coastguard Worker bool isOk = true;
2751*35238bceSAndroid Build Coastguard Worker
2752*35238bceSAndroid Build Coastguard Worker if (numPassedLoc == GL_INVALID_INDEX)
2753*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("No location for ac_numPassed found");
2754*35238bceSAndroid Build Coastguard Worker
2755*35238bceSAndroid Build Coastguard Worker if (acBufferInfo.index == GL_INVALID_INDEX)
2756*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("ac_numPassed buffer index is GL_INVALID_INDEX");
2757*35238bceSAndroid Build Coastguard Worker
2758*35238bceSAndroid Build Coastguard Worker if (acBufferInfo.dataSize == 0)
2759*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("ac_numPassed buffer size = 0");
2760*35238bceSAndroid Build Coastguard Worker
2761*35238bceSAndroid Build Coastguard Worker // Initialize atomic counter buffer.
2762*35238bceSAndroid Build Coastguard Worker {
2763*35238bceSAndroid Build Coastguard Worker vector<uint8_t> emptyData(acBufferInfo.dataSize, 0);
2764*35238bceSAndroid Build Coastguard Worker
2765*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, *acBuffer);
2766*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, (glw::GLsizeiptr)emptyData.size(), &emptyData[0], GL_STATIC_READ);
2767*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, acBufferInfo.index, *acBuffer);
2768*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Setting up buffer for ac_numPassed failed");
2769*35238bceSAndroid Build Coastguard Worker }
2770*35238bceSAndroid Build Coastguard Worker
2771*35238bceSAndroid Build Coastguard Worker gl.useProgram(program);
2772*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(1, 1, 1);
2773*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute() failed");
2774*35238bceSAndroid Build Coastguard Worker
2775*35238bceSAndroid Build Coastguard Worker // Read back ac_numPassed data.
2776*35238bceSAndroid Build Coastguard Worker {
2777*35238bceSAndroid Build Coastguard Worker const void *mapPtr = gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, acBufferInfo.dataSize, GL_MAP_READ_BIT);
2778*35238bceSAndroid Build Coastguard Worker const int refCount = 1;
2779*35238bceSAndroid Build Coastguard Worker int resCount = 0;
2780*35238bceSAndroid Build Coastguard Worker
2781*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER) failed");
2782*35238bceSAndroid Build Coastguard Worker TCU_CHECK(mapPtr);
2783*35238bceSAndroid Build Coastguard Worker
2784*35238bceSAndroid Build Coastguard Worker resCount = *(const int *)((const uint8_t *)mapPtr + acVarInfo.offset);
2785*35238bceSAndroid Build Coastguard Worker
2786*35238bceSAndroid Build Coastguard Worker gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2787*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER) failed");
2788*35238bceSAndroid Build Coastguard Worker
2789*35238bceSAndroid Build Coastguard Worker if (refCount != resCount)
2790*35238bceSAndroid Build Coastguard Worker {
2791*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "ERROR: ac_numPassed = " << resCount << ", expected " << refCount
2792*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
2793*35238bceSAndroid Build Coastguard Worker isOk = false;
2794*35238bceSAndroid Build Coastguard Worker }
2795*35238bceSAndroid Build Coastguard Worker }
2796*35238bceSAndroid Build Coastguard Worker
2797*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Shader execution failed");
2798*35238bceSAndroid Build Coastguard Worker
2799*35238bceSAndroid Build Coastguard Worker return isOk;
2800*35238bceSAndroid Build Coastguard Worker }
2801*35238bceSAndroid Build Coastguard Worker
2802*35238bceSAndroid Build Coastguard Worker } // namespace gles31
2803*35238bceSAndroid Build Coastguard Worker } // namespace deqp
2804