xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _VKTSSBOLAYOUTCASE_HPP
2 #define _VKTSSBOLAYOUTCASE_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2015 The Khronos Group Inc.
8  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief SSBO layout tests.
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktTestCase.hpp"
28 #include "tcuDefs.hpp"
29 #include "gluShaderUtil.hpp"
30 #include "gluVarType.hpp"
31 
32 namespace vkt
33 {
34 
35 namespace ssbo
36 {
37 
38 enum BufferVarFlags
39 {
40     LAYOUT_STD140       = (1 << 0),
41     LAYOUT_STD430       = (1 << 1),
42     LAYOUT_ROW_MAJOR    = (1 << 2),
43     LAYOUT_COLUMN_MAJOR = (1 << 3), //!< \note Lack of both flags means column-major matrix.
44     LAYOUT_SCALAR       = (1 << 4),
45     LAYOUT_MASK         = LAYOUT_STD430 | LAYOUT_STD140 | LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR | LAYOUT_SCALAR,
46 
47     // \todo [2013-10-14 pyry] Investigate adding these.
48     /*    QUALIFIER_COHERENT = (1<<4),
49         QUALIFIER_VOLATILE = (1<<5),
50         QUALIFIER_RESTRICT = (1<<6),
51         QUALIFIER_READONLY = (1<<7),
52         QUALIFIER_WRITEONLY = (1<<8),*/
53     ACCESS_READ                = (1 << 9),  //!< Buffer variable is read in the shader.
54     ACCESS_WRITE               = (1 << 10), //!< Buffer variable is written in the shader.
55     LAYOUT_RELAXED             = (1 << 11), //!< Support VK_KHR_relaxed_block_layout extension
56     LAYOUT_16BIT_STORAGE       = (1 << 12), //!< Support VK_KHR_16bit_storage extension
57     LAYOUT_8BIT_STORAGE        = (1 << 13), //!< Support VK_KHR_8bit_storage extension
58     LAYOUT_DESCRIPTOR_INDEXING = (1 << 14), //!< Support VK_KHR_descriptor_indexing extension
59 };
60 
61 enum MatrixLoadFlags
62 {
63     LOAD_FULL_MATRIX       = 0,
64     LOAD_MATRIX_COMPONENTS = 1,
65 };
66 
67 enum MatrixStoreFlags
68 {
69     STORE_FULL_MATRIX    = 0,
70     STORE_MATRIX_COLUMNS = 1,
71 };
72 
73 class BufferVar
74 {
75 public:
76     BufferVar(const char *name, const glu::VarType &type, uint32_t flags);
77 
getName(void) const78     const char *getName(void) const
79     {
80         return m_name.c_str();
81     }
getType(void) const82     const glu::VarType &getType(void) const
83     {
84         return m_type;
85     }
getFlags(void) const86     uint32_t getFlags(void) const
87     {
88         return m_flags;
89     }
getOffset(void) const90     uint32_t getOffset(void) const
91     {
92         return m_offset;
93     }
94 
setOffset(uint32_t offset)95     void setOffset(uint32_t offset)
96     {
97         m_offset = offset;
98     }
99 
100 private:
101     std::string m_name;
102     glu::VarType m_type;
103     uint32_t m_flags;
104     uint32_t m_offset;
105 };
106 
107 class BufferBlock
108 {
109 public:
110     typedef std::vector<BufferVar>::iterator iterator;
111     typedef std::vector<BufferVar>::const_iterator const_iterator;
112 
113     BufferBlock(const char *blockName);
114 
getBlockName(void) const115     const char *getBlockName(void) const
116     {
117         return m_blockName.c_str();
118     }
getInstanceName(void) const119     const char *getInstanceName(void) const
120     {
121         return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();
122     }
isArray(void) const123     bool isArray(void) const
124     {
125         return m_arraySize > 0;
126     }
getArraySize(void) const127     int getArraySize(void) const
128     {
129         return m_arraySize;
130     }
getFlags(void) const131     uint32_t getFlags(void) const
132     {
133         return m_flags;
134     }
135 
setInstanceName(const char * name)136     void setInstanceName(const char *name)
137     {
138         m_instanceName = name;
139     }
setFlags(uint32_t flags)140     void setFlags(uint32_t flags)
141     {
142         m_flags = flags;
143     }
addMember(const BufferVar & var)144     void addMember(const BufferVar &var)
145     {
146         m_variables.push_back(var);
147     }
148     void setArraySize(int arraySize);
149 
getLastUnsizedArraySize(int instanceNdx) const150     int getLastUnsizedArraySize(int instanceNdx) const
151     {
152         return m_lastUnsizedArraySizes[instanceNdx];
153     }
setLastUnsizedArraySize(int instanceNdx,int size)154     void setLastUnsizedArraySize(int instanceNdx, int size)
155     {
156         m_lastUnsizedArraySizes[instanceNdx] = size;
157     }
158 
begin(void)159     inline iterator begin(void)
160     {
161         return m_variables.begin();
162     }
begin(void) const163     inline const_iterator begin(void) const
164     {
165         return m_variables.begin();
166     }
end(void)167     inline iterator end(void)
168     {
169         return m_variables.end();
170     }
end(void) const171     inline const_iterator end(void) const
172     {
173         return m_variables.end();
174     }
175 
176 private:
177     std::string m_blockName;
178     std::string m_instanceName;
179     std::vector<BufferVar> m_variables;
180     int m_arraySize;                          //!< Array size or 0 if not interface block array.
181     std::vector<int> m_lastUnsizedArraySizes; //!< Sizes of last unsized array element, can be different per instance.
182     uint32_t m_flags;
183 };
184 
185 class ShaderInterface
186 {
187 public:
188     ShaderInterface(void);
189     ~ShaderInterface(void);
190 
191     glu::StructType &allocStruct(const char *name);
192     const glu::StructType *findStruct(const char *name) const;
193     void getNamedStructs(std::vector<const glu::StructType *> &structs) const;
194 
195     BufferBlock &allocBlock(const char *name);
196 
getNumBlocks(void) const197     int getNumBlocks(void) const
198     {
199         return (int)m_bufferBlocks.size();
200     }
getBlock(int ndx) const201     const BufferBlock &getBlock(int ndx) const
202     {
203         return *m_bufferBlocks[ndx];
204     }
getBlock(int ndx)205     BufferBlock &getBlock(int ndx)
206     {
207         return *m_bufferBlocks[ndx];
208     }
209 
210 private:
211     ShaderInterface(const ShaderInterface &);
212     ShaderInterface &operator=(const ShaderInterface &);
213 
214     std::vector<glu::StructType *> m_structs;
215     std::vector<BufferBlock *> m_bufferBlocks;
216 };
217 
218 struct BufferVarLayoutEntry
219 {
BufferVarLayoutEntryvkt::ssbo::BufferVarLayoutEntry220     BufferVarLayoutEntry(void)
221         : type(glu::TYPE_LAST)
222         , blockNdx(-1)
223         , offset(-1)
224         , arraySize(-1)
225         , arrayStride(-1)
226         , matrixStride(-1)
227         , topLevelArraySize(-1)
228         , topLevelArrayStride(-1)
229         , isRowMajor(false)
230     {
231     }
232 
233     std::string name;
234     glu::DataType type;
235     int blockNdx;
236     int offset;
237     int arraySize;
238     int arrayStride;
239     int matrixStride;
240     int topLevelArraySize;
241     int topLevelArrayStride;
242     bool isRowMajor;
243 };
244 
245 struct BlockLayoutEntry
246 {
BlockLayoutEntryvkt::ssbo::BlockLayoutEntry247     BlockLayoutEntry(void) : size(0)
248     {
249     }
250 
251     std::string name;
252     int size;
253     std::vector<int> activeVarIndices;
254 };
255 
256 class BufferLayout
257 {
258 public:
259     std::vector<BlockLayoutEntry> blocks;
260     std::vector<BufferVarLayoutEntry> bufferVars;
261 
262     int getVariableIndex(const std::string &name) const;
263     int getBlockIndex(const std::string &name) const;
264 };
265 
266 // BlockDataPtr
267 
268 struct BlockDataPtr
269 {
270     void *ptr;
271     int size; //!< Redundant, for debugging purposes.
272     int lastUnsizedArraySize;
273 
BlockDataPtrvkt::ssbo::BlockDataPtr274     BlockDataPtr(void *ptr_, int size_, int lastUnsizedArraySize_)
275         : ptr(ptr_)
276         , size(size_)
277         , lastUnsizedArraySize(lastUnsizedArraySize_)
278     {
279     }
280 
BlockDataPtrvkt::ssbo::BlockDataPtr281     BlockDataPtr(void) : ptr(DE_NULL), size(0), lastUnsizedArraySize(0)
282     {
283     }
284 };
285 
286 struct RefDataStorage
287 {
288     std::vector<uint8_t> data;
289     std::vector<BlockDataPtr> pointers;
290 };
291 
292 class SSBOLayoutCase : public vkt::TestCase
293 {
294 public:
295     enum BufferMode
296     {
297         BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks.
298         BUFFERMODE_PER_BLOCK,  //!< Per-block buffers
299 
300         BUFFERMODE_LAST
301     };
302 
303     SSBOLayoutCase(tcu::TestContext &testCtx, const char *name, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag,
304                    MatrixStoreFlags matrixStoreFlag, bool usePhysStorageBuffer);
305     virtual ~SSBOLayoutCase(void);
306 
307     virtual void delayedInit(void);
308     virtual void initPrograms(vk::SourceCollections &programCollection) const;
309     virtual TestInstance *createInstance(Context &context) const;
310     virtual void checkSupport(Context &context) const;
311 
312 protected:
313     BufferMode m_bufferMode;
314     ShaderInterface m_interface;
315     MatrixLoadFlags m_matrixLoadFlag;
316     MatrixStoreFlags m_matrixStoreFlag;
317     std::string m_computeShaderSrc;
318     bool m_usePhysStorageBuffer;
319 
320 private:
321     SSBOLayoutCase(const SSBOLayoutCase &);
322     SSBOLayoutCase &operator=(const SSBOLayoutCase &);
323 
324     BufferLayout m_refLayout;
325     RefDataStorage m_initialData; // Initial data stored in buffer.
326     RefDataStorage m_writeData;   // Data written by compute shader.
327 };
328 
329 } // namespace ssbo
330 } // namespace vkt
331 
332 #endif // _VKTSSBOLAYOUTCASE_HPP
333