Speed up hierarchy traversal, part 2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / transform_feedback / vktTransformFeedbackFuzzLayoutCase.hpp
1 #ifndef _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_HPP
2 #define _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_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  * Copyright (c) 2018 The Khronos Group Inc.
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  *//*!
24  * \file
25  * \brief Vulkan Transform Feedback Fuzz Layout Tests
26  *//*--------------------------------------------------------------------*/
27
28 #include "deSharedPtr.hpp"
29 #include "vktTestCase.hpp"
30 #include "tcuDefs.hpp"
31 #include "gluShaderUtil.hpp"
32
33 #include <map>
34
35 namespace vkt
36 {
37 namespace TransformFeedback
38 {
39
40 // Interface block details.
41
42 enum InterfaceFlags
43 {
44         PRECISION_LOW                   = (1<<0),
45         PRECISION_MEDIUM                = (1<<1),
46         PRECISION_HIGH                  = (1<<2),
47         PRECISION_MASK                  = PRECISION_LOW|PRECISION_MEDIUM|PRECISION_HIGH,
48
49         LAYOUT_XFBBUFFER                = (1<<3),
50         LAYOUT_XFBOFFSET                = (1<<4),
51         LAYOUT_XFBSTRIDE                = (1<<5),
52         LAYOUT_MASK                             = LAYOUT_XFBBUFFER|LAYOUT_XFBOFFSET|LAYOUT_XFBSTRIDE,
53
54         FIELD_UNASSIGNED                = (1<<6),       //!< Interface or struct member is not used in shader.
55         FIELD_MISSING                   = (1<<7),       //!< Interface or struct member will be commented out in shader.
56         FIELD_OPTIONS                   = FIELD_UNASSIGNED|FIELD_MISSING,
57 };
58
59 enum MatrixLoadFlags
60 {
61         LOAD_FULL_MATRIX                = 0,
62         LOAD_MATRIX_COMPONENTS  = 1,
63 };
64
65 enum TestStageFlags
66 {
67         TEST_STAGE_VERTEX       = 0,
68         TEST_STAGE_GEOMETRY     = 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)
132                                                         , m_type(type)
133                                                         , m_flags(flags)
134                                                 {}
135
136                                                 StructMember    (void)
137                                                         : m_flags(0)
138                                                 {}
139
140         const std::string&      getName                 (void) const { return m_name;   }
141         const VarType&          getType                 (void) const { return m_type;   }
142         deUint32                        getFlags                (void) const { return m_flags;  }
143
144 private:
145         std::string                     m_name;
146         VarType                         m_type;
147         deUint32                        m_flags;
148 };
149
150 class StructType
151 {
152 public:
153         typedef std::vector<StructMember>::iterator                     Iterator;
154         typedef std::vector<StructMember>::const_iterator       ConstIterator;
155
156                                                                 StructType              (const std::string& typeName) : m_typeName(typeName) {}
157                                                                 ~StructType             (void) {}
158
159         const std::string&                      getTypeName             (void) const    { return m_typeName;                    }
160         bool                                            hasTypeName             (void) const    { return !m_typeName.empty();   }
161
162         inline Iterator                         begin                   (void)                  { return m_members.begin();             }
163         inline ConstIterator            begin                   (void) const    { return m_members.begin();             }
164         inline Iterator                         end                             (void)                  { return m_members.end();               }
165         inline ConstIterator            end                             (void) const    { return m_members.end();               }
166
167         void                                            addMember               (const std::string& name, const VarType& type, deUint32 flags = 0);
168
169 private:
170         std::string                                     m_typeName;
171         std::vector<StructMember>       m_members;
172 };
173
174 class InterfaceBlockMember
175 {
176 public:
177                                                 InterfaceBlockMember    (const std::string& name, const VarType& type, deUint32 flags = 0);
178
179         const std::string&      getName                                 (void) const { return m_name;   }
180         const VarType&          getType                                 (void) const { return m_type;   }
181         deUint32                        getFlags                                (void) const { return m_flags;  }
182
183 private:
184         std::string                     m_name;
185         VarType                         m_type;
186         deUint32                        m_flags;
187 };
188
189 class InterfaceBlock
190 {
191 public:
192         typedef std::vector<InterfaceBlockMember>::iterator                     Iterator;
193         typedef std::vector<InterfaceBlockMember>::const_iterator       ConstIterator;
194
195                                                                                 InterfaceBlock          (const std::string& blockName);
196
197         const std::string&                                      getBlockName            (void) const { return m_blockName;                              }
198         bool                                                            hasInstanceName         (void) const { return !m_instanceName.empty();  }
199         const std::string&                                      getInstanceName         (void) const { return m_instanceName;                   }
200         bool                                                            isArray                         (void) const { return m_arraySize > 0;                  }
201         int                                                                     getArraySize            (void) const { return m_arraySize;                              }
202         int                                                                     getXfbBuffer            (void) const { return m_xfbBuffer;                              }
203         deUint32                                                        getFlags                        (void) const { return m_flags;                                  }
204
205         void                                                            setInstanceName         (const std::string& name)                                                       { m_instanceName = name;                                                }
206         void                                                            setFlags                        (deUint32 flags)                                                                        { m_flags = flags;                                                              }
207         void                                                            setFlag                         (deUint32 flag)                                                                         { m_flags |= flag;                                                              }
208         void                                                            setArraySize            (int arraySize)                                                                         { m_arraySize = arraySize;                                              }
209         void                                                            setXfbBuffer            (int xfbBuffer)                                                                         { m_xfbBuffer = xfbBuffer;                                              }
210         void                                                            addInterfaceMember      (const InterfaceBlockMember& interfaceBlockMember)      { m_members.push_back(interfaceBlockMember);    }
211
212         inline Iterator                                         begin                           (void)                  { return m_members.begin();             }
213         inline ConstIterator                            begin                           (void) const    { return m_members.begin();             }
214         inline Iterator                                         end                                     (void)                  { return m_members.end();               }
215         inline ConstIterator                            end                                     (void) const    { return m_members.end();               }
216
217 private:
218         std::string                                                     m_blockName;
219         std::string                                                     m_instanceName;
220         std::vector<InterfaceBlockMember>       m_members;
221         int                                                                     m_xfbBuffer;
222         int                                                                     m_arraySize;    //!< Array size or 0 if not interface block array.
223         deUint32                                                        m_flags;
224 };
225
226 typedef de::SharedPtr<StructType>               StructTypeSP;
227 typedef de::SharedPtr<InterfaceBlock>   InterfaceBlockSP;
228
229 class ShaderInterface
230 {
231 public:
232                                                                         ShaderInterface                         (void);
233                                                                         ~ShaderInterface                        (void);
234
235         StructType&                                             allocStruct                                     (const std::string& name);
236         void                                                    getNamedStructs                         (std::vector<const StructType*>& structs) const;
237
238         InterfaceBlock&                                 allocBlock                                      (const std::string& name);
239
240         int                                                             getNumInterfaceBlocks           (void) const    { return (int)m_interfaceBlocks.size(); }
241         const InterfaceBlock&                   getInterfaceBlock                       (int ndx) const { return *m_interfaceBlocks[ndx];               }
242         InterfaceBlock&                                 getInterfaceBlockForModify      (int ndx)               { return *m_interfaceBlocks[ndx];               }
243
244 private:
245         std::vector<StructTypeSP>               m_structs;
246         std::vector<InterfaceBlockSP>   m_interfaceBlocks;
247 };
248
249 struct BlockLayoutEntry
250 {
251         BlockLayoutEntry (void)
252                 : xfbBuffer                             (-1)
253                 , xfbOffset                             (-1)
254                 , xfbSize                               (0)
255                 , xfbStride                             (0)
256                 , blockDeclarationNdx   (-1)
257                 , instanceNdx                   (-1)
258                 , locationNdx                   (-1)
259                 , locationSize                  (-1)
260         {
261         }
262
263         std::string                     name;
264         int                                     xfbBuffer;
265         int                                     xfbOffset;
266         int                                     xfbSize;
267         int                                     xfbStride;
268         std::vector<int>        activeInterfaceIndices;
269         int                                     blockDeclarationNdx;
270         int                                     instanceNdx;
271         // Location are not used for transform feedback, but they must be not overlap to pass GLSL compiler
272         int                                     locationNdx;
273         int                                     locationSize;
274 };
275
276 struct InterfaceLayoutEntry
277 {
278         InterfaceLayoutEntry (void)
279                 : type                  (glu::TYPE_LAST)
280                 , arraySize             (0)
281                 , blockLayoutNdx(-1)
282                 , offset                (-1)
283                 , arrayStride   (-1)
284                 , matrixStride  (-1)
285                 , instanceNdx   (0)
286                 , locationNdx   (-1)
287                 , validate              (true)
288         {
289         }
290
291         std::string                     name;
292         glu::DataType           type;
293         int                                     arraySize;
294         int                                     blockLayoutNdx;
295         int                                     offset;
296         int                                     arrayStride;
297         int                                     matrixStride;
298         int                                     instanceNdx;
299         // Location are not used for transform feedback, but they must be not overlap to pass GLSL compiler
300         int                                     locationNdx;
301         bool                            validate;
302 };
303
304 class InterfaceLayout
305 {
306 public:
307         std::vector<BlockLayoutEntry>           blocks;
308         std::vector<InterfaceLayoutEntry>       interfaces;
309
310         int                                                                     getInterfaceLayoutIndex (int blockDeclarationNdx, const std::string& name) const;
311         int                                                                     getBlockLayoutIndex             (int blockDeclarationNdx, int instanceNdx) const;
312 };
313
314 typedef std::vector<vk::VkDeviceSize> DeviceSizeVector;
315
316 class InterfaceBlockCase : public vkt::TestCase
317 {
318 public:
319                                                         InterfaceBlockCase                      (tcu::TestContext&              testCtx,
320                                                                                                                  const std::string&             name,
321                                                                                                                  const std::string&             description,
322                                                                                                                  MatrixLoadFlags                matrixLoadFlag,
323                                                                                                                  TestStageFlags                 testStageFlag,
324                                                                                                                  bool                                   shuffleInterfaceMembers = false);
325                                                         ~InterfaceBlockCase                     (void);
326
327         virtual void                    delayedInit                                     (void);
328         virtual void                    initPrograms                            (vk::SourceCollections& programCollection) const;
329         virtual TestInstance*   createInstance                          (Context&                               context) const;
330
331 protected:
332         ShaderInterface                 m_interface;
333         MatrixLoadFlags                 m_matrixLoadFlag;
334         TestStageFlags                  m_testStageFlags;
335         bool                                    m_shuffleInterfaceMembers;      //!< Used with explicit offsets to test out of order member offsets
336         deUint32                                m_locationsRequired;
337
338 private:
339         std::string                             m_vertShaderSource;
340         std::string                             m_geomShaderSource;
341
342         std::vector<deUint8>    m_data;                                         //!< Data.
343         DeviceSizeVector                m_tfBufBindingSizes;
344         DeviceSizeVector                m_tfBufBindingOffsets;
345         std::map<int, void*>    m_blockPointers;                        //!< Reference block pointers.
346         InterfaceLayout                 m_interfaceLayout;                      //!< interface layout.
347 };
348
349 } // TransformFeedback
350 } // vkt
351
352 #endif // _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_HPP