Limit changes by xor to upper 8 bits in mixed atomic tests am: 6bc3c7a634 am: eef2e71...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / ubo / vktRandomUniformBlockCase.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Random uniform block layout case.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktRandomUniformBlockCase.hpp"
27 #include "deRandom.hpp"
28
29 namespace vkt
30 {
31 namespace ubo
32 {
33
34 namespace
35 {
36
37 static std::string genName (char first, char last, int ndx)
38 {
39         std::string     str                     = "";
40         int                     alphabetLen     = last - first + 1;
41
42         while (ndx > alphabetLen)
43         {
44                 str.insert(str.begin(), (char)(first + ((ndx - 1) % alphabetLen)));
45                 ndx = (ndx - 1) / alphabetLen;
46         }
47
48         str.insert(str.begin(), (char)(first + (ndx % (alphabetLen + 1)) - 1));
49
50         return str;
51 }
52
53 } // anonymous
54
55 RandomUniformBlockCase::RandomUniformBlockCase (tcu::TestContext&       testCtx,
56                                                                                                 const std::string&      name,
57                                                                                                 const std::string&      description,
58                                                                                                 BufferMode                      bufferMode,
59                                                                                                 deUint32                        features,
60                                                                                                 deUint32                        seed)
61         : UniformBlockCase              (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX, (features & FEATURE_OUT_OF_ORDER_OFFSETS) != 0u)
62         , m_features                    (features)
63         , m_maxVertexBlocks             ((features & FEATURE_VERTEX_BLOCKS)             ? 4 : 0)
64         , m_maxFragmentBlocks   ((features & FEATURE_FRAGMENT_BLOCKS)   ? 4 : 0)
65         , m_maxSharedBlocks             ((features & FEATURE_SHARED_BLOCKS)             ? 4 : 0)
66         , m_maxInstances                ((features & FEATURE_INSTANCE_ARRAYS)   ? 3 : 0)
67         , m_maxArrayLength              ((features & FEATURE_ARRAYS)                    ? 8 : 0)
68         , m_maxStructDepth              ((features & FEATURE_STRUCTS)                   ? 2 : 0)
69         , m_maxBlockMembers             (5)
70         , m_maxStructMembers    (4)
71         , m_seed                                (seed)
72         , m_blockNdx                    (1)
73         , m_uniformNdx                  (1)
74         , m_structNdx                   (1)
75 {
76         de::Random rnd(m_seed);
77
78         int numShared           = m_maxSharedBlocks                             > 0     ? rnd.getInt(1, m_maxSharedBlocks)                              : 0;
79         int numVtxBlocks        = m_maxVertexBlocks-numShared   > 0     ? rnd.getInt(1, m_maxVertexBlocks - numShared)  : 0;
80         int     numFragBlocks   = m_maxFragmentBlocks-numShared > 0 ? rnd.getInt(1, m_maxFragmentBlocks - numShared): 0;
81
82         for (int ndx = 0; ndx < numShared; ndx++)
83                 generateBlock(rnd, DECLARE_VERTEX | DECLARE_FRAGMENT);
84
85         for (int ndx = 0; ndx < numVtxBlocks; ndx++)
86                 generateBlock(rnd, DECLARE_VERTEX);
87
88         for (int ndx = 0; ndx < numFragBlocks; ndx++)
89                 generateBlock(rnd, DECLARE_FRAGMENT);
90
91         init();
92 }
93
94 void RandomUniformBlockCase::generateBlock (de::Random& rnd, deUint32 layoutFlags)
95 {
96         DE_ASSERT(m_blockNdx <= 'z' - 'a');
97
98         const float             instanceArrayWeight     = 0.3f;
99         UniformBlock&   block                           = m_interface.allocBlock(std::string("Block") + (char)('A' + m_blockNdx));
100         int                             numInstances            = (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0;
101         int                             numUniforms                     = rnd.getInt(1, m_maxBlockMembers);
102
103         if (numInstances > 0)
104                 block.setArraySize(numInstances);
105
106         if (numInstances > 0 || rnd.getBool())
107                 block.setInstanceName(std::string("block") + (char)('A' + m_blockNdx));
108
109         // Layout flag candidates.
110         std::vector<deUint32> layoutFlagCandidates;
111         layoutFlagCandidates.push_back(0);
112
113         if (m_features & FEATURE_STD140_LAYOUT)
114                 layoutFlagCandidates.push_back(LAYOUT_STD140);
115
116         layoutFlags |= rnd.choose<deUint32>(layoutFlagCandidates.begin(), layoutFlagCandidates.end());
117
118         if (m_features & FEATURE_MATRIX_LAYOUT)
119         {
120                 static const deUint32 matrixCandidates[] = { 0, LAYOUT_ROW_MAJOR, LAYOUT_COLUMN_MAJOR };
121                 layoutFlags |= rnd.choose<deUint32>(&matrixCandidates[0], &matrixCandidates[DE_LENGTH_OF_ARRAY(matrixCandidates)]);
122         }
123
124         block.setFlags(layoutFlags);
125
126         for (int ndx = 0; ndx < numUniforms; ndx++)
127                 generateUniform(rnd, block);
128
129         m_blockNdx += 1;
130 }
131
132 void RandomUniformBlockCase::generateUniform (de::Random& rnd, UniformBlock& block)
133 {
134         const float             unusedVtxWeight         = 0.15f;
135         const float             unusedFragWeight        = 0.15f;
136         bool                    unusedOk                        = (m_features & FEATURE_UNUSED_UNIFORMS) != 0;
137         deUint32                flags                           = 0;
138         std::string             name                            = genName('a', 'z', m_uniformNdx);
139         VarType                 type                            = generateType(rnd, 0, true);
140
141         flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight)         ? UNUSED_VERTEX         : 0;
142         flags |= (unusedOk && rnd.getFloat() < unusedFragWeight)        ? UNUSED_FRAGMENT       : 0;
143
144         block.addUniform(Uniform(name, type, flags));
145
146         m_uniformNdx += 1;
147 }
148
149 VarType RandomUniformBlockCase::generateType (de::Random& rnd, int typeDepth, bool arrayOk)
150 {
151         const float structWeight        = 0.1f;
152         const float arrayWeight         = 0.1f;
153
154         if (typeDepth < m_maxStructDepth && rnd.getFloat() < structWeight)
155         {
156                 const float                             unusedVtxWeight         = 0.15f;
157                 const float                             unusedFragWeight        = 0.15f;
158                 bool                                    unusedOk                        = (m_features & FEATURE_UNUSED_MEMBERS) != 0;
159                 std::vector<VarType>    memberTypes;
160                 int                                             numMembers = rnd.getInt(1, m_maxStructMembers);
161
162                 // Generate members first so nested struct declarations are in correct order.
163                 for (int ndx = 0; ndx < numMembers; ndx++)
164                         memberTypes.push_back(generateType(rnd, typeDepth+1, true));
165
166                 StructType& structType = m_interface.allocStruct(std::string("s") + genName('A', 'Z', m_structNdx));
167                 m_structNdx += 1;
168
169                 DE_ASSERT(numMembers <= 'Z' - 'A');
170                 for (int ndx = 0; ndx < numMembers; ndx++)
171                 {
172                         deUint32 flags = 0;
173
174                         flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight)         ? UNUSED_VERTEX         : 0;
175                         flags |= (unusedOk && rnd.getFloat() < unusedFragWeight)        ? UNUSED_FRAGMENT       : 0;
176
177                         structType.addMember(std::string("m") + (char)('A' + ndx), memberTypes[ndx], flags);
178                 }
179
180                 return VarType(&structType, m_shuffleUniformMembers ? static_cast<deUint32>(LAYOUT_OFFSET) : 0u);
181         }
182         else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight)
183         {
184                 const bool      arraysOfArraysOk        = (m_features & FEATURE_ARRAYS_OF_ARRAYS) != 0;
185                 const int       arrayLength                     = rnd.getInt(1, m_maxArrayLength);
186                 VarType         elementType                     = generateType(rnd, typeDepth, arraysOfArraysOk);
187                 return VarType(elementType, arrayLength);
188         }
189         else
190         {
191                 std::vector<glu::DataType> typeCandidates;
192
193                 typeCandidates.push_back(glu::TYPE_FLOAT);
194                 typeCandidates.push_back(glu::TYPE_INT);
195                 typeCandidates.push_back(glu::TYPE_UINT);
196                 typeCandidates.push_back(glu::TYPE_BOOL);
197
198                 if (m_features & FEATURE_VECTORS)
199                 {
200                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC2);
201                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC3);
202                         typeCandidates.push_back(glu::TYPE_FLOAT_VEC4);
203                         typeCandidates.push_back(glu::TYPE_INT_VEC2);
204                         typeCandidates.push_back(glu::TYPE_INT_VEC3);
205                         typeCandidates.push_back(glu::TYPE_INT_VEC4);
206                         typeCandidates.push_back(glu::TYPE_UINT_VEC2);
207                         typeCandidates.push_back(glu::TYPE_UINT_VEC3);
208                         typeCandidates.push_back(glu::TYPE_UINT_VEC4);
209                         typeCandidates.push_back(glu::TYPE_BOOL_VEC2);
210                         typeCandidates.push_back(glu::TYPE_BOOL_VEC3);
211                         typeCandidates.push_back(glu::TYPE_BOOL_VEC4);
212                 }
213
214                 if (m_features & FEATURE_MATRICES)
215                 {
216                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT2);
217                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT2X3);
218                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X2);
219                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3);
220                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X4);
221                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X2);
222                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X3);
223                         typeCandidates.push_back(glu::TYPE_FLOAT_MAT4);
224                 }
225
226                 glu::DataType   type    = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end());
227                 deUint32                flags   = (m_shuffleUniformMembers ? static_cast<deUint32>(LAYOUT_OFFSET) : 0u);
228
229                 if (!glu::isDataTypeBoolOrBVec(type))
230                 {
231                         // Precision.
232                         static const deUint32 precisionCandidates[] = { PRECISION_LOW, PRECISION_MEDIUM, PRECISION_HIGH };
233                         flags |= rnd.choose<deUint32>(&precisionCandidates[0], &precisionCandidates[DE_LENGTH_OF_ARRAY(precisionCandidates)]);
234                 }
235
236                 return VarType(type, flags);
237         }
238 }
239
240 } // ubo
241 } // vkt