Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / ubo / vktUniformBlockCase.hpp
1 #ifndef _VKTUNIFORMBLOCKCASE_HPP
2 #define _VKTUNIFORMBLOCKCASE_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 Uniform block tests.
25  *//*--------------------------------------------------------------------*/
26
27 #include "deSharedPtr.hpp"
28 #include "vktTestCase.hpp"
29 #include "tcuDefs.hpp"
30 #include "gluShaderUtil.hpp"
31
32 #include <map>
33
34 namespace vkt
35 {
36 namespace ubo
37 {
38
39 // Uniform block details.
40
41 enum UniformFlags
42 {
43         PRECISION_LOW           = (1<<0),
44         PRECISION_MEDIUM        = (1<<1),
45         PRECISION_HIGH          = (1<<2),
46         PRECISION_MASK          = PRECISION_LOW|PRECISION_MEDIUM|PRECISION_HIGH,
47
48         LAYOUT_SHARED           = (1<<3),
49         LAYOUT_PACKED           = (1<<4),
50         LAYOUT_STD140           = (1<<5),
51         LAYOUT_ROW_MAJOR        = (1<<6),
52         LAYOUT_COLUMN_MAJOR     = (1<<7),       //!< \note Lack of both flags means column-major matrix.
53         LAYOUT_OFFSET           = (1<<8),
54         LAYOUT_STD430           = (1<<9),
55         LAYOUT_SCALAR           = (1<<10),
56         LAYOUT_MASK                     = LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_STD430|LAYOUT_SCALAR|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_OFFSET,
57
58         DECLARE_VERTEX          = (1<<11),
59         DECLARE_FRAGMENT        = (1<<12),
60         DECLARE_BOTH            = DECLARE_VERTEX|DECLARE_FRAGMENT,
61
62         UNUSED_VERTEX           = (1<<13),      //!< Uniform or struct member is not read in vertex shader.
63         UNUSED_FRAGMENT         = (1<<14),      //!< Uniform or struct member is not read in fragment shader.
64         UNUSED_BOTH                     = UNUSED_VERTEX|UNUSED_FRAGMENT,
65
66         LAYOUT_16BIT_STORAGE= (1<<15),  //!< Support VK_KHR_16bit_storage extension
67         LAYOUT_8BIT_STORAGE     = (1<<16),  //!< Support VK_KHR_8bit_storage extension
68
69         LAYOUT_DESCRIPTOR_INDEXING = (1 << 17),  //!< Support VK_KHR_descriptor_indexing extension
70 };
71
72 enum MatrixLoadFlags
73 {
74         LOAD_FULL_MATRIX                = 0,
75         LOAD_MATRIX_COMPONENTS  = 1,
76 };
77
78 class StructType;
79
80 class VarType
81 {
82 public:
83                                                 VarType                 (void);
84                                                 VarType                 (const VarType& other);
85                                                 VarType                 (glu::DataType basicType, deUint32 flags);
86                                                 VarType                 (const VarType& elementType, int arraySize);
87         explicit                        VarType                 (const StructType* structPtr, deUint32 flags = 0u);
88                                                 ~VarType                (void);
89
90         bool                            isBasicType             (void) const    { return m_type == TYPE_BASIC;  }
91         bool                            isArrayType             (void) const    { return m_type == TYPE_ARRAY;  }
92         bool                            isStructType    (void) const    { return m_type == TYPE_STRUCT; }
93
94         deUint32                        getFlags                (void) const    { return m_flags;                                       }
95         glu::DataType           getBasicType    (void) const    { return m_data.basicType;                      }
96
97         const VarType&          getElementType  (void) const    { return *m_data.array.elementType;     }
98         int                                     getArraySize    (void) const    { return m_data.array.size;                     }
99
100         const StructType&       getStruct               (void) const    { return *m_data.structPtr;                     }
101         const StructType*       getStructPtr    (void) const    { DE_ASSERT(isStructType()); return m_data.structPtr;                   }
102
103         VarType&                        operator=               (const VarType& other);
104
105 private:
106         enum Type
107         {
108                 TYPE_BASIC,
109                 TYPE_ARRAY,
110                 TYPE_STRUCT,
111
112                 TYPE_LAST
113         };
114
115         Type                            m_type;
116         deUint32                        m_flags;
117         union Data
118         {
119                 glu::DataType           basicType;
120                 struct
121                 {
122                         VarType*                elementType;
123                         int                             size;
124                 } array;
125                 const StructType*       structPtr;
126
127                 Data (void)
128                 {
129                         array.elementType       = DE_NULL;
130                         array.size                      = 0;
131                 }
132         } m_data;
133 };
134
135 class StructMember
136 {
137 public:
138                                                 StructMember    (const std::string& name, const VarType& type, deUint32 flags)
139                                                         : m_name(name), m_type(type), m_flags(flags)
140                                                 {}
141                                                 StructMember    (void)
142                                                         : m_flags(0)
143                                                 {}
144
145         const std::string&      getName                 (void) const { return m_name;   }
146         const VarType&          getType                 (void) const { return m_type;   }
147         deUint32                        getFlags                (void) const { return m_flags;  }
148
149 private:
150         std::string                     m_name;
151         VarType                         m_type;
152         deUint32                        m_flags;
153 };
154
155 class StructType
156 {
157 public:
158         typedef std::vector<StructMember>::iterator                     Iterator;
159         typedef std::vector<StructMember>::const_iterator       ConstIterator;
160
161                                                                 StructType              (const std::string& typeName) : m_typeName(typeName) {}
162                                                                 ~StructType             (void) {}
163
164         const std::string&                      getTypeName             (void) const    { return m_typeName;                    }
165         bool                                            hasTypeName             (void) const    { return !m_typeName.empty();   }
166
167         inline Iterator                         begin                   (void)                  { return m_members.begin();             }
168         inline ConstIterator            begin                   (void) const    { return m_members.begin();             }
169         inline Iterator                         end                             (void)                  { return m_members.end();               }
170         inline ConstIterator            end                             (void) const    { return m_members.end();               }
171
172         void                                            addMember               (const std::string& name, const VarType& type, deUint32 flags = 0);
173
174 private:
175         std::string                                     m_typeName;
176         std::vector<StructMember>       m_members;
177 };
178
179 class Uniform
180 {
181 public:
182                                                 Uniform                 (const std::string& name, const VarType& type, deUint32 flags = 0);
183
184         const std::string&      getName                 (void) const { return m_name;   }
185         const VarType&          getType                 (void) const { return m_type;   }
186         deUint32                        getFlags                (void) const { return m_flags;  }
187
188 private:
189         std::string                     m_name;
190         VarType                         m_type;
191         deUint32                        m_flags;
192 };
193
194 class UniformBlock
195 {
196 public:
197         typedef std::vector<Uniform>::iterator                  Iterator;
198         typedef std::vector<Uniform>::const_iterator    ConstIterator;
199
200                                                         UniformBlock            (const std::string& blockName);
201
202         const std::string&              getBlockName            (void) const { return m_blockName;              }
203         const std::string&              getInstanceName         (void) const { return m_instanceName;   }
204         bool                                    hasInstanceName         (void) const { return !m_instanceName.empty();  }
205         bool                                    isArray                         (void) const { return m_arraySize > 0;                  }
206         int                                             getArraySize            (void) const { return m_arraySize;                              }
207         deUint32                                getFlags                        (void) const { return m_flags;                                  }
208
209         void                                    setInstanceName         (const std::string& name)       { m_instanceName = name;                        }
210         void                                    setFlags                        (deUint32 flags)                        { m_flags = flags;                                      }
211         void                                    setArraySize            (int arraySize)                         { m_arraySize = arraySize;                      }
212         void                                    addUniform                      (const Uniform& uniform)        { m_uniforms.push_back(uniform);        }
213
214         inline Iterator                 begin                           (void)                  { return m_uniforms.begin();    }
215         inline ConstIterator    begin                           (void) const    { return m_uniforms.begin();    }
216         inline Iterator                 end                                     (void)                  { return m_uniforms.end();              }
217         inline ConstIterator    end                                     (void) const    { return m_uniforms.end();              }
218
219 private:
220         std::string                             m_blockName;
221         std::string                             m_instanceName;
222         std::vector<Uniform>    m_uniforms;
223         int                                             m_arraySize;    //!< Array size or 0 if not interface block array.
224         deUint32                                m_flags;
225 };
226
227 typedef de::SharedPtr<StructType>       StructTypeSP;
228 typedef de::SharedPtr<UniformBlock>     UniformBlockSP;
229
230 class ShaderInterface
231 {
232 public:
233                                                                 ShaderInterface                 (void);
234                                                                 ~ShaderInterface                (void);
235
236         StructType&                                     allocStruct                             (const std::string& name);
237         void                                            getNamedStructs                 (std::vector<const StructType*>& structs) const;
238
239         UniformBlock&                           allocBlock                              (const std::string& name);
240
241         int                                                     getNumUniformBlocks             (void) const    { return (int)m_uniformBlocks.size();   }
242         const UniformBlock&                     getUniformBlock                 (int ndx) const { return *m_uniformBlocks[ndx];                 }
243         bool                                            usesBlockLayout                 (UniformFlags layoutFlag) const;
244
245 private:
246         std::vector<StructTypeSP>               m_structs;
247         std::vector<UniformBlockSP>             m_uniformBlocks;
248 };
249
250 struct BlockLayoutEntry
251 {
252         BlockLayoutEntry (void)
253                 : size                                  (0)
254                 , blockDeclarationNdx   (-1)
255                 , bindingNdx                    (-1)
256                 , instanceNdx                   (-1)
257         {
258         }
259
260         std::string                     name;
261         int                                     size;
262         std::vector<int>        activeUniformIndices;
263         int                                     blockDeclarationNdx;
264         int                                     bindingNdx;
265         int                                     instanceNdx;
266 };
267
268 struct UniformLayoutEntry
269 {
270         UniformLayoutEntry (void)
271                 : type                  (glu::TYPE_LAST)
272                 , size                  (0)
273                 , blockNdx              (-1)
274                 , offset                (-1)
275                 , arraySize             (-1)
276                 , arrayStride   (-1)
277                 , matrixStride  (-1)
278                 , topLevelArraySize             (-1)
279                 , topLevelArrayStride   (-1)
280                 , isRowMajor    (false)
281                 , instanceNdx   (0)
282         {
283         }
284
285         std::string                     name;
286         glu::DataType           type;
287         int                                     size;
288         int                                     blockNdx;
289         int                                     offset;
290         int                                     arraySize;
291         int                                     arrayStride;
292         int                                     matrixStride;
293         int                                     topLevelArraySize;
294         int                                     topLevelArrayStride;
295         bool                            isRowMajor;
296         int                                     instanceNdx;
297 };
298
299 class UniformLayout
300 {
301 public:
302         std::vector<BlockLayoutEntry>           blocks;
303         std::vector<UniformLayoutEntry>         uniforms;
304
305         int                                                                     getUniformLayoutIndex   (int blockDeclarationNdx, const std::string& name) const;
306         int                                                                     getBlockLayoutIndex             (int blockDeclarationNdx, int instanceNdx) const;
307 };
308
309 class UniformBlockCase : public vkt::TestCase
310 {
311 public:
312         enum BufferMode
313         {
314                 BUFFERMODE_SINGLE = 0,  //!< Single buffer shared between uniform blocks.
315                 BUFFERMODE_PER_BLOCK,   //!< Per-block buffers
316
317                 BUFFERMODE_LAST
318         };
319
320                                                                 UniformBlockCase                        (tcu::TestContext&      testCtx,
321                                                                                                                          const std::string&     name,
322                                                                                                                          const std::string&     description,
323                                                                                                                          BufferMode                     bufferMode,
324                                                                                                                          MatrixLoadFlags        matrixLoadFlag,
325                                                                                                                          bool                           shuffleUniformMembers = false);
326                                                                 ~UniformBlockCase                       (void);
327
328         virtual void                            delayedInit                                     (void);
329         virtual void                            initPrograms                            (vk::SourceCollections& programCollection) const;
330         virtual TestInstance*           createInstance                          (Context& context) const;
331         bool                                            usesBlockLayout                         (UniformFlags layoutFlag) const { return m_interface.usesBlockLayout(layoutFlag); }
332
333 protected:
334         BufferMode                                      m_bufferMode;
335         ShaderInterface                         m_interface;
336         MatrixLoadFlags                         m_matrixLoadFlag;
337         const bool                                      m_shuffleUniformMembers;        //!< Used with explicit offsets to test out of order member offsets
338
339 private:
340         std::string                                     m_vertShaderSource;
341         std::string                                     m_fragShaderSource;
342
343         std::vector<deUint8>            m_data;                                         //!< Data.
344         std::map<int, void*>            m_blockPointers;                        //!< Reference block pointers.
345         UniformLayout                           m_uniformLayout;                        //!< std140 layout.
346 };
347
348 } // ubo
349 } // vkt
350
351 #endif // _VKTUNIFORMBLOCKCASE_HPP