1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2018 NVIDIA Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Vulkan descriptor set tests
23 *//*--------------------------------------------------------------------*/
24
25 // These tests generate random descriptor set layouts, where each descriptor
26 // set has a random number of bindings, each binding has a random array size
27 // and random descriptor type. The descriptor types are all backed by buffers
28 // or buffer views, and each buffer is filled with a unique integer starting
29 // from zero. The shader fetches from each descriptor (possibly using dynamic
30 // indexing of the descriptor array) and compares against the expected value.
31 //
32 // The different test cases vary the maximum number of descriptors used of
33 // each type. "Low" limit tests use the spec minimum maximum limit, "high"
34 // limit tests use up to 4k descriptors of the corresponding type. Test cases
35 // also vary the type indexing used, and shader stage.
36
37 #include "vktBindingDescriptorSetRandomTests.hpp"
38
39 #include "vkBufferWithMemory.hpp"
40 #include "vkImageWithMemory.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkBuilderUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkTypeUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 #include "vktTestCase.hpp"
47
48 #include "deDefs.h"
49 #include "deMath.h"
50 #include "deRandom.h"
51 #include "deSharedPtr.hpp"
52 #include "deString.h"
53
54 #include "tcuTestCase.hpp"
55 #include "tcuTestLog.hpp"
56
57 #include <string>
58 #include <sstream>
59
60 namespace vkt
61 {
62 namespace BindingModel
63 {
64 namespace
65 {
66 using namespace vk;
67 using namespace std;
68
69 static const deUint32 DIM = 8;
70
71 typedef enum
72 {
73 INDEX_TYPE_NONE = 0,
74 INDEX_TYPE_CONSTANT,
75 INDEX_TYPE_PUSHCONSTANT,
76 INDEX_TYPE_DEPENDENT,
77 INDEX_TYPE_RUNTIME_SIZE,
78 } IndexType;
79
80 typedef enum
81 {
82 STAGE_COMPUTE = 0,
83 STAGE_VERTEX,
84 STAGE_FRAGMENT,
85 } Stage;
86
87 typedef enum
88 {
89 UPDATE_AFTER_BIND_DISABLED = 0,
90 UPDATE_AFTER_BIND_ENABLED,
91 } UpdateAfterBind;
92
93 const VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
94 const VkFlags allPipelineStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
95
96 struct CaseDef
97 {
98 IndexType indexType;
99 deUint32 numDescriptorSets;
100 deUint32 maxPerStageUniformBuffers;
101 deUint32 maxUniformBuffersDynamic;
102 deUint32 maxPerStageStorageBuffers;
103 deUint32 maxStorageBuffersDynamic;
104 deUint32 maxPerStageSampledImages;
105 deUint32 maxPerStageStorageImages;
106 deUint32 maxInlineUniformBlocks;
107 deUint32 maxInlineUniformBlockSize;
108 Stage stage;
109 UpdateAfterBind uab;
110 deUint32 seed;
111 };
112
113
114 class RandomLayout
115 {
116 public:
RandomLayout(deUint32 numSets)117 RandomLayout(deUint32 numSets) :
118 layoutBindings(numSets),
119 layoutBindingFlags(numSets),
120 arraySizes(numSets),
121 variableDescriptorSizes(numSets)
122 {
123 }
124
125 // These three are indexed by [set][binding]
126 vector<vector<VkDescriptorSetLayoutBinding> > layoutBindings;
127 vector<vector<VkDescriptorBindingFlagsEXT> > layoutBindingFlags;
128 vector<vector<deUint32> > arraySizes;
129 // size of the variable descriptor (last) binding in each set
130 vector<deUint32> variableDescriptorSizes;
131
132 };
133
134
135 class DescriptorSetRandomTestInstance : public TestInstance
136 {
137 public:
138 DescriptorSetRandomTestInstance (Context& context, const CaseDef& data);
139 ~DescriptorSetRandomTestInstance (void);
140 tcu::TestStatus iterate (void);
141 private:
142 CaseDef m_data;
143
144 enum
145 {
146 WIDTH = 256,
147 HEIGHT = 256
148 };
149 };
150
DescriptorSetRandomTestInstance(Context & context,const CaseDef & data)151 DescriptorSetRandomTestInstance::DescriptorSetRandomTestInstance (Context& context, const CaseDef& data)
152 : vkt::TestInstance (context)
153 , m_data (data)
154 {
155 }
156
~DescriptorSetRandomTestInstance(void)157 DescriptorSetRandomTestInstance::~DescriptorSetRandomTestInstance (void)
158 {
159 }
160
161 class DescriptorSetRandomTestCase : public TestCase
162 {
163 public:
164 DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
165 ~DescriptorSetRandomTestCase (void);
166 virtual void initPrograms (SourceCollections& programCollection) const;
167 virtual TestInstance* createInstance (Context& context) const;
168 virtual void checkSupport (Context& context) const;
169
170 private:
171 CaseDef m_data;
172 };
173
DescriptorSetRandomTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef data)174 DescriptorSetRandomTestCase::DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
175 : vkt::TestCase (context, name, desc)
176 , m_data (data)
177 {
178 }
179
~DescriptorSetRandomTestCase(void)180 DescriptorSetRandomTestCase::~DescriptorSetRandomTestCase (void)
181 {
182 }
183
checkSupport(Context & context) const184 void DescriptorSetRandomTestCase::checkSupport(Context& context) const
185 {
186 VkPhysicalDeviceInlineUniformBlockPropertiesEXT inlineUniformProperties;
187 deMemset(&inlineUniformProperties, 0, sizeof(inlineUniformProperties));
188 inlineUniformProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT;
189
190 VkPhysicalDeviceProperties2 properties;
191 deMemset(&properties, 0, sizeof(properties));
192 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
193
194 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
195 {
196 properties.pNext = &inlineUniformProperties;
197 }
198
199 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
200
201 VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures;
202 deMemset(&inlineUniformFeatures, 0, sizeof(inlineUniformFeatures));
203 inlineUniformFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
204
205 VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures;
206 deMemset(&indexingFeatures, 0, sizeof(indexingFeatures));
207 indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
208
209 VkPhysicalDeviceFeatures2 features;
210 deMemset(&features, 0, sizeof(features));
211 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
212
213 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_descriptor_indexing") &&
214 isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
215 {
216 indexingFeatures.pNext = &inlineUniformFeatures;
217 features.pNext = &indexingFeatures;
218 }
219 else if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_descriptor_indexing"))
220 {
221 features.pNext = &indexingFeatures;
222 }
223 else if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
224 {
225 features.pNext = &inlineUniformFeatures;
226 }
227
228 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features);
229 if (m_data.stage == STAGE_VERTEX && !features.features.vertexPipelineStoresAndAtomics)
230 {
231 return TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
232 }
233
234 if ((m_data.indexType == INDEX_TYPE_PUSHCONSTANT ||
235 m_data.indexType == INDEX_TYPE_DEPENDENT ||
236 m_data.indexType == INDEX_TYPE_RUNTIME_SIZE) &&
237 (!features.features.shaderUniformBufferArrayDynamicIndexing ||
238 !features.features.shaderStorageBufferArrayDynamicIndexing ||
239 !features.features.shaderSampledImageArrayDynamicIndexing ||
240 !features.features.shaderStorageImageArrayDynamicIndexing ||
241 !indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing ||
242 !indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing))
243 {
244 TCU_THROW(NotSupportedError, "Dynamic indexing not supported");
245 }
246
247 if (m_data.numDescriptorSets > properties.properties.limits.maxBoundDescriptorSets)
248 {
249 TCU_THROW(NotSupportedError, "Number of descriptor sets not supported");
250 }
251
252 if ((m_data.maxPerStageUniformBuffers + m_data.maxPerStageStorageBuffers +
253 m_data.maxPerStageSampledImages + m_data.maxPerStageStorageImages) >
254 properties.properties.limits.maxPerStageResources)
255 {
256 TCU_THROW(NotSupportedError, "Number of descriptors not supported");
257 }
258
259 if (m_data.maxPerStageUniformBuffers > properties.properties.limits.maxPerStageDescriptorUniformBuffers ||
260 m_data.maxPerStageStorageBuffers > properties.properties.limits.maxPerStageDescriptorStorageBuffers ||
261 m_data.maxUniformBuffersDynamic > properties.properties.limits.maxDescriptorSetUniformBuffersDynamic ||
262 m_data.maxStorageBuffersDynamic > properties.properties.limits.maxDescriptorSetStorageBuffersDynamic ||
263 m_data.maxPerStageSampledImages > properties.properties.limits.maxPerStageDescriptorSampledImages ||
264 m_data.maxPerStageStorageImages > properties.properties.limits.maxPerStageDescriptorStorageImages)
265 {
266 TCU_THROW(NotSupportedError, "Number of descriptors not supported");
267 }
268
269 if (m_data.maxInlineUniformBlocks != 0 &&
270 !inlineUniformFeatures.inlineUniformBlock)
271 {
272 TCU_THROW(NotSupportedError, "Inline uniform blocks not supported");
273 }
274
275 if (m_data.maxInlineUniformBlocks > inlineUniformProperties.maxPerStageDescriptorInlineUniformBlocks)
276 {
277 TCU_THROW(NotSupportedError, "Number of inline uniform blocks not supported");
278 }
279
280 if (m_data.maxInlineUniformBlocks != 0 &&
281 m_data.maxInlineUniformBlockSize > inlineUniformProperties.maxInlineUniformBlockSize)
282 {
283 TCU_THROW(NotSupportedError, "Inline uniform block size not supported");
284 }
285
286 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE &&
287 !indexingFeatures.runtimeDescriptorArray)
288 {
289 TCU_THROW(NotSupportedError, "runtimeDescriptorArray not supported");
290 }
291 }
292
293 // Return a random value in the range [min, max]
randRange(deRandom * rnd,deInt32 min,deInt32 max)294 deInt32 randRange(deRandom *rnd, deInt32 min, deInt32 max)
295 {
296 if (max < 0)
297 return 0;
298
299 return (deRandom_getUint32(rnd) % (max - min + 1)) + min;
300 }
301
generateRandomLayout(RandomLayout & randomLayout,const CaseDef & caseDef)302 void generateRandomLayout(RandomLayout &randomLayout, const CaseDef &caseDef)
303 {
304 deRandom rnd;
305 deRandom_init(&rnd, caseDef.seed);
306
307 // Count the number of each resource type, to avoid overflowing the limits.
308 deUint32 numUBO = 0;
309 deUint32 numUBODyn = 0;
310 deUint32 numSSBO = 0;
311 deUint32 numSSBODyn = 0;
312 deUint32 numImage = 0;
313 deUint32 numTexBuffer = 0;
314 deUint32 numInlineUniformBlocks = 0;
315
316 // TODO: Consider varying these
317 deUint32 minBindings = 0;
318 deUint32 maxBindings = 32;
319 // No larger than 32 elements for dynamic indexing tests, due to 128B limit
320 // for push constants (used for the indices)
321 deUint32 maxArray = caseDef.indexType == INDEX_TYPE_NONE ? 0 : 32;
322
323 // Each set has a random number of bindings, each binding has a random
324 // array size and a random descriptor type.
325 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
326 {
327 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
328 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
329 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
330 int numBindings = randRange(&rnd, minBindings, maxBindings);
331
332 // Guarantee room for the output image
333 if (s == 0 && numBindings == 0)
334 {
335 numBindings = 1;
336 }
337
338 bindings = vector<VkDescriptorSetLayoutBinding>(numBindings);
339 bindingsFlags = vector<VkDescriptorBindingFlagsEXT>(numBindings);
340 arraySizes = vector<deUint32>(numBindings);
341 }
342
343 // BUFFER_DYNAMIC descriptor types cannot be used with VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bindings in one set
344 bool allowDynamicBuffers = caseDef.uab != UPDATE_AFTER_BIND_ENABLED;
345
346 // Iterate over bindings first, then over sets. This prevents the low-limit bindings
347 // from getting clustered in low-numbered sets.
348 for (deUint32 b = 0; b <= maxBindings; ++b)
349 {
350 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
351 {
352 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
353 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
354
355 if (b >= bindings.size())
356 {
357 continue;
358 }
359
360 VkDescriptorSetLayoutBinding &binding = bindings[b];
361 binding.binding = b;
362 binding.pImmutableSamplers = NULL;
363 binding.stageFlags = allShaderStages;
364
365 // Output image
366 if (s == 0 && b == 0)
367 {
368 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
369 binding.descriptorCount = 1;
370 numImage++;
371 arraySizes[b] = 0;
372 continue;
373 }
374
375 binding.descriptorCount = 0;
376
377 // Select a random type of descriptor.
378 int r = randRange(&rnd, 0, (allowDynamicBuffers ? 6 : 4));
379 switch (r)
380 {
381 default: DE_ASSERT(0); // Fallthrough
382 case 0:
383 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
384 if (numUBO < caseDef.maxPerStageUniformBuffers)
385 {
386 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageUniformBuffers - numUBO));
387 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
388 numUBO += binding.descriptorCount;
389 }
390 break;
391 case 1:
392 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
393 if (numSSBO < caseDef.maxPerStageStorageBuffers)
394 {
395 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageBuffers - numSSBO));
396 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
397 numSSBO += binding.descriptorCount;
398 }
399 break;
400 case 2:
401 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
402 if (numImage < caseDef.maxPerStageStorageImages)
403 {
404 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageImages - numImage));
405 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
406 numImage += binding.descriptorCount;
407 }
408 break;
409 case 3:
410 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
411 if (numTexBuffer < caseDef.maxPerStageSampledImages)
412 {
413 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageSampledImages - numTexBuffer));
414 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
415 numTexBuffer += binding.descriptorCount;
416 }
417 break;
418 case 4:
419 if (caseDef.maxInlineUniformBlocks > 0)
420 {
421 binding.descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
422 if (numInlineUniformBlocks < caseDef.maxInlineUniformBlocks)
423 {
424 arraySizes[b] = randRange(&rnd, 1, (caseDef.maxInlineUniformBlockSize - 16) / 16); // subtract 16 for "ivec4 dummy"
425 arraySizes[b] = de::min(maxArray, arraySizes[b]);
426 binding.descriptorCount = (arraySizes[b] ? arraySizes[b] : 1) * 16 + 16; // add 16 for "ivec4 dummy"
427 numInlineUniformBlocks++;
428 }
429 }
430 else
431 {
432 // Plug in a dummy descriptor type, so validation layers that don't
433 // support inline_uniform_block don't crash.
434 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
435 }
436 break;
437 case 5:
438 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
439 if (numUBODyn < caseDef.maxUniformBuffersDynamic &&
440 numUBO < caseDef.maxPerStageUniformBuffers)
441 {
442 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxUniformBuffersDynamic - numUBODyn,
443 caseDef.maxPerStageUniformBuffers - numUBO)));
444 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
445 numUBO += binding.descriptorCount;
446 numUBODyn += binding.descriptorCount;
447 }
448 break;
449 case 6:
450 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
451 if (numSSBODyn < caseDef.maxStorageBuffersDynamic &&
452 numSSBO < caseDef.maxPerStageStorageBuffers)
453 {
454 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxStorageBuffersDynamic - numSSBODyn,
455 caseDef.maxPerStageStorageBuffers - numSSBO)));
456 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
457 numSSBO += binding.descriptorCount;
458 numSSBODyn += binding.descriptorCount;
459 }
460 break;
461 }
462 }
463 }
464
465 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
466 {
467 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
468 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
469 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
470
471 // Choose a variable descriptor count size. If the feature is not supported, we'll just
472 // allocate the whole thing later on.
473 if (bindings.size() > 0 &&
474 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
475 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC &&
476 !(s == 0 && bindings.size() == 1) && // Don't cut out the output image binding
477 randRange(&rnd, 1,4) == 1) // 1 in 4 chance
478 {
479
480 bindingsFlags[bindings.size()-1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
481 variableDescriptorSizes[s] = randRange(&rnd, 0,bindings[bindings.size()-1].descriptorCount);
482 if (bindings[bindings.size()-1].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
483 {
484 // keep a multiple of 16B
485 variableDescriptorSizes[s] &= ~0xF;
486 }
487 }
488 }
489 }
490
initPrograms(SourceCollections & programCollection) const491 void DescriptorSetRandomTestCase::initPrograms (SourceCollections& programCollection) const
492 {
493 RandomLayout randomLayout(m_data.numDescriptorSets);
494 generateRandomLayout(randomLayout, m_data);
495
496 std::stringstream decls, checks;
497
498 deUint32 descriptor = 0;
499 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
500 {
501 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
502 vector<VkDescriptorBindingFlagsEXT> bindingsFlags = randomLayout.layoutBindingFlags[s];
503 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
504 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
505
506 for (size_t b = 0; b < bindings.size(); ++b)
507 {
508 VkDescriptorSetLayoutBinding &binding = bindings[b];
509 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1;
510
511 // Construct the declaration for the binding
512 if (binding.descriptorCount > 0)
513 {
514 std::stringstream array;
515 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE &&
516 binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
517 {
518 if (arraySizes[b])
519 {
520 array << "[]";
521 }
522 }
523 else
524 {
525 if (arraySizes[b])
526 {
527 array << "[" << arraySizes[b] << "]";
528 }
529 }
530 switch (binding.descriptorType)
531 {
532 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
533 decls << "layout(set = " << s << ", binding = " << b << ") uniform inlineubodef" << s << "_" << b << " { ivec4 dummy; int val" << array.str() << "; } inlineubo" << s << "_" << b << ";\n";
534 break;
535 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
536 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
537 decls << "layout(set = " << s << ", binding = " << b << ") uniform ubodef" << s << "_" << b << " { int val; } ubo" << s << "_" << b << array.str() << ";\n";
538 break;
539 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
540 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
541 decls << "layout(set = " << s << ", binding = " << b << ") buffer sbodef" << s << "_" << b << " { int val; } ssbo" << s << "_" << b << array.str() << ";\n";
542 break;
543 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
544 decls << "layout(set = " << s << ", binding = " << b << ") uniform itextureBuffer texbo" << s << "_" << b << array.str() << ";\n";
545 break;
546 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
547 decls << "layout(r32i, set = " << s << ", binding = " << b << ") uniform iimageBuffer image" << s << "_" << b << array.str() << ";\n";
548 break;
549 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
550 decls << "layout(r32ui, set = " << s << ", binding = " << b << ") uniform uimage2D image" << s << "_" << b << array.str() << ";\n";
551 break;
552 default: DE_ASSERT(0);
553 }
554
555 for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement)
556 {
557 // Don't access descriptors past the end of the allocated range for
558 // variable descriptor count
559 if (b == bindings.size() - 1 &&
560 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT))
561 {
562 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
563 {
564 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block
565 const deUint32 uboRange = ai*16 + 16;
566 if (uboRange >= variableDescriptorSizes[s])
567 continue;
568 }
569 else
570 {
571 if (ai >= variableDescriptorSizes[s])
572 continue;
573 }
574 }
575
576 if (s == 0 && b == 0)
577 {
578 // This is the output image, skip.
579 continue;
580 }
581
582 // Check that the value in the descriptor equals its descriptor number.
583 // i.e. check "ubo[c].val == descriptor" or "ubo[pushconst[c]].val == descriptor"
584
585 // First, construct the index. This can be a constant literal, a value
586 // from a push constant, or a function of the previous descriptor value.
587 std::stringstream ind;
588 switch (m_data.indexType)
589 {
590 case INDEX_TYPE_NONE:
591 case INDEX_TYPE_CONSTANT:
592 // The index is just the constant literal
593 if (arraySizes[b])
594 {
595 ind << "[" << ai << "]";
596 }
597 break;
598 case INDEX_TYPE_PUSHCONSTANT:
599 // identity is an int[], directly index it
600 if (arraySizes[b])
601 {
602 ind << "[pc.identity[" << ai << "]]";
603 }
604 break;
605 case INDEX_TYPE_RUNTIME_SIZE:
606 case INDEX_TYPE_DEPENDENT:
607 // Index is a function of the previous return value (which is reset to zero)
608 if (arraySizes[b])
609 {
610 ind << "[accum + " << ai << "]";
611 }
612 break;
613 default: DE_ASSERT(0);
614 }
615
616 // For very large bindings, only check every N=201 descriptors (chosen arbitrarily)
617 bool checkDescriptor = true;
618 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
619 {
620 // For "large" bindings, only check every N=3 descriptors (chosen arbitrarily).
621 // This is meant to reduce shader compile time.
622 if (ai > 2 &&
623 binding.descriptorCount >= 4 &&
624 (ai % 3) != 0)
625 {
626 checkDescriptor = false;
627 }
628 }
629
630 if (checkDescriptor)
631 {
632 // Fetch from the descriptor.
633 switch (binding.descriptorType)
634 {
635 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
636 checks << " temp = inlineubo" << s << "_" << b << ".val" << ind.str() << ";\n";
637 break;
638 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
639 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
640 checks << " temp = ubo" << s << "_" << b << ind.str() << ".val;\n";
641 break;
642 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
643 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
644 checks << " temp = ssbo" << s << "_" << b << ind.str() << ".val;\n";
645 break;
646 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
647 checks << " temp = texelFetch(texbo" << s << "_" << b << ind.str() << ", 0).x;\n";
648 break;
649 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
650 checks << " temp = imageLoad(image" << s << "_" << b << ind.str() << ", 0).x;\n";
651 break;
652 default: DE_ASSERT(0);
653 }
654 if (m_data.indexType == INDEX_TYPE_DEPENDENT || m_data.indexType == INDEX_TYPE_RUNTIME_SIZE)
655 {
656 // Set accum to zero, it is added to the next index.
657 checks << " accum = temp - " << descriptor << ";\n";
658 }
659 else
660 {
661 // Accumulate any incorrect values.
662 checks << " accum |= temp - " << descriptor << ";\n";
663 }
664 }
665 }
666 }
667 }
668 }
669
670 std::stringstream pushdecl;
671 switch (m_data.indexType)
672 {
673 case INDEX_TYPE_PUSHCONSTANT:
674 pushdecl << "layout (push_constant, std430) uniform Block { int identity[32]; } pc;\n";
675 break;
676 default: DE_ASSERT(0);
677 case INDEX_TYPE_NONE:
678 case INDEX_TYPE_CONSTANT:
679 case INDEX_TYPE_DEPENDENT:
680 case INDEX_TYPE_RUNTIME_SIZE:
681 break;
682 }
683
684
685 switch (m_data.stage)
686 {
687 default: DE_ASSERT(0); // Fallthrough
688 case STAGE_COMPUTE:
689 {
690 std::stringstream css;
691 css <<
692 "#version 450 core\n"
693 "#extension GL_EXT_nonuniform_qualifier : enable\n"
694 << pushdecl.str()
695 << decls.str() <<
696 "layout(local_size_x = 1, local_size_y = 1) in;\n"
697 "void main()\n"
698 "{\n"
699 " int accum = 0, temp;\n"
700 << checks.str() <<
701 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
702 " imageStore(image0_0, ivec2(gl_GlobalInvocationID.xy), color);\n"
703 "}\n";
704
705 programCollection.glslSources.add("test") << glu::ComputeSource(css.str());
706 break;
707 }
708 case STAGE_VERTEX:
709 {
710 std::stringstream vss;
711 vss <<
712 "#version 450 core\n"
713 "#extension GL_EXT_nonuniform_qualifier : enable\n"
714 << pushdecl.str()
715 << decls.str() <<
716 "void main()\n"
717 "{\n"
718 " int accum = 0, temp;\n"
719 << checks.str() <<
720 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
721 " imageStore(image0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n"
722 " gl_PointSize = 1.0f;\n"
723 " gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
724 "}\n";
725
726 programCollection.glslSources.add("test") << glu::VertexSource(vss.str());
727 break;
728 }
729 case STAGE_FRAGMENT:
730 {
731 std::stringstream vss;
732 vss <<
733 "#version 450 core\n"
734 "void main()\n"
735 "{\n"
736 // full-viewport quad
737 " gl_Position = vec4( 2.0*float(gl_VertexIndex&2) - 1.0, 4.0*(gl_VertexIndex&1)-1.0, 1.0 - 2.0 * float(gl_VertexIndex&1), 1);\n"
738 "}\n";
739
740 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
741
742 std::stringstream fss;
743 fss <<
744 "#version 450 core\n"
745 "#extension GL_EXT_nonuniform_qualifier : enable\n"
746 << pushdecl.str()
747 << decls.str() <<
748 "void main()\n"
749 "{\n"
750 " int accum = 0, temp;\n"
751 << checks.str() <<
752 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n"
753 " imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n"
754 "}\n";
755
756 programCollection.glslSources.add("test") << glu::FragmentSource(fss.str());
757 break;
758 }
759 }
760
761 }
762
createInstance(Context & context) const763 TestInstance* DescriptorSetRandomTestCase::createInstance (Context& context) const
764 {
765 return new DescriptorSetRandomTestInstance(context, m_data);
766 }
767
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)768 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
769 const VkBufferUsageFlags usage)
770 {
771 const VkBufferCreateInfo bufferCreateInfo =
772 {
773 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
774 DE_NULL, // const void* pNext;
775 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
776 bufferSize, // VkDeviceSize size;
777 usage, // VkBufferUsageFlags usage;
778 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
779 0u, // deUint32 queueFamilyIndexCount;
780 DE_NULL, // const deUint32* pQueueFamilyIndices;
781 };
782 return bufferCreateInfo;
783 }
784
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const void * pNext,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)785 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
786 const VkDevice device,
787 const void* pNext,
788 const VkDescriptorPool descriptorPool,
789 const VkDescriptorSetLayout setLayout)
790 {
791 const VkDescriptorSetAllocateInfo allocateParams =
792 {
793 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
794 pNext, // const void* pNext;
795 descriptorPool, // VkDescriptorPool descriptorPool;
796 1u, // deUint32 setLayoutCount;
797 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
798 };
799 return allocateDescriptorSet(vk, device, &allocateParams);
800 }
801
makeBufferImageCopy(const VkExtent3D extent,const VkImageSubresourceLayers subresourceLayers)802 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
803 const VkImageSubresourceLayers subresourceLayers)
804 {
805 const VkBufferImageCopy copyParams =
806 {
807 0ull, // VkDeviceSize bufferOffset;
808 0u, // deUint32 bufferRowLength;
809 0u, // deUint32 bufferImageHeight;
810 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
811 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
812 extent, // VkExtent3D imageExtent;
813 };
814 return copyParams;
815 }
816
iterate(void)817 tcu::TestStatus DescriptorSetRandomTestInstance::iterate (void)
818 {
819 const DeviceInterface& vk = m_context.getDeviceInterface();
820 const VkDevice device = m_context.getDevice();
821 Allocator& allocator = m_context.getDefaultAllocator();
822
823 RandomLayout randomLayout(m_data.numDescriptorSets);
824 generateRandomLayout(randomLayout, m_data);
825
826
827 VkPhysicalDeviceProperties2 properties;
828 deMemset(&properties, 0, sizeof(properties));
829 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
830
831 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties);
832
833 VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures;
834 deMemset(&inlineUniformFeatures, 0, sizeof(inlineUniformFeatures));
835 inlineUniformFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
836
837 VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures;
838 deMemset(&indexingFeatures, 0, sizeof(indexingFeatures));
839 indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
840
841 VkPhysicalDeviceFeatures2 features;
842 deMemset(&features, 0, sizeof(features));
843 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
844
845 if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_descriptor_indexing") &&
846 isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
847 {
848 indexingFeatures.pNext = &inlineUniformFeatures;
849 features.pNext = &indexingFeatures;
850 }
851 else if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_descriptor_indexing"))
852 {
853 features.pNext = &indexingFeatures;
854 }
855 else if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_inline_uniform_block"))
856 {
857 features.pNext = &inlineUniformFeatures;
858 }
859
860 m_context.getInstanceInterface().getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &features);
861
862 deRandom rnd;
863 deRandom_init(&rnd, m_data.seed);
864
865 VkPipelineBindPoint bindPoint = m_data.stage == STAGE_COMPUTE ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
866
867 DE_ASSERT(m_data.numDescriptorSets <= 32);
868 Move<vk::VkDescriptorSetLayout> descriptorSetLayouts[32];
869 Move<vk::VkDescriptorPool> descriptorPools[32];
870 Move<vk::VkDescriptorSet> descriptorSets[32];
871
872 deUint32 numDescriptors = 0;
873 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
874 {
875 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
876 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
877 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
878
879 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
880 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
881
882 for (size_t b = 0; b < bindings.size(); ++b)
883 {
884 VkDescriptorSetLayoutBinding &binding = bindings[b];
885 numDescriptors += binding.descriptorCount;
886
887 // Randomly choose some bindings to use update-after-bind, if it is supported
888 if (m_data.uab == UPDATE_AFTER_BIND_ENABLED &&
889 randRange(&rnd, 1, 8) == 1 && // 1 in 8 chance
890 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || indexingFeatures.descriptorBindingUniformBufferUpdateAfterBind) &&
891 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || indexingFeatures.descriptorBindingStorageImageUpdateAfterBind) &&
892 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || indexingFeatures.descriptorBindingStorageBufferUpdateAfterBind) &&
893 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || indexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind) &&
894 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || indexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind) &&
895 (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT || inlineUniformFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind) &&
896 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) &&
897 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
898 {
899 bindingsFlags[b] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT;
900 layoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
901 poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
902 }
903
904 if (!indexingFeatures.descriptorBindingVariableDescriptorCount)
905 {
906 bindingsFlags[b] &= ~VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
907 }
908 }
909
910 // Create a layout and allocate a descriptor set for it.
911
912 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT bindingFlagsInfo =
913 {
914 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT, // VkStructureType sType;
915 DE_NULL, // const void* pNext;
916 (deUint32)bindings.size(), // uint32_t bindingCount;
917 bindings.empty() ? DE_NULL : &bindingsFlags[0], // const VkDescriptorBindingFlagsEXT* pBindingFlags;
918 };
919
920 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
921 {
922 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
923 &bindingFlagsInfo,
924
925 layoutCreateFlags,
926 (deUint32)bindings.size(),
927 bindings.empty() ? DE_NULL : &bindings[0]
928 };
929
930 descriptorSetLayouts[s] = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
931
932 vk::DescriptorPoolBuilder poolBuilder;
933 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, m_data.maxPerStageUniformBuffers);
934 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, m_data.maxUniformBuffersDynamic);
935 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_data.maxPerStageStorageBuffers);
936 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, m_data.maxStorageBuffersDynamic);
937 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, m_data.maxPerStageSampledImages);
938 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, m_data.maxPerStageStorageImages);
939 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1);
940 if (m_data.maxInlineUniformBlocks)
941 {
942 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, m_data.maxInlineUniformBlocks * m_data.maxInlineUniformBlockSize);
943 }
944
945 VkDescriptorPoolInlineUniformBlockCreateInfoEXT inlineUniformBlockPoolCreateInfo =
946 {
947 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, // VkStructureType sType;
948 DE_NULL, // const void* pNext;
949 m_data.maxInlineUniformBlocks, // uint32_t maxInlineUniformBlockBindings;
950 };
951
952 descriptorPools[s] = poolBuilder.build(vk, device, poolCreateFlags, 1u,
953 m_data.maxInlineUniformBlocks ? &inlineUniformBlockPoolCreateInfo : DE_NULL);
954
955 VkDescriptorSetVariableDescriptorCountAllocateInfoEXT variableCountInfo =
956 {
957 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT, // VkStructureType sType;
958 DE_NULL, // const void* pNext;
959 0, // uint32_t descriptorSetCount;
960 DE_NULL, // const uint32_t* pDescriptorCounts;
961 };
962
963 const void *pNext = DE_NULL;
964 if (bindings.size() > 0 &&
965 bindingsFlags[bindings.size()-1] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)
966 {
967 variableCountInfo.descriptorSetCount = 1;
968 variableCountInfo.pDescriptorCounts = &variableDescriptorSizes[s];
969 pNext = &variableCountInfo;
970 }
971
972 descriptorSets[s] = makeDescriptorSet(vk, device, pNext, *descriptorPools[s], *descriptorSetLayouts[s]);
973 }
974
975
976 VkDeviceSize align = de::max(de::max(de::max(properties.properties.limits.minTexelBufferOffsetAlignment,
977 properties.properties.limits.minUniformBufferOffsetAlignment),
978 properties.properties.limits.minStorageBufferOffsetAlignment),
979 (VkDeviceSize)sizeof(deUint32));
980
981 de::MovePtr<BufferWithMemory> buffer;
982 buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
983 vk, device, allocator, makeBufferCreateInfo(align*numDescriptors,
984 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
985 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
986 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
987 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT),
988 MemoryRequirement::HostVisible));
989 deUint8 *bufferPtr = (deUint8 *)buffer->getAllocation().getHostPtr();
990
991 typedef vk::Unique<vk::VkBufferView> BufferViewHandleUp;
992 typedef de::SharedPtr<BufferViewHandleUp> BufferViewHandleSp;
993
994 vector<BufferViewHandleSp> bufferViews(de::max(1u,numDescriptors));
995
996 // Create a buffer and view for each descriptor. Fill descriptor 'd'
997 // with an integer value equal to 'd'.
998 int descriptor = 0;
999 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
1000 {
1001 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
1002 for (size_t b = 0; b < bindings.size(); ++b)
1003 {
1004 VkDescriptorSetLayoutBinding &binding = bindings[b];
1005
1006 if (binding.descriptorCount == 0)
1007 {
1008 continue;
1009 }
1010 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1011 {
1012 for (deUint32 d = descriptor; d < descriptor + binding.descriptorCount; ++d)
1013 {
1014 deUint32 *ptr = (deUint32 *)(bufferPtr + align*d);
1015 *ptr = d;
1016
1017 const vk::VkBufferViewCreateInfo viewCreateInfo =
1018 {
1019 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1020 DE_NULL,
1021 (vk::VkBufferViewCreateFlags)0,
1022 **buffer, // buffer
1023 VK_FORMAT_R32_SINT, // format
1024 (vk::VkDeviceSize)align*d, // offset
1025 (vk::VkDeviceSize)sizeof(deUint32) // range
1026 };
1027 vk::Move<vk::VkBufferView> bufferView = vk::createBufferView(vk, device, &viewCreateInfo);
1028 bufferViews[d] = BufferViewHandleSp(new BufferViewHandleUp(bufferView));
1029 }
1030 descriptor += binding.descriptorCount;
1031 }
1032 else
1033 {
1034 // subtract 16 for "ivec4 dummy"
1035 DE_ASSERT(binding.descriptorCount >= 16);
1036 descriptor += binding.descriptorCount - 16;
1037 }
1038 }
1039 }
1040
1041 flushMappedMemoryRange(vk, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1042
1043 const VkQueue queue = m_context.getUniversalQueue();
1044 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex());
1045 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1046
1047 beginCommandBuffer(vk, *cmdBuffer, 0u);
1048
1049 // Push constants are used for dynamic indexing. PushConstant[i] = i.
1050
1051 const VkPushConstantRange pushConstRange =
1052 {
1053 allShaderStages, // VkShaderStageFlags stageFlags
1054 0, // deUint32 offset
1055 128 // deUint32 size
1056 };
1057
1058 vector<vk::VkDescriptorSetLayout> descriptorSetLayoutsRaw(m_data.numDescriptorSets);
1059 for (size_t i = 0; i < m_data.numDescriptorSets; ++i)
1060 {
1061 descriptorSetLayoutsRaw[i] = descriptorSetLayouts[i].get();
1062 }
1063
1064 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1065 {
1066 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1067 DE_NULL, // pNext
1068 (VkPipelineLayoutCreateFlags)0,
1069 m_data.numDescriptorSets, // setLayoutCount
1070 &descriptorSetLayoutsRaw[0], // pSetLayouts
1071 m_data.indexType == INDEX_TYPE_PUSHCONSTANT ? 1u : 0u, // pushConstantRangeCount
1072 &pushConstRange, // pPushConstantRanges
1073 };
1074
1075 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1076
1077 if (m_data.indexType == INDEX_TYPE_PUSHCONSTANT)
1078 {
1079 // PushConstant[i] = i
1080 for (deUint32 i = 0; i < (deUint32)(128 / sizeof(deUint32)); ++i)
1081 {
1082 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages,
1083 (deUint32)(i * sizeof(deUint32)), (deUint32)sizeof(deUint32), &i);
1084 }
1085 }
1086
1087 de::MovePtr<BufferWithMemory> copyBuffer;
1088 copyBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1089 vk, device, allocator, makeBufferCreateInfo(DIM*DIM*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1090
1091 const VkImageCreateInfo imageCreateInfo =
1092 {
1093 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1094 DE_NULL, // const void* pNext;
1095 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1096 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1097 VK_FORMAT_R32_UINT, // VkFormat format;
1098 {
1099 DIM, // deUint32 width;
1100 DIM, // deUint32 height;
1101 1u // deUint32 depth;
1102 }, // VkExtent3D extent;
1103 1u, // deUint32 mipLevels;
1104 1u, // deUint32 arrayLayers;
1105 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1106 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1107 VK_IMAGE_USAGE_STORAGE_BIT
1108 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1109 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1110 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1111 0u, // deUint32 queueFamilyIndexCount;
1112 DE_NULL, // const deUint32* pQueueFamilyIndices;
1113 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1114 };
1115
1116 VkImageViewCreateInfo imageViewCreateInfo =
1117 {
1118 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1119 DE_NULL, // const void* pNext;
1120 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1121 DE_NULL, // VkImage image;
1122 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1123 VK_FORMAT_R32_UINT, // VkFormat format;
1124 {
1125 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1126 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1127 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1128 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1129 }, // VkComponentMapping components;
1130 {
1131 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1132 0u, // deUint32 baseMipLevel;
1133 1u, // deUint32 levelCount;
1134 0u, // deUint32 baseArrayLayer;
1135 1u // deUint32 layerCount;
1136 } // VkImageSubresourceRange subresourceRange;
1137 };
1138
1139 de::MovePtr<ImageWithMemory> image;
1140 Move<VkImageView> imageView;
1141
1142 image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1143 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1144 imageViewCreateInfo.image = **image;
1145 imageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1146
1147 descriptor = 0;
1148 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
1149 {
1150 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
1151 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s];
1152 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
1153 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
1154
1155 vector<VkDescriptorBufferInfo> bufferInfoVec(numDescriptors);
1156 vector<VkDescriptorImageInfo> imageInfoVec(numDescriptors);
1157 vector<VkBufferView> bufferViewVec(numDescriptors);
1158 vector<VkWriteDescriptorSetInlineUniformBlockEXT> inlineInfoVec(numDescriptors);
1159 vector<deUint32> descriptorNumber(numDescriptors);
1160 vector<VkWriteDescriptorSet> writesBeforeBindVec(0);
1161 vector<VkWriteDescriptorSet> writesAfterBindVec(0);
1162 int vecIndex = 0;
1163 int numDynamic = 0;
1164
1165 vector<VkDescriptorUpdateTemplateEntry> imgTemplateEntriesBefore, imgTemplateEntriesAfter,
1166 bufTemplateEntriesBefore, bufTemplateEntriesAfter,
1167 texelBufTemplateEntriesBefore, texelBufTemplateEntriesAfter,
1168 inlineTemplateEntriesBefore, inlineTemplateEntriesAfter;
1169
1170 for (size_t b = 0; b < bindings.size(); ++b)
1171 {
1172 VkDescriptorSetLayoutBinding &binding = bindings[b];
1173 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1;
1174
1175 // Construct the declaration for the binding
1176 if (binding.descriptorCount > 0)
1177 {
1178 bool updateAfterBind = !!(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT);
1179 for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement)
1180 {
1181 // Don't access descriptors past the end of the allocated range for
1182 // variable descriptor count
1183 if (b == bindings.size() - 1 &&
1184 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT))
1185 {
1186 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1187 {
1188 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block
1189 const deUint32 uboRange = ai*16 + 16;
1190 if (uboRange >= variableDescriptorSizes[s])
1191 continue;
1192 }
1193 else
1194 {
1195 if (ai >= variableDescriptorSizes[s])
1196 continue;
1197 }
1198 }
1199
1200 // output image
1201 imageInfoVec[vecIndex] = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1202
1203 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1204 {
1205 bufferInfoVec[vecIndex] = makeDescriptorBufferInfo(**buffer, descriptor*align, sizeof(deUint32));
1206 bufferViewVec[vecIndex] = **bufferViews[descriptor];
1207 }
1208
1209 descriptorNumber[descriptor] = descriptor;
1210
1211 VkWriteDescriptorSet w =
1212 {
1213 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1214 DE_NULL, // pNext
1215 *descriptorSets[s], // dstSet
1216 (deUint32)b, // binding
1217 ai, // dstArrayElement
1218 1u, // descriptorCount
1219 binding.descriptorType, // descriptorType
1220 &imageInfoVec[vecIndex], // pImageInfo
1221 &bufferInfoVec[vecIndex], // pBufferInfo
1222 &bufferViewVec[vecIndex], // pTexelBufferView
1223 };
1224
1225 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1226 {
1227 VkWriteDescriptorSetInlineUniformBlockEXT inlineUniformBlock =
1228 {
1229 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT, // VkStructureType sType;
1230 DE_NULL, // const void* pNext;
1231 sizeof(deUint32), // uint32_t dataSize;
1232 &descriptorNumber[descriptor], // const void* pData;
1233 };
1234
1235 inlineInfoVec[vecIndex] = inlineUniformBlock;
1236 w.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy"
1237 w.pNext = &inlineInfoVec[vecIndex];
1238 w.descriptorCount = sizeof(deUint32);
1239 }
1240
1241 VkDescriptorUpdateTemplateEntry templateEntry =
1242 {
1243 (deUint32)b, // uint32_t dstBinding;
1244 ai, // uint32_t dstArrayElement;
1245 1u, // uint32_t descriptorCount;
1246 binding.descriptorType, // VkDescriptorType descriptorType;
1247 0, // size_t offset;
1248 0, // size_t stride;
1249 };
1250
1251 switch (binding.descriptorType)
1252 {
1253 default: DE_ASSERT(0); // Fallthrough
1254 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1255 templateEntry.offset = vecIndex * sizeof(VkDescriptorImageInfo);
1256 (updateAfterBind ? imgTemplateEntriesAfter : imgTemplateEntriesBefore).push_back(templateEntry);
1257 break;
1258 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1259 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1260 templateEntry.offset = vecIndex * sizeof(VkBufferView);
1261 (updateAfterBind ? texelBufTemplateEntriesAfter : texelBufTemplateEntriesBefore).push_back(templateEntry);
1262 break;
1263 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1264 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1265 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1266 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1267 templateEntry.offset = vecIndex * sizeof(VkDescriptorBufferInfo);
1268 (updateAfterBind ? bufTemplateEntriesAfter : bufTemplateEntriesBefore).push_back(templateEntry);
1269 break;
1270 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
1271 templateEntry.offset = descriptor * sizeof(deUint32);
1272 templateEntry.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy"
1273 templateEntry.descriptorCount = sizeof(deUint32);
1274 (updateAfterBind ? inlineTemplateEntriesAfter : inlineTemplateEntriesBefore).push_back(templateEntry);
1275 break;
1276 }
1277
1278 vecIndex++;
1279
1280 (updateAfterBind ? writesAfterBindVec : writesBeforeBindVec).push_back(w);
1281
1282 // Count the number of dynamic descriptors in this set.
1283 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1284 binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
1285 {
1286 numDynamic++;
1287 }
1288 }
1289 }
1290 }
1291
1292 // Make zeros have at least one element so &zeros[0] works
1293 vector<deUint32> zeros(de::max(1,numDynamic));
1294 deMemset(&zeros[0], 0, numDynamic * sizeof(deUint32));
1295
1296 // Randomly select between vkUpdateDescriptorSets and vkUpdateDescriptorSetWithTemplate
1297 if (randRange(&rnd, 1, 2) == 1 &&
1298 m_context.contextSupports(vk::ApiVersion(1, 1, 0)))
1299 {
1300 VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
1301 {
1302 VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, // VkStructureType sType;
1303 NULL, // void* pNext;
1304 0, // VkDescriptorUpdateTemplateCreateFlags flags;
1305 0, // uint32_t descriptorUpdateEntryCount;
1306 DE_NULL, // uint32_t descriptorUpdateEntryCount;
1307 VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, // VkDescriptorUpdateTemplateType templateType;
1308 descriptorSetLayouts[s].get(), // VkDescriptorSetLayout descriptorSetLayout;
1309 bindPoint, // VkPipelineBindPoint pipelineBindPoint;
1310 0, // VkPipelineLayout pipelineLayout;
1311 0, // uint32_t set;
1312 };
1313
1314 void *templateVectorData[] =
1315 {
1316 &imageInfoVec[0],
1317 &bufferInfoVec[0],
1318 &bufferViewVec[0],
1319 &descriptorNumber[0],
1320 };
1321
1322 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsBefore[] =
1323 {
1324 &imgTemplateEntriesBefore,
1325 &bufTemplateEntriesBefore,
1326 &texelBufTemplateEntriesBefore,
1327 &inlineTemplateEntriesBefore,
1328 };
1329
1330 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsAfter[] =
1331 {
1332 &imgTemplateEntriesAfter,
1333 &bufTemplateEntriesAfter,
1334 &texelBufTemplateEntriesAfter,
1335 &inlineTemplateEntriesAfter,
1336 };
1337
1338 for (size_t i = 0; i < sizeof(templateVectorsBefore) / sizeof(templateVectorsBefore[0]); ++i)
1339 {
1340 if (templateVectorsBefore[i]->size())
1341 {
1342 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsBefore[i]->size();
1343 templateCreateInfo.pDescriptorUpdateEntries = &((*templateVectorsBefore[i])[0]);
1344 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
1345 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]);
1346 }
1347 }
1348
1349 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]);
1350
1351 for (size_t i = 0; i < sizeof(templateVectorsAfter) / sizeof(templateVectorsAfter[0]); ++i)
1352 {
1353 if (templateVectorsAfter[i]->size())
1354 {
1355 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsAfter[i]->size();
1356 templateCreateInfo.pDescriptorUpdateEntries = &((*templateVectorsAfter[i])[0]);
1357 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
1358 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]);
1359 }
1360 }
1361
1362 }
1363 else
1364 {
1365 if (writesBeforeBindVec.size())
1366 {
1367 vk.updateDescriptorSets(device, (deUint32)writesBeforeBindVec.size(), &writesBeforeBindVec[0], 0, NULL);
1368 }
1369
1370 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]);
1371
1372 if (writesAfterBindVec.size())
1373 {
1374 vk.updateDescriptorSets(device, (deUint32)writesAfterBindVec.size(), &writesAfterBindVec[0], 0, NULL);
1375 }
1376 }
1377 }
1378
1379 Move<VkPipeline> pipeline;
1380 Move<VkRenderPass> renderPass;
1381 Move<VkFramebuffer> framebuffer;
1382
1383 if (m_data.stage == STAGE_COMPUTE)
1384 {
1385 const Unique<VkShaderModule> shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));
1386
1387 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
1388 {
1389 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1390 DE_NULL,
1391 (VkPipelineShaderStageCreateFlags)0,
1392 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1393 *shader, // shader
1394 "main",
1395 DE_NULL, // pSpecializationInfo
1396 };
1397
1398 const VkComputePipelineCreateInfo pipelineCreateInfo =
1399 {
1400 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1401 DE_NULL,
1402 0u, // flags
1403 shaderCreateInfo, // cs
1404 *pipelineLayout, // layout
1405 (vk::VkPipeline)0, // basePipelineHandle
1406 0u, // basePipelineIndex
1407 };
1408 pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1409 }
1410 else
1411 {
1412
1413 const vk::VkSubpassDescription subpassDesc =
1414 {
1415 (vk::VkSubpassDescriptionFlags)0,
1416 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1417 0u, // inputCount
1418 DE_NULL, // pInputAttachments
1419 0u, // colorCount
1420 DE_NULL, // pColorAttachments
1421 DE_NULL, // pResolveAttachments
1422 DE_NULL, // depthStencilAttachment
1423 0u, // preserveCount
1424 DE_NULL, // pPreserveAttachments
1425 };
1426 const vk::VkRenderPassCreateInfo renderPassParams =
1427 {
1428 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
1429 DE_NULL, // pNext
1430 (vk::VkRenderPassCreateFlags)0,
1431 0u, // attachmentCount
1432 DE_NULL, // pAttachments
1433 1u, // subpassCount
1434 &subpassDesc, // pSubpasses
1435 0u, // dependencyCount
1436 DE_NULL, // pDependencies
1437 };
1438
1439 renderPass = createRenderPass(vk, device, &renderPassParams);
1440
1441 const vk::VkFramebufferCreateInfo framebufferParams =
1442 {
1443 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
1444 DE_NULL, // pNext
1445 (vk::VkFramebufferCreateFlags)0,
1446 *renderPass, // renderPass
1447 0u, // attachmentCount
1448 DE_NULL, // pAttachments
1449 DIM, // width
1450 DIM, // height
1451 1u, // layers
1452 };
1453
1454 framebuffer = createFramebuffer(vk, device, &framebufferParams);
1455
1456 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
1457 {
1458 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1459 DE_NULL, // const void* pNext;
1460 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1461 0u, // deUint32 vertexBindingDescriptionCount;
1462 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1463 0u, // deUint32 vertexAttributeDescriptionCount;
1464 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1465 };
1466
1467 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
1468 {
1469 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1470 DE_NULL, // const void* pNext;
1471 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1472 (m_data.stage == STAGE_VERTEX) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
1473 VK_FALSE // VkBool32 primitiveRestartEnable;
1474 };
1475
1476 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1477 {
1478 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1479 DE_NULL, // const void* pNext;
1480 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1481 VK_FALSE, // VkBool32 depthClampEnable;
1482 (m_data.stage == STAGE_VERTEX) ? VK_TRUE : VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1483 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1484 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1485 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1486 VK_FALSE, // VkBool32 depthBiasEnable;
1487 0.0f, // float depthBiasConstantFactor;
1488 0.0f, // float depthBiasClamp;
1489 0.0f, // float depthBiasSlopeFactor;
1490 1.0f // float lineWidth;
1491 };
1492
1493 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
1494 {
1495 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1496 DE_NULL, // const void* pNext
1497 0u, // VkPipelineMultisampleStateCreateFlags flags
1498 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
1499 VK_FALSE, // VkBool32 sampleShadingEnable
1500 1.0f, // float minSampleShading
1501 DE_NULL, // const VkSampleMask* pSampleMask
1502 VK_FALSE, // VkBool32 alphaToCoverageEnable
1503 VK_FALSE // VkBool32 alphaToOneEnable
1504 };
1505
1506 VkViewport viewport = makeViewport(DIM, DIM);
1507 VkRect2D scissor = makeRect2D(DIM, DIM);
1508
1509 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
1510 {
1511 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1512 DE_NULL, // const void* pNext
1513 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1514 1u, // deUint32 viewportCount
1515 &viewport, // const VkViewport* pViewports
1516 1u, // deUint32 scissorCount
1517 &scissor // const VkRect2D* pScissors
1518 };
1519
1520 Move<VkShaderModule> fs;
1521 Move<VkShaderModule> vs;
1522
1523 deUint32 numStages;
1524 if (m_data.stage == STAGE_VERTEX)
1525 {
1526 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
1527 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); // bogus
1528 numStages = 1u;
1529 }
1530 else
1531 {
1532 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
1533 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
1534 numStages = 2u;
1535 }
1536
1537 const VkPipelineShaderStageCreateInfo shaderCreateInfo[2] =
1538 {
1539 {
1540 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1541 DE_NULL,
1542 (VkPipelineShaderStageCreateFlags)0,
1543 VK_SHADER_STAGE_VERTEX_BIT, // stage
1544 *vs, // shader
1545 "main",
1546 DE_NULL, // pSpecializationInfo
1547 },
1548 {
1549 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1550 DE_NULL,
1551 (VkPipelineShaderStageCreateFlags)0,
1552 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1553 *fs, // shader
1554 "main",
1555 DE_NULL, // pSpecializationInfo
1556 }
1557 };
1558
1559 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
1560 {
1561 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1562 DE_NULL, // const void* pNext;
1563 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1564 numStages, // deUint32 stageCount;
1565 &shaderCreateInfo[0], // const VkPipelineShaderStageCreateInfo* pStages;
1566 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1567 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1568 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1569 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
1570 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1571 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1572 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1573 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1574 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1575 pipelineLayout.get(), // VkPipelineLayout layout;
1576 renderPass.get(), // VkRenderPass renderPass;
1577 0u, // deUint32 subpass;
1578 DE_NULL, // VkPipeline basePipelineHandle;
1579 0 // int basePipelineIndex;
1580 };
1581
1582 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
1583 }
1584
1585 const VkImageMemoryBarrier imageBarrier =
1586 {
1587 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1588 DE_NULL, // const void* pNext
1589 0u, // VkAccessFlags srcAccessMask
1590 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1591 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1592 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1593 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1594 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1595 **image, // VkImage image
1596 {
1597 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1598 0u, // uint32_t baseMipLevel
1599 1u, // uint32_t mipLevels,
1600 0u, // uint32_t baseArray
1601 1u, // uint32_t arraySize
1602 }
1603 };
1604
1605 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1606 (VkDependencyFlags)0,
1607 0, (const VkMemoryBarrier*)DE_NULL,
1608 0, (const VkBufferMemoryBarrier*)DE_NULL,
1609 1, &imageBarrier);
1610
1611 vk.cmdBindPipeline(*cmdBuffer, bindPoint, *pipeline);
1612
1613 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1614 VkClearValue clearColor = makeClearValueColorU32(0,0,0,0);
1615
1616 VkMemoryBarrier memBarrier =
1617 {
1618 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
1619 DE_NULL, // pNext
1620 0u, // srcAccessMask
1621 0u, // dstAccessMask
1622 };
1623
1624 vk.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
1625
1626 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1627 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
1628 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
1629 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1630
1631 if (m_data.stage == STAGE_COMPUTE)
1632 {
1633 vk.cmdDispatch(*cmdBuffer, DIM, DIM, 1);
1634 }
1635 else
1636 {
1637 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
1638 makeRect2D(DIM, DIM),
1639 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1640 // Draw a point cloud for vertex shader testing, and a single quad for fragment shader testing
1641 if (m_data.stage == STAGE_VERTEX)
1642 {
1643 vk.cmdDraw(*cmdBuffer, DIM*DIM, 1u, 0u, 0u);
1644 }
1645 else
1646 {
1647 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
1648 }
1649 endRenderPass(vk, *cmdBuffer);
1650 }
1651
1652 memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
1653 memBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
1654 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, VK_PIPELINE_STAGE_TRANSFER_BIT,
1655 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1656
1657 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(DIM, DIM, 1u),
1658 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1659 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **copyBuffer, 1u, ©Region);
1660
1661 endCommandBuffer(vk, *cmdBuffer);
1662
1663 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1664
1665 deUint32 *ptr = (deUint32 *)copyBuffer->getAllocation().getHostPtr();
1666 invalidateMappedMemoryRange(vk, device, copyBuffer->getAllocation().getMemory(), copyBuffer->getAllocation().getOffset(), DIM*DIM*sizeof(deUint32));
1667
1668 qpTestResult res = QP_TEST_RESULT_PASS;
1669
1670 for (deUint32 i = 0; i < DIM*DIM; ++i)
1671 {
1672 if (ptr[i] != 1)
1673 {
1674 res = QP_TEST_RESULT_FAIL;
1675 }
1676 }
1677
1678 return tcu::TestStatus(res, qpGetTestResultName(res));
1679 }
1680
1681 } // anonymous
1682
createDescriptorSetRandomTests(tcu::TestContext & testCtx)1683 tcu::TestCaseGroup* createDescriptorSetRandomTests (tcu::TestContext& testCtx)
1684 {
1685 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "descriptorset_random", "Randomly-generated desciptor set layouts"));
1686
1687 deUint32 seed = 0;
1688
1689 typedef struct
1690 {
1691 deUint32 count;
1692 const char* name;
1693 const char* description;
1694 } TestGroupCase;
1695
1696 TestGroupCase setsCases[] =
1697 {
1698 { 4, "sets4", "4 descriptor sets" },
1699 { 8, "sets8", "8 descriptor sets" },
1700 { 16, "sets16", "16 descriptor sets" },
1701 { 32, "sets32", "32 descriptor sets" },
1702 };
1703
1704 TestGroupCase indexCases[] =
1705 {
1706 { INDEX_TYPE_NONE, "noarray", "all descriptor declarations are not arrays" },
1707 { INDEX_TYPE_CONSTANT, "constant", "constant indexing of descriptor arrays" },
1708 { INDEX_TYPE_PUSHCONSTANT, "unifindexed", "indexing descriptor arrays with push constants" },
1709 { INDEX_TYPE_DEPENDENT, "dynindexed", "dynamically uniform indexing descriptor arrays" },
1710 { INDEX_TYPE_RUNTIME_SIZE, "runtimesize", "runtime-size declarations of descriptor arrays" },
1711 };
1712
1713 TestGroupCase uboCases[] =
1714 {
1715 { 12, "ubolimitlow", "spec minmax ubo limit" },
1716 { 4096, "ubolimithigh", "high ubo limit" },
1717 };
1718
1719 TestGroupCase sboCases[] =
1720 {
1721 { 4, "sbolimitlow", "spec minmax ssbo limit" },
1722 { 4096, "sbolimithigh", "high ssbo limit" },
1723 };
1724
1725 static const struct
1726 {
1727 deUint32 texCount;
1728 deUint32 imgCount;
1729 const char* name;
1730 const char* description;
1731 } imgCases[] =
1732 {
1733 { 16, 4, "imglimitlow", "spec minmax image limit" },
1734 { 4096, 4096, "imglimithigh", "high image limit" },
1735 };
1736
1737 static const struct
1738 {
1739 deUint32 iubCount;
1740 deUint32 iubSize;
1741 const char* name;
1742 const char* description;
1743 } iubCases[] =
1744 {
1745 { 0, 0, "noiub", "no inline_uniform_block" },
1746 { 4, 256, "iublimitlow", "inline_uniform_block low limit" },
1747 { 8, 4096, "iublimithigh", "inline_uniform_block high limit" },
1748 };
1749
1750 TestGroupCase stageCases[] =
1751 {
1752 { STAGE_COMPUTE, "comp", "compute" },
1753 { STAGE_FRAGMENT, "frag", "fragment" },
1754 { STAGE_VERTEX, "vert", "vertex" },
1755 };
1756
1757 TestGroupCase uabCases[] =
1758 {
1759 { UPDATE_AFTER_BIND_DISABLED, "nouab", "no update after bind" },
1760 };
1761
1762 for (int setsNdx = 0; setsNdx < DE_LENGTH_OF_ARRAY(setsCases); setsNdx++)
1763 {
1764 de::MovePtr<tcu::TestCaseGroup> setsGroup(new tcu::TestCaseGroup(testCtx, setsCases[setsNdx].name, setsCases[setsNdx].description));
1765 for (int indexNdx = 0; indexNdx < DE_LENGTH_OF_ARRAY(indexCases); indexNdx++)
1766 {
1767 de::MovePtr<tcu::TestCaseGroup> indexGroup(new tcu::TestCaseGroup(testCtx, indexCases[indexNdx].name, indexCases[indexNdx].description));
1768 for (int uboNdx = 0; uboNdx < DE_LENGTH_OF_ARRAY(uboCases); uboNdx++)
1769 {
1770 de::MovePtr<tcu::TestCaseGroup> uboGroup(new tcu::TestCaseGroup(testCtx, uboCases[uboNdx].name, uboCases[uboNdx].description));
1771 for (int sboNdx = 0; sboNdx < DE_LENGTH_OF_ARRAY(sboCases); sboNdx++)
1772 {
1773 de::MovePtr<tcu::TestCaseGroup> sboGroup(new tcu::TestCaseGroup(testCtx, sboCases[sboNdx].name, sboCases[sboNdx].description));
1774 for (int imgNdx = 0; imgNdx < DE_LENGTH_OF_ARRAY(imgCases); imgNdx++)
1775 {
1776 de::MovePtr<tcu::TestCaseGroup> imgGroup(new tcu::TestCaseGroup(testCtx, imgCases[imgNdx].name, imgCases[imgNdx].description));
1777 for (int iubNdx = 0; iubNdx < DE_LENGTH_OF_ARRAY(iubCases); iubNdx++)
1778 {
1779 de::MovePtr<tcu::TestCaseGroup> iubGroup(new tcu::TestCaseGroup(testCtx, iubCases[iubNdx].name, iubCases[iubNdx].description));
1780 for (int uabNdx = 0; uabNdx < DE_LENGTH_OF_ARRAY(uabCases); uabNdx++)
1781 {
1782 de::MovePtr<tcu::TestCaseGroup> uabGroup(new tcu::TestCaseGroup(testCtx, uabCases[uabNdx].name, uabCases[uabNdx].description));
1783 bool updateAfterBind = (UpdateAfterBind)uabCases[uabNdx].count == UPDATE_AFTER_BIND_ENABLED;
1784 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stageCases); stageNdx++)
1785 {
1786 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stageCases[stageNdx].name, stageCases[stageNdx].description));
1787 deUint32 numSeeds = (setsCases[setsNdx].count == 4 && uboNdx == 0 && sboNdx == 0 && imgNdx == 0 && iubNdx == 0) ? 10 : 1;
1788 for (deUint32 rnd = 0; rnd < numSeeds; ++rnd)
1789 {
1790 CaseDef c =
1791 {
1792 (IndexType)indexCases[indexNdx].count, // IndexType indexType;
1793 setsCases[setsNdx].count, // deUint32 numDescriptorSets;
1794 uboCases[uboNdx].count, // deUint32 maxPerStageUniformBuffers;
1795 8, // deUint32 maxUniformBuffersDynamic;
1796 sboCases[sboNdx].count, // deUint32 maxPerStageStorageBuffers;
1797 4, // deUint32 maxStorageBuffersDynamic;
1798 imgCases[imgNdx].texCount, // deUint32 maxPerStageSampledImages;
1799 imgCases[imgNdx].imgCount, // deUint32 maxPerStageStorageImages;
1800 iubCases[iubNdx].iubCount, // deUint32 maxInlineUniformBlocks;
1801 iubCases[iubNdx].iubSize, // deUint32 maxInlineUniformBlockSize;
1802 (Stage)stageCases[stageNdx].count, // Stage stage;
1803 (UpdateAfterBind)uabCases[uabNdx].count, // UpdateAfterBind uab;
1804 seed++, // deUint32 seed;
1805 };
1806
1807 string name = de::toString(rnd);
1808 stageGroup->addChild(new DescriptorSetRandomTestCase(testCtx, name.c_str(), "test", c));
1809 }
1810 (updateAfterBind ? uabGroup : iubGroup)->addChild(stageGroup.release());
1811 }
1812 if (updateAfterBind)
1813 {
1814 iubGroup->addChild(uabGroup.release());
1815 }
1816 }
1817 imgGroup->addChild(iubGroup.release());
1818 }
1819 sboGroup->addChild(imgGroup.release());
1820 }
1821 uboGroup->addChild(sboGroup.release());
1822 }
1823 indexGroup->addChild(uboGroup.release());
1824 }
1825 setsGroup->addChild(indexGroup.release());
1826 }
1827 group->addChild(setsGroup.release());
1828 }
1829 return group.release();
1830 }
1831
1832 } // BindingModel
1833 } // vkt
1834