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