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