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 "vkObjUtil.hpp"
46 #include "vkRayTracingUtil.hpp"
47
48 #include "vktTestGroupUtil.hpp"
49 #include "vktTestCase.hpp"
50
51 #include "deDefs.h"
52 #include "deMath.h"
53 #include "deRandom.h"
54 #include "deSharedPtr.hpp"
55 #include "deString.h"
56
57 #include "tcuTestCase.hpp"
58 #include "tcuTestLog.hpp"
59
60 #include <string>
61 #include <sstream>
62 #include <algorithm>
63 #include <map>
64 #include <utility>
65 #include <memory>
66
67 namespace vkt
68 {
69 namespace BindingModel
70 {
71 namespace
72 {
73 using namespace vk;
74 using namespace std;
75
76 static const deUint32 DIM = 8;
77
78 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
79 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
80 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
81 | VK_SHADER_STAGE_MISS_BIT_KHR
82 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
83 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
84
85 typedef enum
86 {
87 INDEX_TYPE_NONE = 0,
88 INDEX_TYPE_CONSTANT,
89 INDEX_TYPE_PUSHCONSTANT,
90 INDEX_TYPE_DEPENDENT,
91 INDEX_TYPE_RUNTIME_SIZE,
92 } IndexType;
93
94 typedef enum
95 {
96 STAGE_COMPUTE = 0,
97 STAGE_VERTEX,
98 STAGE_FRAGMENT,
99 STAGE_RAYGEN_NV,
100 STAGE_RAYGEN,
101 STAGE_INTERSECT,
102 STAGE_ANY_HIT,
103 STAGE_CLOSEST_HIT,
104 STAGE_MISS,
105 STAGE_CALLABLE,
106 } Stage;
107
108 typedef enum
109 {
110 UPDATE_AFTER_BIND_DISABLED = 0,
111 UPDATE_AFTER_BIND_ENABLED,
112 } UpdateAfterBind;
113
114 struct DescriptorId
115 {
DescriptorIdvkt::BindingModel::__anon99d916290111::DescriptorId116 DescriptorId (deUint32 set_, deUint32 binding_, deUint32 number_)
117 : set(set_), binding(binding_), number(number_)
118 {}
119
operator <vkt::BindingModel::__anon99d916290111::DescriptorId120 bool operator< (const DescriptorId& other) const
121 {
122 return (set < other.set || (set == other.set && (binding < other.binding || (binding == other.binding && number < other.number))));
123 }
124
125 deUint32 set;
126 deUint32 binding;
127 deUint32 number;
128 };
129
130 struct WriteInfo
131 {
WriteInfovkt::BindingModel::__anon99d916290111::WriteInfo132 WriteInfo () : ptr(nullptr), expected(0u), writeGenerated(false) {}
133
134 deInt32* ptr;
135 deInt32 expected;
136 bool writeGenerated;
137 };
138
isRayTracingStageKHR(const Stage stage)139 bool isRayTracingStageKHR (const Stage stage)
140 {
141 switch (stage)
142 {
143 case STAGE_COMPUTE:
144 case STAGE_VERTEX:
145 case STAGE_FRAGMENT:
146 case STAGE_RAYGEN_NV:
147 return false;
148
149 case STAGE_RAYGEN:
150 case STAGE_INTERSECT:
151 case STAGE_ANY_HIT:
152 case STAGE_CLOSEST_HIT:
153 case STAGE_MISS:
154 case STAGE_CALLABLE:
155 return true;
156
157 default: TCU_THROW(InternalError, "Unknown stage specified");
158 }
159 }
160
getShaderStageFlag(const Stage stage)161 VkShaderStageFlagBits getShaderStageFlag (const Stage stage)
162 {
163 switch (stage)
164 {
165 case STAGE_RAYGEN: return VK_SHADER_STAGE_RAYGEN_BIT_KHR;
166 case STAGE_ANY_HIT: return VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
167 case STAGE_CLOSEST_HIT: return VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
168 case STAGE_MISS: return VK_SHADER_STAGE_MISS_BIT_KHR;
169 case STAGE_INTERSECT: return VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
170 case STAGE_CALLABLE: return VK_SHADER_STAGE_CALLABLE_BIT_KHR;
171 default: TCU_THROW(InternalError, "Unknown stage specified");
172 }
173 }
174
usesAccelerationStructure(const Stage stage)175 bool usesAccelerationStructure (const Stage stage)
176 {
177 return (isRayTracingStageKHR(stage) && stage != STAGE_RAYGEN && stage != STAGE_CALLABLE);
178 }
179
180 class RandomLayout
181 {
182 public:
RandomLayout(deUint32 numSets)183 RandomLayout(deUint32 numSets) :
184 layoutBindings(numSets),
185 layoutBindingFlags(numSets),
186 arraySizes(numSets),
187 variableDescriptorSizes(numSets)
188 {
189 }
190
191 // These three are indexed by [set][binding]
192 vector<vector<VkDescriptorSetLayoutBinding> > layoutBindings;
193 vector<vector<VkDescriptorBindingFlags> > layoutBindingFlags;
194 vector<vector<deUint32> > arraySizes;
195 // size of the variable descriptor (last) binding in each set
196 vector<deUint32> variableDescriptorSizes;
197
198 // List of descriptors that will write the descriptor value instead of reading it.
199 map<DescriptorId, WriteInfo> descriptorWrites;
200
201 };
202
203 struct CaseDef
204 {
205 IndexType indexType;
206 deUint32 numDescriptorSets;
207 deUint32 maxPerStageUniformBuffers;
208 deUint32 maxUniformBuffersDynamic;
209 deUint32 maxPerStageStorageBuffers;
210 deUint32 maxStorageBuffersDynamic;
211 deUint32 maxPerStageSampledImages;
212 deUint32 maxPerStageStorageImages;
213 deUint32 maxPerStageStorageTexelBuffers;
214 deUint32 maxInlineUniformBlocks;
215 deUint32 maxInlineUniformBlockSize;
216 deUint32 maxPerStageInputAttachments;
217 Stage stage;
218 UpdateAfterBind uab;
219 deUint32 seed;
220 VkFlags allShaderStages;
221 VkFlags allPipelineStages;
222 // Shared by the test case and the test instance.
223 std::shared_ptr<RandomLayout> randomLayout;
224 };
225
226
227 class DescriptorSetRandomTestInstance : public TestInstance
228 {
229 public:
230 DescriptorSetRandomTestInstance (Context& context, const std::shared_ptr<CaseDef>& data);
231 ~DescriptorSetRandomTestInstance (void);
232 tcu::TestStatus iterate (void);
233 private:
234 // Shared pointer because the test case and the test instance need to share the random layout information. Specifically, the
235 // descriptorWrites map, which is filled from the test case and used by the test instance.
236 std::shared_ptr<CaseDef> m_data_ptr;
237 CaseDef& m_data;
238 };
239
DescriptorSetRandomTestInstance(Context & context,const std::shared_ptr<CaseDef> & data)240 DescriptorSetRandomTestInstance::DescriptorSetRandomTestInstance (Context& context, const std::shared_ptr<CaseDef>& data)
241 : vkt::TestInstance (context)
242 , m_data_ptr (data)
243 , m_data (*m_data_ptr.get())
244 {
245 }
246
~DescriptorSetRandomTestInstance(void)247 DescriptorSetRandomTestInstance::~DescriptorSetRandomTestInstance (void)
248 {
249 }
250
251 class DescriptorSetRandomTestCase : public TestCase
252 {
253 public:
254 DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef& data);
255 ~DescriptorSetRandomTestCase (void);
256 virtual void initPrograms (SourceCollections& programCollection) const;
257 virtual TestInstance* createInstance (Context& context) const;
258 virtual void checkSupport (Context& context) const;
259
260 private:
261 // See DescriptorSetRandomTestInstance about the need for a shared pointer here.
262 std::shared_ptr<CaseDef> m_data_ptr;
263 CaseDef& m_data;
264 };
265
DescriptorSetRandomTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef & data)266 DescriptorSetRandomTestCase::DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef& data)
267 : vkt::TestCase (context, name, desc)
268 , m_data_ptr (std::make_shared<CaseDef>(data))
269 , m_data (*reinterpret_cast<CaseDef*>(m_data_ptr.get()))
270 {
271 }
272
~DescriptorSetRandomTestCase(void)273 DescriptorSetRandomTestCase::~DescriptorSetRandomTestCase (void)
274 {
275 }
276
checkSupport(Context & context) const277 void DescriptorSetRandomTestCase::checkSupport(Context& context) const
278 {
279 // Get needed properties.
280 VkPhysicalDeviceInlineUniformBlockPropertiesEXT inlineUniformProperties;
281 deMemset(&inlineUniformProperties, 0, sizeof(inlineUniformProperties));
282 inlineUniformProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT;
283
284 VkPhysicalDeviceProperties2 properties;
285 deMemset(&properties, 0, sizeof(properties));
286 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
287 void** pNextTail = &properties.pNext;
288
289 if (context.isDeviceFunctionalitySupported("VK_EXT_inline_uniform_block"))
290 {
291 *pNextTail = &inlineUniformProperties;
292 pNextTail = &inlineUniformProperties.pNext;
293 }
294 *pNextTail = NULL;
295
296 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
297
298 // Get needed features.
299 auto features = context.getDeviceFeatures2();
300 auto indexingFeatures = context.getDescriptorIndexingFeatures();
301 auto inlineUniformFeatures = context.getInlineUniformBlockFeaturesEXT();
302
303 // Check needed properties and features
304 if (m_data.stage == STAGE_VERTEX && !features.features.vertexPipelineStoresAndAtomics)
305 {
306 TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
307 }
308 else if (m_data.stage == STAGE_RAYGEN_NV)
309 {
310 context.requireDeviceFunctionality("VK_NV_ray_tracing");
311 }
312 else if (isRayTracingStageKHR(m_data.stage))
313 {
314 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
315 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
316
317 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
318 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
319 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
320
321 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
322 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
323 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
324 }
325
326 // Note binding 0 in set 0 is the output storage image, always present and not subject to dynamic indexing.
327 if ((m_data.indexType == INDEX_TYPE_PUSHCONSTANT ||
328 m_data.indexType == INDEX_TYPE_DEPENDENT ||
329 m_data.indexType == INDEX_TYPE_RUNTIME_SIZE) &&
330 ((m_data.maxPerStageUniformBuffers > 0u && !features.features.shaderUniformBufferArrayDynamicIndexing) ||
331 (m_data.maxPerStageStorageBuffers > 0u && !features.features.shaderStorageBufferArrayDynamicIndexing) ||
332 (m_data.maxPerStageStorageImages > 1u && !features.features.shaderStorageImageArrayDynamicIndexing) ||
333 (m_data.stage == STAGE_FRAGMENT && m_data.maxPerStageInputAttachments > 0u && (!indexingFeatures.shaderInputAttachmentArrayDynamicIndexing)) ||
334 (m_data.maxPerStageSampledImages > 0u && !indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing) ||
335 (m_data.maxPerStageStorageTexelBuffers > 0u && !indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing)))
336 {
337 TCU_THROW(NotSupportedError, "Dynamic indexing not supported");
338 }
339
340 if (m_data.numDescriptorSets > properties.properties.limits.maxBoundDescriptorSets)
341 {
342 TCU_THROW(NotSupportedError, "Number of descriptor sets not supported");
343 }
344
345 if ((m_data.maxPerStageUniformBuffers + m_data.maxPerStageStorageBuffers +
346 m_data.maxPerStageSampledImages + m_data.maxPerStageStorageImages +
347 m_data.maxPerStageStorageTexelBuffers + m_data.maxPerStageInputAttachments) >
348 properties.properties.limits.maxPerStageResources)
349 {
350 TCU_THROW(NotSupportedError, "Number of descriptors not supported");
351 }
352
353 if (m_data.maxPerStageUniformBuffers > properties.properties.limits.maxPerStageDescriptorUniformBuffers ||
354 m_data.maxPerStageStorageBuffers > properties.properties.limits.maxPerStageDescriptorStorageBuffers ||
355 m_data.maxUniformBuffersDynamic > properties.properties.limits.maxDescriptorSetUniformBuffersDynamic ||
356 m_data.maxStorageBuffersDynamic > properties.properties.limits.maxDescriptorSetStorageBuffersDynamic ||
357 m_data.maxPerStageSampledImages > properties.properties.limits.maxPerStageDescriptorSampledImages ||
358 (m_data.maxPerStageStorageImages +
359 m_data.maxPerStageStorageTexelBuffers) > properties.properties.limits.maxPerStageDescriptorStorageImages ||
360 m_data.maxPerStageInputAttachments > properties.properties.limits.maxPerStageDescriptorInputAttachments)
361 {
362 TCU_THROW(NotSupportedError, "Number of descriptors not supported");
363 }
364
365 if (m_data.maxInlineUniformBlocks != 0 &&
366 !inlineUniformFeatures.inlineUniformBlock)
367 {
368 TCU_THROW(NotSupportedError, "Inline uniform blocks not supported");
369 }
370
371 if (m_data.maxInlineUniformBlocks > inlineUniformProperties.maxPerStageDescriptorInlineUniformBlocks)
372 {
373 TCU_THROW(NotSupportedError, "Number of inline uniform blocks not supported");
374 }
375
376 if (m_data.maxInlineUniformBlocks != 0 &&
377 m_data.maxInlineUniformBlockSize > inlineUniformProperties.maxInlineUniformBlockSize)
378 {
379 TCU_THROW(NotSupportedError, "Inline uniform block size not supported");
380 }
381
382 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE &&
383 !indexingFeatures.runtimeDescriptorArray)
384 {
385 TCU_THROW(NotSupportedError, "runtimeDescriptorArray not supported");
386 }
387 }
388
389 // Return a random value in the range [min, max]
randRange(deRandom * rnd,deInt32 min,deInt32 max)390 deInt32 randRange(deRandom *rnd, deInt32 min, deInt32 max)
391 {
392 if (max < 0)
393 return 0;
394
395 return (deRandom_getUint32(rnd) % (max - min + 1)) + min;
396 }
397
chooseWritesRandomly(vk::VkDescriptorType type,RandomLayout & randomLayout,deRandom & rnd,deUint32 set,deUint32 binding,deUint32 count)398 void chooseWritesRandomly(vk::VkDescriptorType type, RandomLayout& randomLayout, deRandom& rnd, deUint32 set, deUint32 binding, deUint32 count)
399 {
400 // Make sure the type supports writes.
401 switch (type)
402 {
403 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
404 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
405 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
406 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
407 break;
408 default:
409 DE_ASSERT(false);
410 break;
411 }
412
413 for (deUint32 i = 0u; i < count; ++i)
414 {
415 // 1/2 chance of being a write.
416 if (randRange(&rnd, 1, 2) == 1)
417 randomLayout.descriptorWrites[DescriptorId(set, binding, i)] = {};
418 }
419 }
420
generateRandomLayout(RandomLayout & randomLayout,const CaseDef & caseDef,deRandom & rnd)421 void generateRandomLayout(RandomLayout& randomLayout, const CaseDef &caseDef, deRandom& rnd)
422 {
423 // Count the number of each resource type, to avoid overflowing the limits.
424 deUint32 numUBO = 0;
425 deUint32 numUBODyn = 0;
426 deUint32 numSSBO = 0;
427 deUint32 numSSBODyn = 0;
428 deUint32 numImage = 0;
429 deUint32 numStorageTex = 0;
430 deUint32 numTexBuffer = 0;
431 deUint32 numInlineUniformBlocks = 0;
432 deUint32 numInputAttachments = 0;
433
434 // TODO: Consider varying these
435 deUint32 minBindings = 0;
436 // Try to keep the workload roughly constant while exercising higher numbered sets.
437 deUint32 maxBindings = 128u / caseDef.numDescriptorSets;
438 // No larger than 32 elements for dynamic indexing tests, due to 128B limit
439 // for push constants (used for the indices)
440 deUint32 maxArray = caseDef.indexType == INDEX_TYPE_NONE ? 0 : 32;
441
442 // Each set has a random number of bindings, each binding has a random
443 // array size and a random descriptor type.
444 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
445 {
446 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
447 vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
448 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
449 int numBindings = randRange(&rnd, minBindings, maxBindings);
450
451 // Guarantee room for the output image
452 if (s == 0 && numBindings == 0)
453 {
454 numBindings = 1;
455 }
456 // Guarantee room for the raytracing acceleration structure
457 if (s == 0 && numBindings < 2 && usesAccelerationStructure(caseDef.stage))
458 {
459 numBindings = 2;
460 }
461
462 bindings = vector<VkDescriptorSetLayoutBinding>(numBindings);
463 bindingsFlags = vector<VkDescriptorBindingFlags>(numBindings);
464 arraySizes = vector<deUint32>(numBindings);
465 }
466
467 // BUFFER_DYNAMIC descriptor types cannot be used with VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bindings in one set
468 bool allowDynamicBuffers = caseDef.uab != UPDATE_AFTER_BIND_ENABLED;
469
470 // Iterate over bindings first, then over sets. This prevents the low-limit bindings
471 // from getting clustered in low-numbered sets.
472 for (deUint32 b = 0; b <= maxBindings; ++b)
473 {
474 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
475 {
476 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
477 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
478
479 if (b >= bindings.size())
480 {
481 continue;
482 }
483
484 VkDescriptorSetLayoutBinding &binding = bindings[b];
485 binding.binding = b;
486 binding.pImmutableSamplers = NULL;
487 binding.stageFlags = caseDef.allShaderStages;
488
489 // Output image
490 if (s == 0 && b == 0)
491 {
492 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
493 binding.descriptorCount = 1;
494 binding.stageFlags = caseDef.allShaderStages;
495 numImage++;
496 arraySizes[b] = 0;
497 continue;
498 }
499
500 // Raytracing acceleration structure
501 if (s == 0 && b == 1 && usesAccelerationStructure(caseDef.stage))
502 {
503 binding.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
504 binding.descriptorCount = 1;
505 binding.stageFlags = caseDef.allShaderStages;
506 arraySizes[b] = 0;
507 continue;
508 }
509
510 binding.descriptorCount = 0;
511
512 // Select a random type of descriptor.
513 std::map<int, vk::VkDescriptorType> intToType;
514 {
515 int index = 0;
516 intToType[index++] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
517 intToType[index++] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
518 intToType[index++] = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
519 intToType[index++] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
520 intToType[index++] = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
521 intToType[index++] = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
522 if (caseDef.stage == STAGE_FRAGMENT)
523 {
524 intToType[index++] = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
525 }
526 if (allowDynamicBuffers)
527 {
528 intToType[index++] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
529 intToType[index++] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
530 }
531 }
532
533 int r = randRange(&rnd, 0, static_cast<int>(intToType.size() - 1));
534 DE_ASSERT(r >= 0 && static_cast<size_t>(r) < intToType.size());
535
536 // Add a binding for that descriptor type if possible.
537 binding.descriptorType = intToType[r];
538 switch (binding.descriptorType)
539 {
540 default: DE_ASSERT(0); // Fallthrough
541 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
542 if (numUBO < caseDef.maxPerStageUniformBuffers)
543 {
544 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageUniformBuffers - numUBO));
545 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
546 numUBO += binding.descriptorCount;
547 }
548 break;
549 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
550 if (numSSBO < caseDef.maxPerStageStorageBuffers)
551 {
552 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageBuffers - numSSBO));
553 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
554 numSSBO += binding.descriptorCount;
555
556 chooseWritesRandomly(binding.descriptorType, randomLayout, rnd, s, b, binding.descriptorCount);
557 }
558 break;
559 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
560 if (numStorageTex < caseDef.maxPerStageStorageTexelBuffers)
561 {
562 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageTexelBuffers - numStorageTex));
563 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
564 numStorageTex += binding.descriptorCount;
565
566 chooseWritesRandomly(binding.descriptorType, randomLayout, rnd, s, b, binding.descriptorCount);
567 }
568 break;
569 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
570 if (numImage < caseDef.maxPerStageStorageImages)
571 {
572 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageImages - numImage));
573 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
574 numImage += binding.descriptorCount;
575
576 chooseWritesRandomly(binding.descriptorType, randomLayout, rnd, s, b, binding.descriptorCount);
577 }
578 break;
579 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
580 if (numTexBuffer < caseDef.maxPerStageSampledImages)
581 {
582 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageSampledImages - numTexBuffer));
583 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
584 numTexBuffer += binding.descriptorCount;
585 }
586 break;
587 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
588 if (caseDef.maxInlineUniformBlocks > 0)
589 {
590 if (numInlineUniformBlocks < caseDef.maxInlineUniformBlocks)
591 {
592 arraySizes[b] = randRange(&rnd, 1, (caseDef.maxInlineUniformBlockSize - 16) / 16); // subtract 16 for "ivec4 dummy"
593 arraySizes[b] = de::min(maxArray, arraySizes[b]);
594 binding.descriptorCount = (arraySizes[b] ? arraySizes[b] : 1) * 16 + 16; // add 16 for "ivec4 dummy"
595 numInlineUniformBlocks++;
596 }
597 }
598 else
599 {
600 // Plug in a dummy descriptor type, so validation layers that don't
601 // support inline_uniform_block don't crash.
602 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
603 }
604 break;
605 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
606 if (numUBODyn < caseDef.maxUniformBuffersDynamic &&
607 numUBO < caseDef.maxPerStageUniformBuffers)
608 {
609 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxUniformBuffersDynamic - numUBODyn,
610 caseDef.maxPerStageUniformBuffers - numUBO)));
611 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
612 numUBO += binding.descriptorCount;
613 numUBODyn += binding.descriptorCount;
614 }
615 break;
616 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
617 if (numSSBODyn < caseDef.maxStorageBuffersDynamic &&
618 numSSBO < caseDef.maxPerStageStorageBuffers)
619 {
620 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxStorageBuffersDynamic - numSSBODyn,
621 caseDef.maxPerStageStorageBuffers - numSSBO)));
622 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
623 numSSBO += binding.descriptorCount;
624 numSSBODyn += binding.descriptorCount;
625
626 chooseWritesRandomly(binding.descriptorType, randomLayout, rnd, s, b, binding.descriptorCount);
627 }
628 break;
629 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
630 if (numInputAttachments < caseDef.maxPerStageInputAttachments)
631 {
632 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageInputAttachments - numInputAttachments));
633 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1;
634 numInputAttachments += binding.descriptorCount;
635 }
636 break;
637 }
638
639 binding.stageFlags = ((binding.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ? (VkFlags)(VK_SHADER_STAGE_FRAGMENT_BIT) : caseDef.allShaderStages);
640 }
641 }
642
643 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s)
644 {
645 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
646 vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
647 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
648
649 // Choose a variable descriptor count size. If the feature is not supported, we'll just
650 // allocate the whole thing later on.
651 if (bindings.size() > 0 &&
652 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
653 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC &&
654 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT &&
655 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR &&
656 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
657 !(s == 0 && bindings.size() == 1) && // Don't cut out the output image binding
658 randRange(&rnd, 1,4) == 1) // 1 in 4 chance
659 {
660
661 bindingsFlags[bindings.size()-1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
662 variableDescriptorSizes[s] = randRange(&rnd, 0,bindings[bindings.size()-1].descriptorCount);
663 if (bindings[bindings.size()-1].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
664 {
665 // keep a multiple of 16B
666 variableDescriptorSizes[s] &= ~0xF;
667 }
668 }
669 }
670 }
671
672 class CheckDecider
673 {
674 public:
CheckDecider(deRandom & rnd,deUint32 descriptorCount)675 CheckDecider (deRandom& rnd, deUint32 descriptorCount)
676 : m_rnd(rnd)
677 , m_count(descriptorCount)
678 , m_remainder(0u)
679 , m_have_remainder(false)
680 {
681 }
682
shouldCheck(deUint32 arrayIndex)683 bool shouldCheck (deUint32 arrayIndex)
684 {
685 // Always check the first 3 and the last one, at least.
686 if (arrayIndex <= 2u || arrayIndex == m_count - 1u)
687 return true;
688
689 if (!m_have_remainder)
690 {
691 // Find a random remainder for this set and binding.
692 DE_ASSERT(m_count >= kRandomChecksPerBinding);
693
694 // Because the divisor will be m_count/kRandomChecksPerBinding and the remainder will be chosen randomly for the
695 // divisor, we expect to check around kRandomChecksPerBinding descriptors per binding randomly, no matter the amount of
696 // descriptors in the binding.
697 m_remainder = static_cast<deUint32>(randRange(&m_rnd, 0, static_cast<deInt32>((m_count / kRandomChecksPerBinding) - 1)));
698 m_have_remainder = true;
699 }
700
701 return (arrayIndex % m_count == m_remainder);
702 }
703
704 private:
705 static constexpr deUint32 kRandomChecksPerBinding = 4u;
706
707 deRandom& m_rnd;
708 deUint32 m_count;
709 deUint32 m_remainder;
710 bool m_have_remainder;
711 };
712
initPrograms(SourceCollections & programCollection) const713 void DescriptorSetRandomTestCase::initPrograms (SourceCollections& programCollection) const
714 {
715 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
716
717 deRandom rnd;
718 deRandom_init(&rnd, m_data.seed);
719
720 m_data.randomLayout.reset(new RandomLayout(m_data.numDescriptorSets));
721 RandomLayout& randomLayout = *m_data.randomLayout.get();
722 generateRandomLayout(randomLayout, m_data, rnd);
723
724 std::stringstream decls, checks;
725
726 deUint32 inputAttachments = 0;
727 deUint32 descriptor = 0;
728
729 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
730 {
731 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
732 vector<VkDescriptorBindingFlags> bindingsFlags = randomLayout.layoutBindingFlags[s];
733 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
734 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
735
736 for (size_t b = 0; b < bindings.size(); ++b)
737 {
738 VkDescriptorSetLayoutBinding &binding = bindings[b];
739 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1;
740
741 // Construct the declaration for the binding
742 if (binding.descriptorCount > 0)
743 {
744 std::stringstream array;
745 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE &&
746 binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
747 {
748 if (arraySizes[b])
749 {
750 array << "[]";
751 }
752 }
753 else
754 {
755 if (arraySizes[b])
756 {
757 array << "[" << arraySizes[b] << "]";
758 }
759 }
760
761 switch (binding.descriptorType)
762 {
763 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
764 decls << "layout(set = " << s << ", binding = " << b << ") uniform inlineubodef" << s << "_" << b << " { ivec4 dummy; int val" << array.str() << "; } inlineubo" << s << "_" << b << ";\n";
765 break;
766 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
767 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
768 decls << "layout(set = " << s << ", binding = " << b << ") uniform ubodef" << s << "_" << b << " { int val; } ubo" << s << "_" << b << array.str() << ";\n";
769 break;
770 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
771 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
772 decls << "layout(set = " << s << ", binding = " << b << ") buffer sbodef" << s << "_" << b << " { int val; } ssbo" << s << "_" << b << array.str() << ";\n";
773 break;
774 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
775 decls << "layout(set = " << s << ", binding = " << b << ") uniform itextureBuffer texbo" << s << "_" << b << array.str() << ";\n";
776 break;
777 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
778 decls << "layout(r32i, set = " << s << ", binding = " << b << ") uniform iimageBuffer image" << s << "_" << b << array.str() << ";\n";
779 break;
780 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
781 decls << "layout(r32i, set = " << s << ", binding = " << b << ") uniform iimage2D simage" << s << "_" << b << array.str() << ";\n";
782 break;
783 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
784 decls << "layout(input_attachment_index = " << inputAttachments << ", set = " << s << ", binding = " << b << ") uniform isubpassInput attachment" << s << "_" << b << array.str() << ";\n";
785 inputAttachments += binding.descriptorCount;
786 break;
787 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
788 DE_ASSERT(s == 0 && b == 1);
789 DE_ASSERT(bindings.size() >= 2);
790 decls << "layout(set = " << s << ", binding = " << b << ") uniform accelerationStructureEXT as" << s << "_" << b << ";\n";
791 break;
792 default: DE_ASSERT(0);
793 }
794
795 const deUint32 arraySize = de::max(1u, arraySizes[b]);
796 CheckDecider checkDecider (rnd, arraySize);
797
798 for (deUint32 ai = 0; ai < arraySize; ++ai, descriptor += descriptorIncrement)
799 {
800 // Don't access descriptors past the end of the allocated range for
801 // variable descriptor count
802 if (b == bindings.size() - 1 &&
803 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))
804 {
805 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
806 {
807 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block
808 const deUint32 uboRange = ai*16 + 16;
809 if (uboRange >= variableDescriptorSizes[s])
810 continue;
811 }
812 else
813 {
814 if (ai >= variableDescriptorSizes[s])
815 continue;
816 }
817 }
818
819 if (s == 0 && b == 0)
820 {
821 // This is the output image, skip.
822 continue;
823 }
824
825 if (s == 0 && b == 1 && usesAccelerationStructure(m_data.stage))
826 {
827 // This is the raytracing acceleration structure, skip.
828 continue;
829 }
830
831 if (checkDecider.shouldCheck(ai))
832 {
833 // Check that the value in the descriptor equals its descriptor number.
834 // i.e. check "ubo[c].val == descriptor" or "ubo[pushconst[c]].val == descriptor"
835 // When doing a write check, write the descriptor number in the value.
836
837 // First, construct the index. This can be a constant literal, a value
838 // from a push constant, or a function of the previous descriptor value.
839 std::stringstream ind;
840 switch (m_data.indexType)
841 {
842 case INDEX_TYPE_NONE:
843 case INDEX_TYPE_CONSTANT:
844 // The index is just the constant literal
845 if (arraySizes[b])
846 {
847 ind << "[" << ai << "]";
848 }
849 break;
850 case INDEX_TYPE_PUSHCONSTANT:
851 // identity is an int[], directly index it
852 if (arraySizes[b])
853 {
854 ind << "[pc.identity[" << ai << "]]";
855 }
856 break;
857 case INDEX_TYPE_RUNTIME_SIZE:
858 case INDEX_TYPE_DEPENDENT:
859 // Index is a function of the previous return value (which is reset to zero)
860 if (arraySizes[b])
861 {
862 ind << "[accum + " << ai << "]";
863 }
864 break;
865 default: DE_ASSERT(0);
866 }
867
868 const DescriptorId descriptorId (s, static_cast<deUint32>(b), ai);
869 auto writesItr = randomLayout.descriptorWrites.find(descriptorId);
870
871 if (writesItr == randomLayout.descriptorWrites.end())
872 {
873 // Fetch from the descriptor.
874 switch (binding.descriptorType)
875 {
876 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
877 checks << " temp = inlineubo" << s << "_" << b << ".val" << ind.str() << ";\n";
878 break;
879 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
880 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
881 checks << " temp = ubo" << s << "_" << b << ind.str() << ".val;\n";
882 break;
883 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
884 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
885 checks << " temp = ssbo" << s << "_" << b << ind.str() << ".val;\n";
886 break;
887 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
888 checks << " temp = texelFetch(texbo" << s << "_" << b << ind.str() << ", 0).x;\n";
889 break;
890 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
891 checks << " temp = imageLoad(image" << s << "_" << b << ind.str() << ", 0).x;\n";
892 break;
893 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
894 checks << " temp = imageLoad(simage" << s << "_" << b << ind.str() << ", ivec2(0, 0)).x;\n";
895 break;
896 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
897 checks << " temp = subpassLoad(attachment" << s << "_" << b << ind.str() << ").r;\n";
898 break;
899 default: DE_ASSERT(0);
900 }
901
902 // Accumulate any incorrect values.
903 checks << " accum |= temp - " << descriptor << ";\n";
904 }
905 else
906 {
907 // Check descriptor write. We need to confirm we are actually generating write code for this descriptor.
908 writesItr->second.writeGenerated = true;
909
910 // Assign each write operation to a single invocation to avoid race conditions.
911 const auto expectedInvocationID = descriptor % (DIM*DIM);
912 const std::string writeCond = "if (" + de::toString(expectedInvocationID) + " == invocationID)";
913
914 switch (binding.descriptorType)
915 {
916 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
917 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
918 checks << " " << writeCond << " ssbo" << s << "_" << b << ind.str() << ".val = " << descriptor << ";\n";
919 break;
920 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
921 checks << " " << writeCond << " imageStore(image" << s << "_" << b << ind.str() << ", 0, ivec4(" << descriptor << ", 0, 0, 0));\n";
922 break;
923 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
924 checks << " " << writeCond << " imageStore(simage" << s << "_" << b << ind.str() << ", ivec2(0, 0), ivec4(" << descriptor << ", 0, 0, 0));\n";
925 break;
926 default: DE_ASSERT(0);
927 }
928 }
929 }
930 }
931 }
932 }
933 }
934
935 std::stringstream pushdecl;
936 switch (m_data.indexType)
937 {
938 case INDEX_TYPE_PUSHCONSTANT:
939 pushdecl << "layout (push_constant, std430) uniform Block { int identity[32]; } pc;\n";
940 break;
941 default: DE_ASSERT(0);
942 case INDEX_TYPE_NONE:
943 case INDEX_TYPE_CONSTANT:
944 case INDEX_TYPE_DEPENDENT:
945 case INDEX_TYPE_RUNTIME_SIZE:
946 break;
947 }
948
949
950 switch (m_data.stage)
951 {
952 default: DE_ASSERT(0); // Fallthrough
953 case STAGE_COMPUTE:
954 {
955 std::stringstream css;
956 css <<
957 "#version 450 core\n"
958 "#extension GL_EXT_nonuniform_qualifier : enable\n"
959 << pushdecl.str()
960 << decls.str() <<
961 "layout(local_size_x = 1, local_size_y = 1) in;\n"
962 "void main()\n"
963 "{\n"
964 " const int invocationID = int(gl_GlobalInvocationID.y) * " << DIM << " + int(gl_GlobalInvocationID.x);\n"
965 " int accum = 0, temp;\n"
966 << checks.str() <<
967 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
968 " imageStore(simage0_0, ivec2(gl_GlobalInvocationID.xy), color);\n"
969 "}\n";
970
971 programCollection.glslSources.add("test") << glu::ComputeSource(css.str());
972 break;
973 }
974 case STAGE_RAYGEN_NV:
975 {
976 std::stringstream css;
977 css <<
978 "#version 460 core\n"
979 "#extension GL_EXT_nonuniform_qualifier : enable\n"
980 "#extension GL_NV_ray_tracing : require\n"
981 << pushdecl.str()
982 << decls.str() <<
983 "void main()\n"
984 "{\n"
985 " const int invocationID = int(gl_LaunchIDNV.y) * " << DIM << " + int(gl_LaunchIDNV.x);\n"
986 " int accum = 0, temp;\n"
987 << checks.str() <<
988 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
989 " imageStore(simage0_0, ivec2(gl_LaunchIDNV.xy), color);\n"
990 "}\n";
991
992 programCollection.glslSources.add("test") << glu::RaygenSource(css.str());
993 break;
994 }
995 case STAGE_RAYGEN:
996 {
997 std::stringstream css;
998 css <<
999 "#version 460 core\n"
1000 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1001 "#extension GL_EXT_ray_tracing : require\n"
1002 << pushdecl.str()
1003 << decls.str() <<
1004 "void main()\n"
1005 "{\n"
1006 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1007 " int accum = 0, temp;\n"
1008 << checks.str() <<
1009 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1010 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1011 "}\n";
1012
1013 programCollection.glslSources.add("test") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1014 break;
1015 }
1016 case STAGE_INTERSECT:
1017 {
1018 {
1019 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1020 }
1021
1022 {
1023 std::stringstream css;
1024 css <<
1025 "#version 460 core\n"
1026 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1027 "#extension GL_EXT_ray_tracing : require\n"
1028 "hitAttributeEXT vec3 hitAttribute;\n"
1029 << pushdecl.str()
1030 << decls.str() <<
1031 "void main()\n"
1032 "{\n"
1033 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1034 " int accum = 0, temp;\n"
1035 << checks.str() <<
1036 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1037 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1038 " hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1039 " reportIntersectionEXT(1.0f, 0);\n"
1040 "}\n";
1041
1042 programCollection.glslSources.add("test") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1043 }
1044
1045 break;
1046 }
1047 case STAGE_ANY_HIT:
1048 {
1049 {
1050 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1051 }
1052
1053 {
1054 std::stringstream css;
1055 css <<
1056 "#version 460 core\n"
1057 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1058 "#extension GL_EXT_ray_tracing : require\n"
1059 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1060 "hitAttributeEXT vec3 attribs;\n"
1061 << pushdecl.str()
1062 << decls.str() <<
1063 "void main()\n"
1064 "{\n"
1065 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1066 " int accum = 0, temp;\n"
1067 << checks.str() <<
1068 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1069 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1070 "}\n";
1071
1072 programCollection.glslSources.add("test") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1073 }
1074
1075 break;
1076 }
1077 case STAGE_CLOSEST_HIT:
1078 {
1079 {
1080 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1081 }
1082
1083 {
1084 std::stringstream css;
1085 css <<
1086 "#version 460 core\n"
1087 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1088 "#extension GL_EXT_ray_tracing : require\n"
1089 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1090 "hitAttributeEXT vec3 attribs;\n"
1091 << pushdecl.str()
1092 << decls.str() <<
1093 "void main()\n"
1094 "{\n"
1095 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1096 " int accum = 0, temp;\n"
1097 << checks.str() <<
1098 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1099 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1100 "}\n";
1101
1102 programCollection.glslSources.add("test") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1103 }
1104
1105 break;
1106 }
1107 case STAGE_MISS:
1108 {
1109 {
1110 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1111 }
1112
1113 {
1114 std::stringstream css;
1115 css <<
1116 "#version 460 core\n"
1117 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1118 "#extension GL_EXT_ray_tracing : require\n"
1119 "layout(location = 0) rayPayloadInEXT dummyPayload { vec4 dummy; };\n"
1120 << pushdecl.str()
1121 << decls.str() <<
1122 "void main()\n"
1123 "{\n"
1124 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1125 " int accum = 0, temp;\n"
1126 << checks.str() <<
1127 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1128 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1129 "}\n";
1130
1131 programCollection.glslSources.add("test") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1132 }
1133
1134 break;
1135 }
1136 case STAGE_CALLABLE:
1137 {
1138 {
1139 std::stringstream css;
1140 css <<
1141 "#version 460 core\n"
1142 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1143 "#extension GL_EXT_ray_tracing : require\n"
1144 "layout(location = 0) callableDataEXT float dummy;"
1145 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1146 "\n"
1147 "void main()\n"
1148 "{\n"
1149 " executeCallableEXT(0, 0);\n"
1150 "}\n";
1151
1152 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1153 }
1154
1155 {
1156 std::stringstream css;
1157 css <<
1158 "#version 460 core\n"
1159 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1160 "#extension GL_EXT_ray_tracing : require\n"
1161 "layout(location = 0) callableDataInEXT float dummy;"
1162 << pushdecl.str()
1163 << decls.str() <<
1164 "void main()\n"
1165 "{\n"
1166 " const int invocationID = int(gl_LaunchIDEXT.y) * " << DIM << " + int(gl_LaunchIDEXT.x);\n"
1167 " int accum = 0, temp;\n"
1168 << checks.str() <<
1169 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1170 " imageStore(simage0_0, ivec2(gl_LaunchIDEXT.xy), color);\n"
1171 "}\n";
1172
1173 programCollection.glslSources.add("test") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1174 }
1175 break;
1176 }
1177 case STAGE_VERTEX:
1178 {
1179 std::stringstream vss;
1180 vss <<
1181 "#version 450 core\n"
1182 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1183 << pushdecl.str()
1184 << decls.str() <<
1185 "void main()\n"
1186 "{\n"
1187 " const int invocationID = gl_VertexIndex;\n"
1188 " int accum = 0, temp;\n"
1189 << checks.str() <<
1190 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1191 " imageStore(simage0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n"
1192 " gl_PointSize = 1.0f;\n"
1193 " gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
1194 "}\n";
1195
1196 programCollection.glslSources.add("test") << glu::VertexSource(vss.str());
1197 break;
1198 }
1199 case STAGE_FRAGMENT:
1200 {
1201 std::stringstream vss;
1202 vss <<
1203 "#version 450 core\n"
1204 "void main()\n"
1205 "{\n"
1206 // full-viewport quad
1207 " 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"
1208 "}\n";
1209
1210 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
1211
1212 std::stringstream fss;
1213 fss <<
1214 "#version 450 core\n"
1215 "#extension GL_EXT_nonuniform_qualifier : enable\n"
1216 << pushdecl.str()
1217 << decls.str() <<
1218 "void main()\n"
1219 "{\n"
1220 " const int invocationID = int(gl_FragCoord.y) * " << DIM << " + int(gl_FragCoord.x);\n"
1221 " int accum = 0, temp;\n"
1222 << checks.str() <<
1223 " ivec4 color = (accum != 0) ? ivec4(0,0,0,0) : ivec4(1,0,0,1);\n"
1224 " imageStore(simage0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n"
1225 "}\n";
1226
1227 programCollection.glslSources.add("test") << glu::FragmentSource(fss.str());
1228 break;
1229 }
1230 }
1231
1232 }
1233
createInstance(Context & context) const1234 TestInstance* DescriptorSetRandomTestCase::createInstance (Context& context) const
1235 {
1236 return new DescriptorSetRandomTestInstance(context, m_data_ptr);
1237 }
1238
iterate(void)1239 tcu::TestStatus DescriptorSetRandomTestInstance::iterate (void)
1240 {
1241 const InstanceInterface& vki = m_context.getInstanceInterface();
1242 const DeviceInterface& vk = m_context.getDeviceInterface();
1243 const VkDevice device = m_context.getDevice();
1244 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1245 Allocator& allocator = m_context.getDefaultAllocator();
1246 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1247
1248 deRandom rnd;
1249 VkPhysicalDeviceProperties2 properties = getPhysicalDeviceExtensionProperties(vki, physicalDevice);
1250 deUint32 shaderGroupHandleSize = 0;
1251 deUint32 shaderGroupBaseAlignment = 1;
1252
1253 deRandom_init(&rnd, m_data.seed);
1254 RandomLayout& randomLayout = *m_data.randomLayout.get();
1255
1256 if (m_data.stage == STAGE_RAYGEN_NV)
1257 {
1258 const VkPhysicalDeviceRayTracingPropertiesNV rayTracingProperties = getPhysicalDeviceExtensionProperties(vki, physicalDevice);
1259
1260 shaderGroupHandleSize = rayTracingProperties.shaderGroupHandleSize;
1261 }
1262
1263 if (isRayTracingStageKHR(m_data.stage))
1264 {
1265 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
1266
1267 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
1268 shaderGroupHandleSize = rayTracingPropertiesKHR->getShaderGroupHandleSize();
1269 shaderGroupBaseAlignment = rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
1270 }
1271
1272 // Get needed features.
1273 auto descriptorIndexingSupported = m_context.isDeviceFunctionalitySupported("VK_EXT_descriptor_indexing");
1274 auto indexingFeatures = m_context.getDescriptorIndexingFeatures();
1275 auto inlineUniformFeatures = m_context.getInlineUniformBlockFeaturesEXT();
1276
1277 VkPipelineBindPoint bindPoint;
1278
1279 switch (m_data.stage)
1280 {
1281 case STAGE_COMPUTE:
1282 bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
1283 break;
1284 case STAGE_RAYGEN_NV:
1285 bindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_NV;
1286 break;
1287 default:
1288 bindPoint = (isRayTracingStageKHR(m_data.stage) ? VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR : VK_PIPELINE_BIND_POINT_GRAPHICS);
1289 break;
1290 }
1291
1292 DE_ASSERT(m_data.numDescriptorSets <= 32);
1293 Move<vk::VkDescriptorSetLayout> descriptorSetLayouts[32];
1294 Move<vk::VkDescriptorPool> descriptorPools[32];
1295 Move<vk::VkDescriptorSet> descriptorSets[32];
1296
1297 deUint32 numDescriptors = 0;
1298 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
1299 {
1300 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
1301 vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
1302 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
1303
1304 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1305 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1306
1307 for (size_t b = 0; b < bindings.size(); ++b)
1308 {
1309 VkDescriptorSetLayoutBinding &binding = bindings[b];
1310 numDescriptors += binding.descriptorCount;
1311
1312 // Randomly choose some bindings to use update-after-bind, if it is supported
1313 if (descriptorIndexingSupported &&
1314 m_data.uab == UPDATE_AFTER_BIND_ENABLED &&
1315 randRange(&rnd, 1, 8) == 1 && // 1 in 8 chance
1316 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || indexingFeatures.descriptorBindingUniformBufferUpdateAfterBind) &&
1317 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || indexingFeatures.descriptorBindingStorageImageUpdateAfterBind) &&
1318 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || indexingFeatures.descriptorBindingStorageBufferUpdateAfterBind) &&
1319 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || indexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind) &&
1320 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || indexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind) &&
1321 (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT || inlineUniformFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind) &&
1322 (binding.descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) &&
1323 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) &&
1324 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
1325 (binding.descriptorType != VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR))
1326 {
1327 bindingsFlags[b] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
1328 layoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
1329 poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
1330 }
1331
1332 if (!indexingFeatures.descriptorBindingVariableDescriptorCount)
1333 {
1334 bindingsFlags[b] &= ~VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
1335 }
1336 }
1337
1338 // Create a layout and allocate a descriptor set for it.
1339
1340 const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo =
1341 {
1342 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT, // VkStructureType sType;
1343 DE_NULL, // const void* pNext;
1344 (deUint32)bindings.size(), // uint32_t bindingCount;
1345 bindings.empty() ? DE_NULL : bindingsFlags.data(), // const VkDescriptorBindingFlags* pBindingFlags;
1346 };
1347
1348 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1349 {
1350 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
1351 (descriptorIndexingSupported ? &bindingFlagsInfo : DE_NULL),// const void* pNext;
1352 layoutCreateFlags, // VkDescriptorSetLayoutCreateFlags flags;
1353 (deUint32)bindings.size(), // deUint32 bindingCount;
1354 bindings.empty() ? DE_NULL : bindings.data() // const VkDescriptorSetLayoutBinding* pBindings;
1355 };
1356
1357 descriptorSetLayouts[s] = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo);
1358
1359 vk::DescriptorPoolBuilder poolBuilder;
1360 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, m_data.maxPerStageUniformBuffers);
1361 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, m_data.maxUniformBuffersDynamic);
1362 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_data.maxPerStageStorageBuffers);
1363 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, m_data.maxStorageBuffersDynamic);
1364 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, m_data.maxPerStageSampledImages);
1365 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, m_data.maxPerStageStorageTexelBuffers);
1366 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_data.maxPerStageStorageImages);
1367 if (m_data.maxPerStageInputAttachments > 0u)
1368 {
1369 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_data.maxPerStageInputAttachments);
1370 }
1371 if (m_data.maxInlineUniformBlocks > 0u)
1372 {
1373 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, m_data.maxInlineUniformBlocks * m_data.maxInlineUniformBlockSize);
1374 }
1375 if (usesAccelerationStructure(m_data.stage))
1376 {
1377 poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u);
1378 }
1379
1380 VkDescriptorPoolInlineUniformBlockCreateInfoEXT inlineUniformBlockPoolCreateInfo =
1381 {
1382 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, // VkStructureType sType;
1383 DE_NULL, // const void* pNext;
1384 m_data.maxInlineUniformBlocks, // uint32_t maxInlineUniformBlockBindings;
1385 };
1386
1387 descriptorPools[s] = poolBuilder.build(vk, device, poolCreateFlags, 1u,
1388 m_data.maxInlineUniformBlocks ? &inlineUniformBlockPoolCreateInfo : DE_NULL);
1389
1390 VkDescriptorSetVariableDescriptorCountAllocateInfo variableCountInfo =
1391 {
1392 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, // VkStructureType sType;
1393 DE_NULL, // const void* pNext;
1394 0, // uint32_t descriptorSetCount;
1395 DE_NULL, // const uint32_t* pDescriptorCounts;
1396 };
1397
1398 const void *pNext = DE_NULL;
1399 if (bindings.size() > 0 &&
1400 bindingsFlags[bindings.size()-1] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)
1401 {
1402 variableCountInfo.descriptorSetCount = 1;
1403 variableCountInfo.pDescriptorCounts = &variableDescriptorSizes[s];
1404 pNext = &variableCountInfo;
1405 }
1406
1407 descriptorSets[s] = makeDescriptorSet(vk, device, *descriptorPools[s], *descriptorSetLayouts[s], pNext);
1408 }
1409
1410 // Create a buffer to hold data for all descriptors.
1411 VkDeviceSize align = std::max({
1412 properties.properties.limits.minTexelBufferOffsetAlignment,
1413 properties.properties.limits.minUniformBufferOffsetAlignment,
1414 properties.properties.limits.minStorageBufferOffsetAlignment,
1415 (VkDeviceSize)sizeof(deUint32)});
1416
1417 de::MovePtr<BufferWithMemory> buffer;
1418
1419 buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1420 vk, device, allocator, makeBufferCreateInfo(align*numDescriptors,
1421 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
1422 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
1423 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
1424 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT),
1425 MemoryRequirement::HostVisible));
1426 deUint8 *bufferPtr = (deUint8 *)buffer->getAllocation().getHostPtr();
1427
1428 // Create storage images separately.
1429 deUint32 storageImageCount = 0u;
1430 vector<Move<VkImage>> storageImages;
1431
1432 const VkImageCreateInfo storageImgCreateInfo =
1433 {
1434 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1435 DE_NULL, // const void* pNext;
1436 0u, // VkImageCreateFlags flags;
1437 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1438 VK_FORMAT_R32_SINT, // VkFormat format;
1439 { 1u, 1u, 1u }, // VkExtent3D extent;
1440 1u, // deUint32 mipLevels;
1441 1u, // deUint32 arrayLayers;
1442 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1443 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1444 VK_IMAGE_USAGE_STORAGE_BIT
1445 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1446 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1447 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1448 1u, // deUint32 queueFamilyIndexCount;
1449 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1450 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1451 };
1452
1453 // Create storage images.
1454 for (const auto& bindings : randomLayout.layoutBindings)
1455 for (const auto& binding : bindings)
1456 {
1457 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1458 {
1459 storageImageCount += binding.descriptorCount;
1460 for (deUint32 d = 0; d < binding.descriptorCount; ++d)
1461 {
1462 storageImages.push_back(createImage(vk, device, &storageImgCreateInfo));
1463 }
1464 }
1465 }
1466
1467 // Allocate memory for them.
1468 vk::VkMemoryRequirements storageImageMemReqs;
1469 vk.getImageMemoryRequirements(device, *storageImages.front(), &storageImageMemReqs);
1470
1471 de::MovePtr<Allocation> storageImageAlloc;
1472 VkDeviceSize storageImageBlockSize = 0u;
1473 {
1474 VkDeviceSize mod = (storageImageMemReqs.size % storageImageMemReqs.alignment);
1475 storageImageBlockSize = storageImageMemReqs.size + ((mod == 0u) ? 0u : storageImageMemReqs.alignment - mod);
1476 }
1477 storageImageMemReqs.size = storageImageBlockSize * storageImageCount;
1478 storageImageAlloc = allocator.allocate(storageImageMemReqs, MemoryRequirement::Any);
1479
1480 // Allocate buffer to copy storage images to.
1481 auto storageImgBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, makeBufferCreateInfo(storageImageCount * sizeof(deInt32), VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1482 deInt32* storageImgBufferPtr = reinterpret_cast<deInt32*>(storageImgBuffer->getAllocation().getHostPtr());
1483
1484 // Create image views.
1485 vector<Move<VkImageView>> storageImageViews;
1486 {
1487 VkImageViewCreateInfo storageImageViewCreateInfo =
1488 {
1489 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1490 DE_NULL, // const void* pNext;
1491 0u, // VkImageViewCreateFlags flags;
1492 DE_NULL, // VkImage image;
1493 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1494 VK_FORMAT_R32_SINT, // VkFormat format;
1495 { // VkComponentMapping channels;
1496 VK_COMPONENT_SWIZZLE_IDENTITY,
1497 VK_COMPONENT_SWIZZLE_IDENTITY,
1498 VK_COMPONENT_SWIZZLE_IDENTITY,
1499 VK_COMPONENT_SWIZZLE_IDENTITY
1500 },
1501 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
1502 };
1503
1504 for (deUint32 i = 0; i < static_cast<deUint32>(storageImages.size()); ++i)
1505 {
1506 // Bind image memory.
1507 vk::VkImage img = *storageImages[i];
1508 VK_CHECK(vk.bindImageMemory(device, img, storageImageAlloc->getMemory(), storageImageAlloc->getOffset() + i * storageImageBlockSize));
1509
1510 // Create view.
1511 storageImageViewCreateInfo.image = img;
1512 storageImageViews.push_back(createImageView(vk, device, &storageImageViewCreateInfo));
1513 }
1514 }
1515
1516 // Create input attachment images.
1517 vector<Move<VkImage>> inputAttachments;
1518 const VkImageCreateInfo imgCreateInfo =
1519 {
1520 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1521 DE_NULL, // const void* pNext;
1522 0u, // VkImageCreateFlags flags;
1523 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1524 VK_FORMAT_R32_SINT, // VkFormat format;
1525 { DIM, DIM, 1u }, // VkExtent3D extent;
1526 1u, // deUint32 mipLevels;
1527 1u, // deUint32 arrayLayers;
1528 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1529 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1530 (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), // VkImageUsageFlags usage;
1531 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1532 1u, // deUint32 queueFamilyIndexCount;
1533 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1534 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1535
1536 };
1537
1538 deUint32 inputAttachmentCount = 0u;
1539 for (const auto& bindings : randomLayout.layoutBindings)
1540 for (const auto& binding : bindings)
1541 {
1542 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
1543 {
1544 inputAttachmentCount += binding.descriptorCount;
1545 for (deUint32 d = 0; d < binding.descriptorCount; ++d)
1546 {
1547 inputAttachments.push_back(createImage(vk, device, &imgCreateInfo));
1548 }
1549 }
1550 }
1551
1552 de::MovePtr<Allocation> inputAttachmentAlloc;
1553 VkDeviceSize imageBlockSize = 0u;
1554
1555 if (inputAttachmentCount > 0u)
1556 {
1557 VkMemoryRequirements imageReqs = getImageMemoryRequirements(vk, device, inputAttachments.back().get());
1558 VkDeviceSize mod = imageReqs.size % imageReqs.alignment;
1559
1560 // Create memory for every input attachment image.
1561 imageBlockSize = imageReqs.size + ((mod == 0u) ? 0u : (imageReqs.alignment - mod));
1562 imageReqs.size = imageBlockSize * inputAttachmentCount;
1563 inputAttachmentAlloc = allocator.allocate(imageReqs, MemoryRequirement::Any);
1564 }
1565
1566 // Bind memory to each input attachment and create an image view.
1567 VkImageViewCreateInfo inputAttachmentViewParams =
1568 {
1569 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1570 DE_NULL, // const void* pNext;
1571 0u, // VkImageViewCreateFlags flags;
1572 DE_NULL, // VkImage image;
1573 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1574 VK_FORMAT_R32_SINT, // VkFormat format;
1575 { // VkComponentMapping channels;
1576 VK_COMPONENT_SWIZZLE_IDENTITY,
1577 VK_COMPONENT_SWIZZLE_IDENTITY,
1578 VK_COMPONENT_SWIZZLE_IDENTITY,
1579 VK_COMPONENT_SWIZZLE_IDENTITY
1580 },
1581 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
1582 };
1583 vector<Move<VkImageView>> inputAttachmentViews;
1584
1585 for (deUint32 i = 0; i < static_cast<deUint32>(inputAttachments.size()); ++i)
1586 {
1587 vk::VkImage img = *inputAttachments[i];
1588 VK_CHECK(vk.bindImageMemory(device, img, inputAttachmentAlloc->getMemory(), inputAttachmentAlloc->getOffset() + i * imageBlockSize));
1589
1590 inputAttachmentViewParams.image = img;
1591 inputAttachmentViews.push_back(createImageView(vk, device, &inputAttachmentViewParams));
1592 }
1593
1594 // Create a view for each descriptor. Fill descriptor 'd' with an integer value equal to 'd'. In case the descriptor would be
1595 // written to from the shader, store a -1 in it instead. Skip inline uniform blocks and use images for input attachments and
1596 // storage images.
1597
1598 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, queueFamilyIndex);
1599 const VkQueue queue = m_context.getUniversalQueue();
1600 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1601
1602 const VkImageSubresourceRange clearRange =
1603 {
1604 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1605 0u, // deUint32 baseMipLevel;
1606 1u, // deUint32 levelCount;
1607 0u, // deUint32 baseArrayLayer;
1608 1u // deUint32 layerCount;
1609 };
1610
1611 VkImageMemoryBarrier preInputAttachmentBarrier =
1612 {
1613 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1614 DE_NULL, // const void* pNext
1615 0u, // VkAccessFlags srcAccessMask
1616 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1617 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1618 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1619 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1620 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1621 DE_NULL, // VkImage image
1622 {
1623 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1624 0u, // uint32_t baseMipLevel
1625 1u, // uint32_t mipLevels,
1626 0u, // uint32_t baseArray
1627 1u, // uint32_t arraySize
1628 }
1629 };
1630
1631 VkImageMemoryBarrier postInputAttachmentBarrier =
1632 {
1633 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1634 DE_NULL, // const void* pNext;
1635 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1636 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask;
1637 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1638 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1639 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1640 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1641 DE_NULL, // VkImage image;
1642 clearRange, // VkImageSubresourceRange subresourceRange;
1643 };
1644
1645 VkImageMemoryBarrier preStorageImageBarrier =
1646 {
1647 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1648 DE_NULL, // const void* pNext
1649 0u, // VkAccessFlags srcAccessMask
1650 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1651 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1652 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1653 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1654 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1655 DE_NULL, // VkImage image
1656 {
1657 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1658 0u, // uint32_t baseMipLevel
1659 1u, // uint32_t mipLevels,
1660 0u, // uint32_t baseArray
1661 1u, // uint32_t arraySize
1662 }
1663 };
1664
1665 VkImageMemoryBarrier postStorageImageBarrier =
1666 {
1667 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1668 DE_NULL, // const void* pNext;
1669 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1670 (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT), // VkAccessFlags dstAccessMask;
1671 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1672 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1673 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1674 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1675 DE_NULL, // VkImage image;
1676 clearRange, // VkImageSubresourceRange subresourceRange;
1677 };
1678
1679 vk::VkClearColorValue clearValue;
1680 clearValue.uint32[0] = 0u;
1681 clearValue.uint32[1] = 0u;
1682 clearValue.uint32[2] = 0u;
1683 clearValue.uint32[3] = 0u;
1684
1685 beginCommandBuffer(vk, *cmdBuffer, 0u);
1686
1687 int descriptor = 0;
1688 deUint32 attachmentIndex = 0;
1689 deUint32 storageImgIndex = 0;
1690
1691 typedef vk::Unique<vk::VkBufferView> BufferViewHandleUp;
1692 typedef de::SharedPtr<BufferViewHandleUp> BufferViewHandleSp;
1693
1694 vector<BufferViewHandleSp> bufferViews(de::max(1u,numDescriptors));
1695
1696 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
1697 {
1698 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
1699 for (size_t b = 0; b < bindings.size(); ++b)
1700 {
1701 VkDescriptorSetLayoutBinding &binding = bindings[b];
1702
1703 if (binding.descriptorCount == 0)
1704 {
1705 continue;
1706 }
1707 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1708 {
1709 descriptor++;
1710 }
1711 else if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
1712 binding.descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT &&
1713 binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1714 {
1715 for (deUint32 d = descriptor; d < descriptor + binding.descriptorCount; ++d)
1716 {
1717 DescriptorId descriptorId (s, static_cast<deUint32>(b), d - descriptor);
1718 auto writeInfoItr = randomLayout.descriptorWrites.find(descriptorId);
1719 deInt32* ptr = (deInt32 *)(bufferPtr + align*d);
1720
1721 if (writeInfoItr == randomLayout.descriptorWrites.end())
1722 {
1723 *ptr = static_cast<deInt32>(d);
1724 }
1725 else
1726 {
1727 *ptr = -1;
1728 writeInfoItr->second.ptr = ptr;
1729 writeInfoItr->second.expected = d;
1730 }
1731
1732 const vk::VkBufferViewCreateInfo viewCreateInfo =
1733 {
1734 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1735 DE_NULL,
1736 (vk::VkBufferViewCreateFlags)0,
1737 **buffer, // buffer
1738 VK_FORMAT_R32_SINT, // format
1739 (vk::VkDeviceSize)align*d, // offset
1740 (vk::VkDeviceSize)sizeof(deUint32) // range
1741 };
1742 vk::Move<vk::VkBufferView> bufferView = vk::createBufferView(vk, device, &viewCreateInfo);
1743 bufferViews[d] = BufferViewHandleSp(new BufferViewHandleUp(bufferView));
1744 }
1745 descriptor += binding.descriptorCount;
1746 }
1747 else if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1748 {
1749 // subtract 16 for "ivec4 dummy"
1750 DE_ASSERT(binding.descriptorCount >= 16);
1751 descriptor += binding.descriptorCount - 16;
1752 }
1753 else if (binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1754 {
1755 // Storage image.
1756 for (deUint32 d = descriptor; d < descriptor + binding.descriptorCount; ++d)
1757 {
1758 VkImage img = *storageImages[storageImgIndex];
1759 DescriptorId descriptorId (s, static_cast<deUint32>(b), d - descriptor);
1760 deInt32* ptr = storageImgBufferPtr + storageImgIndex;
1761
1762 auto writeInfoItr = randomLayout.descriptorWrites.find(descriptorId);
1763 const bool isWrite = (writeInfoItr != randomLayout.descriptorWrites.end());
1764
1765 if (isWrite)
1766 {
1767 writeInfoItr->second.ptr = ptr;
1768 writeInfoItr->second.expected = static_cast<deInt32>(d);
1769 }
1770
1771 preStorageImageBarrier.image = img;
1772 clearValue.int32[0] = (isWrite ? -1 : static_cast<deInt32>(d));
1773 postStorageImageBarrier.image = img;
1774
1775 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preStorageImageBarrier);
1776 vk.cmdClearColorImage(*cmdBuffer, img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1, &clearRange);
1777 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_data.allPipelineStages, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postStorageImageBarrier);
1778
1779 ++storageImgIndex;
1780 }
1781 descriptor += binding.descriptorCount;
1782 }
1783 else
1784 {
1785 // Input attachment.
1786 for (deUint32 d = descriptor; d < descriptor + binding.descriptorCount; ++d)
1787 {
1788 VkImage img = *inputAttachments[attachmentIndex];
1789
1790 preInputAttachmentBarrier.image = img;
1791 clearValue.int32[0] = static_cast<deInt32>(d);
1792 postInputAttachmentBarrier.image = img;
1793
1794 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preInputAttachmentBarrier);
1795 vk.cmdClearColorImage(*cmdBuffer, img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1, &clearRange);
1796 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postInputAttachmentBarrier);
1797
1798 ++attachmentIndex;
1799 }
1800 descriptor += binding.descriptorCount;
1801 }
1802 }
1803 }
1804
1805 // Flush modified memory.
1806 flushAlloc(vk, device, buffer->getAllocation());
1807
1808 // Push constants are used for dynamic indexing. PushConstant[i] = i.
1809 const VkPushConstantRange pushConstRange =
1810 {
1811 m_data.allShaderStages, // VkShaderStageFlags stageFlags
1812 0, // deUint32 offset
1813 128 // deUint32 size
1814 };
1815
1816 vector<vk::VkDescriptorSetLayout> descriptorSetLayoutsRaw (m_data.numDescriptorSets);
1817 for (size_t i = 0; i < m_data.numDescriptorSets; ++i)
1818 {
1819 descriptorSetLayoutsRaw[i] = descriptorSetLayouts[i].get();
1820 }
1821
1822 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1823 {
1824 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1825 DE_NULL, // const void* pNext;
1826 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1827 m_data.numDescriptorSets, // deUint32 setLayoutCount;
1828 &descriptorSetLayoutsRaw[0], // const VkDescriptorSetLayout* pSetLayouts;
1829 m_data.indexType == INDEX_TYPE_PUSHCONSTANT ? 1u : 0u, // deUint32 pushConstantRangeCount;
1830 &pushConstRange, // const VkPushConstantRange* pPushConstantRanges;
1831 };
1832
1833 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1834
1835 if (m_data.indexType == INDEX_TYPE_PUSHCONSTANT)
1836 {
1837 // PushConstant[i] = i
1838 for (deUint32 i = 0; i < (deUint32)(128 / sizeof(deUint32)); ++i)
1839 {
1840 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, m_data.allShaderStages,
1841 (deUint32)(i * sizeof(deUint32)), (deUint32)sizeof(deUint32), &i);
1842 }
1843 }
1844
1845 de::MovePtr<BufferWithMemory> copyBuffer;
1846 copyBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1847 vk, device, allocator, makeBufferCreateInfo(DIM*DIM*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1848
1849 // Special case for the output storage image.
1850 const VkImageCreateInfo imageCreateInfo =
1851 {
1852 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1853 DE_NULL, // const void* pNext;
1854 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1855 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1856 VK_FORMAT_R32_SINT, // VkFormat format;
1857 {
1858 DIM, // deUint32 width;
1859 DIM, // deUint32 height;
1860 1u // deUint32 depth;
1861 }, // VkExtent3D extent;
1862 1u, // deUint32 mipLevels;
1863 1u, // deUint32 arrayLayers;
1864 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1865 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1866 VK_IMAGE_USAGE_STORAGE_BIT
1867 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1868 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1869 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1870 0u, // deUint32 queueFamilyIndexCount;
1871 DE_NULL, // const deUint32* pQueueFamilyIndices;
1872 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1873 };
1874
1875 VkImageViewCreateInfo imageViewCreateInfo =
1876 {
1877 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1878 DE_NULL, // const void* pNext;
1879 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1880 DE_NULL, // VkImage image;
1881 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1882 VK_FORMAT_R32_SINT, // VkFormat format;
1883 {
1884 VK_COMPONENT_SWIZZLE_IDENTITY,
1885 VK_COMPONENT_SWIZZLE_IDENTITY,
1886 VK_COMPONENT_SWIZZLE_IDENTITY,
1887 VK_COMPONENT_SWIZZLE_IDENTITY
1888 }, // VkComponentMapping components;
1889 {
1890 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1891 0u, // deUint32 baseMipLevel;
1892 1u, // deUint32 levelCount;
1893 0u, // deUint32 baseArrayLayer;
1894 1u // deUint32 layerCount;
1895 } // VkImageSubresourceRange subresourceRange;
1896 };
1897
1898 de::MovePtr<ImageWithMemory> image;
1899 Move<VkImageView> imageView;
1900
1901 image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1902 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1903 imageViewCreateInfo.image = **image;
1904 imageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1905
1906 // Create ray tracing structures
1907 de::MovePtr<vk::BottomLevelAccelerationStructure> bottomLevelAccelerationStructure;
1908 de::MovePtr<vk::TopLevelAccelerationStructure> topLevelAccelerationStructure;
1909 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1910 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1911 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1912 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1913
1914 if (usesAccelerationStructure(m_data.stage))
1915 {
1916 // Create bottom level acceleration structure
1917 {
1918 bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1919
1920 bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageFlag(m_data.stage));
1921
1922 bottomLevelAccelerationStructure->createAndBuild(vk, device, *cmdBuffer, allocator);
1923 }
1924
1925 // Create top level acceleration structure
1926 {
1927 topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1928
1929 topLevelAccelerationStructure->setInstanceCount(1);
1930 topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1931
1932 topLevelAccelerationStructure->createAndBuild(vk, device, *cmdBuffer, allocator);
1933 }
1934 }
1935
1936 descriptor = 0;
1937 attachmentIndex = 0;
1938 storageImgIndex = 0;
1939
1940 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s)
1941 {
1942 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s];
1943 vector<VkDescriptorBindingFlags> &bindingsFlags = randomLayout.layoutBindingFlags[s];
1944 vector<deUint32> &arraySizes = randomLayout.arraySizes[s];
1945 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes;
1946
1947 vector<VkDescriptorBufferInfo> bufferInfoVec(numDescriptors);
1948 vector<VkDescriptorImageInfo> imageInfoVec(numDescriptors);
1949 vector<VkBufferView> bufferViewVec(numDescriptors);
1950 vector<VkWriteDescriptorSetInlineUniformBlockEXT> inlineInfoVec(numDescriptors);
1951 vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationInfoVec(numDescriptors);
1952 vector<deUint32> descriptorNumber(numDescriptors);
1953 vector<VkWriteDescriptorSet> writesBeforeBindVec(0);
1954 vector<VkWriteDescriptorSet> writesAfterBindVec(0);
1955 int vecIndex = 0;
1956 int numDynamic = 0;
1957
1958 vector<VkDescriptorUpdateTemplateEntry> imgTemplateEntriesBefore, imgTemplateEntriesAfter,
1959 bufTemplateEntriesBefore, bufTemplateEntriesAfter,
1960 texelBufTemplateEntriesBefore, texelBufTemplateEntriesAfter,
1961 inlineTemplateEntriesBefore, inlineTemplateEntriesAfter;
1962
1963 for (size_t b = 0; b < bindings.size(); ++b)
1964 {
1965 VkDescriptorSetLayoutBinding &binding = bindings[b];
1966 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1;
1967
1968 // Construct the declaration for the binding
1969 if (binding.descriptorCount > 0)
1970 {
1971 bool updateAfterBind = !!(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT);
1972 for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement)
1973 {
1974 // Don't access descriptors past the end of the allocated range for
1975 // variable descriptor count
1976 if (b == bindings.size() - 1 &&
1977 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))
1978 {
1979 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1980 {
1981 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block
1982 const deUint32 uboRange = ai*16 + 16;
1983 if (uboRange >= variableDescriptorSizes[s])
1984 continue;
1985 }
1986 else
1987 {
1988 if (ai >= variableDescriptorSizes[s])
1989 continue;
1990 }
1991 }
1992
1993 // output image
1994 switch (binding.descriptorType)
1995 {
1996 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1997 // Output image. Special case.
1998 if (s == 0 && b == 0)
1999 {
2000 imageInfoVec[vecIndex] = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2001 }
2002 else
2003 {
2004 imageInfoVec[vecIndex] = makeDescriptorImageInfo(DE_NULL, storageImageViews[storageImgIndex].get(), VK_IMAGE_LAYOUT_GENERAL);
2005 }
2006 ++storageImgIndex;
2007 break;
2008 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2009 imageInfoVec[vecIndex] = makeDescriptorImageInfo(DE_NULL, inputAttachmentViews[attachmentIndex].get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
2010 ++attachmentIndex;
2011 break;
2012 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
2013 // Handled below.
2014 break;
2015 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
2016 // Handled below.
2017 break;
2018 default:
2019 // Other descriptor types.
2020 bufferInfoVec[vecIndex] = makeDescriptorBufferInfo(**buffer, descriptor*align, sizeof(deUint32));
2021 bufferViewVec[vecIndex] = **bufferViews[descriptor];
2022 break;
2023 }
2024
2025 descriptorNumber[descriptor] = descriptor;
2026
2027 VkWriteDescriptorSet w =
2028 {
2029 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
2030 DE_NULL, // const void* pNext;
2031 *descriptorSets[s], // VkDescriptorSet dstSet;
2032 (deUint32)b, // deUint32 dstBinding;
2033 ai, // deUint32 dstArrayElement;
2034 1u, // deUint32 descriptorCount;
2035 binding.descriptorType, // VkDescriptorType descriptorType;
2036 &imageInfoVec[vecIndex], // const VkDescriptorImageInfo* pImageInfo;
2037 &bufferInfoVec[vecIndex], // const VkDescriptorBufferInfo* pBufferInfo;
2038 &bufferViewVec[vecIndex], // const VkBufferView* pTexelBufferView;
2039 };
2040
2041 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
2042 {
2043 VkWriteDescriptorSetInlineUniformBlockEXT iuBlock =
2044 {
2045 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT, // VkStructureType sType;
2046 DE_NULL, // const void* pNext;
2047 sizeof(deUint32), // uint32_t dataSize;
2048 &descriptorNumber[descriptor], // const void* pData;
2049 };
2050
2051 inlineInfoVec[vecIndex] = iuBlock;
2052 w.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy"
2053 w.pNext = &inlineInfoVec[vecIndex];
2054 w.descriptorCount = sizeof(deUint32);
2055 }
2056
2057 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
2058 {
2059 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
2060 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
2061 {
2062 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
2063 DE_NULL, // const void* pNext;
2064 w.descriptorCount, // deUint32 accelerationStructureCount;
2065 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
2066 };
2067
2068 accelerationInfoVec[vecIndex] = accelerationStructureWriteDescriptorSet;
2069 w.dstArrayElement = 0;
2070 w.pNext = &accelerationInfoVec[vecIndex];
2071 }
2072
2073 VkDescriptorUpdateTemplateEntry templateEntry =
2074 {
2075 (deUint32)b, // uint32_t dstBinding;
2076 ai, // uint32_t dstArrayElement;
2077 1u, // uint32_t descriptorCount;
2078 binding.descriptorType, // VkDescriptorType descriptorType;
2079 0, // size_t offset;
2080 0, // size_t stride;
2081 };
2082
2083 switch (binding.descriptorType)
2084 {
2085 default:
2086 TCU_THROW(InternalError, "Unknown descriptor type");
2087
2088 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2089 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2090 templateEntry.offset = vecIndex * sizeof(VkDescriptorImageInfo);
2091 (updateAfterBind ? imgTemplateEntriesAfter : imgTemplateEntriesBefore).push_back(templateEntry);
2092 break;
2093 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2094 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2095 templateEntry.offset = vecIndex * sizeof(VkBufferView);
2096 (updateAfterBind ? texelBufTemplateEntriesAfter : texelBufTemplateEntriesBefore).push_back(templateEntry);
2097 break;
2098 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2099 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2100 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2101 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2102 templateEntry.offset = vecIndex * sizeof(VkDescriptorBufferInfo);
2103 (updateAfterBind ? bufTemplateEntriesAfter : bufTemplateEntriesBefore).push_back(templateEntry);
2104 break;
2105 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
2106 templateEntry.offset = descriptor * sizeof(deUint32);
2107 templateEntry.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy"
2108 templateEntry.descriptorCount = sizeof(deUint32);
2109 (updateAfterBind ? inlineTemplateEntriesAfter : inlineTemplateEntriesBefore).push_back(templateEntry);
2110 break;
2111 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
2112 DE_ASSERT(!updateAfterBind);
2113 DE_ASSERT(usesAccelerationStructure(m_data.stage));
2114 break;
2115 }
2116
2117 vecIndex++;
2118
2119 (updateAfterBind ? writesAfterBindVec : writesBeforeBindVec).push_back(w);
2120
2121 // Count the number of dynamic descriptors in this set.
2122 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2123 binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
2124 {
2125 numDynamic++;
2126 }
2127 }
2128 }
2129 }
2130
2131 // Make zeros have at least one element so &zeros[0] works
2132 vector<deUint32> zeros(de::max(1,numDynamic));
2133 deMemset(&zeros[0], 0, numDynamic * sizeof(deUint32));
2134
2135 // Randomly select between vkUpdateDescriptorSets and vkUpdateDescriptorSetWithTemplate
2136 if (randRange(&rnd, 1, 2) == 1 &&
2137 m_context.contextSupports(vk::ApiVersion(1, 1, 0)) &&
2138 !usesAccelerationStructure(m_data.stage))
2139 {
2140 DE_ASSERT(!usesAccelerationStructure(m_data.stage));
2141
2142 VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
2143 {
2144 VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, // VkStructureType sType;
2145 NULL, // void* pNext;
2146 0, // VkDescriptorUpdateTemplateCreateFlags flags;
2147 0, // uint32_t descriptorUpdateEntryCount;
2148 DE_NULL, // uint32_t descriptorUpdateEntryCount;
2149 VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, // VkDescriptorUpdateTemplateType templateType;
2150 descriptorSetLayouts[s].get(), // VkDescriptorSetLayout descriptorSetLayout;
2151 bindPoint, // VkPipelineBindPoint pipelineBindPoint;
2152 0, // VkPipelineLayout pipelineLayout;
2153 0, // uint32_t set;
2154 };
2155
2156 void *templateVectorData[] =
2157 {
2158 imageInfoVec.data(),
2159 bufferInfoVec.data(),
2160 bufferViewVec.data(),
2161 descriptorNumber.data(),
2162 };
2163
2164 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsBefore[] =
2165 {
2166 &imgTemplateEntriesBefore,
2167 &bufTemplateEntriesBefore,
2168 &texelBufTemplateEntriesBefore,
2169 &inlineTemplateEntriesBefore,
2170 };
2171
2172 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsAfter[] =
2173 {
2174 &imgTemplateEntriesAfter,
2175 &bufTemplateEntriesAfter,
2176 &texelBufTemplateEntriesAfter,
2177 &inlineTemplateEntriesAfter,
2178 };
2179
2180 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(templateVectorsBefore); ++i)
2181 {
2182 if (templateVectorsBefore[i]->size())
2183 {
2184 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsBefore[i]->size();
2185 templateCreateInfo.pDescriptorUpdateEntries = templateVectorsBefore[i]->data();
2186 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
2187 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]);
2188 }
2189 }
2190
2191 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]);
2192
2193 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(templateVectorsAfter); ++i)
2194 {
2195 if (templateVectorsAfter[i]->size())
2196 {
2197 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsAfter[i]->size();
2198 templateCreateInfo.pDescriptorUpdateEntries = templateVectorsAfter[i]->data();
2199 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL);
2200 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]);
2201 }
2202 }
2203
2204 }
2205 else
2206 {
2207 if (writesBeforeBindVec.size())
2208 {
2209 vk.updateDescriptorSets(device, (deUint32)writesBeforeBindVec.size(), &writesBeforeBindVec[0], 0, NULL);
2210 }
2211
2212 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]);
2213
2214 if (writesAfterBindVec.size())
2215 {
2216 vk.updateDescriptorSets(device, (deUint32)writesAfterBindVec.size(), &writesAfterBindVec[0], 0, NULL);
2217 }
2218 }
2219 }
2220
2221 Move<VkPipeline> pipeline;
2222 Move<VkRenderPass> renderPass;
2223 Move<VkFramebuffer> framebuffer;
2224
2225 de::MovePtr<BufferWithMemory> sbtBuffer;
2226 de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
2227 de::MovePtr<BufferWithMemory> missShaderBindingTable;
2228 de::MovePtr<BufferWithMemory> hitShaderBindingTable;
2229 de::MovePtr<BufferWithMemory> callableShaderBindingTable;
2230 de::MovePtr<RayTracingPipeline> rayTracingPipeline;
2231
2232 if (m_data.stage == STAGE_COMPUTE)
2233 {
2234 const Unique<VkShaderModule> shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));
2235
2236 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2237 {
2238 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2239 DE_NULL,
2240 (VkPipelineShaderStageCreateFlags)0,
2241 VK_SHADER_STAGE_COMPUTE_BIT, // stage
2242 *shader, // shader
2243 "main",
2244 DE_NULL, // pSpecializationInfo
2245 };
2246
2247 const VkComputePipelineCreateInfo pipelineCreateInfo =
2248 {
2249 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2250 DE_NULL,
2251 0u, // flags
2252 shaderCreateInfo, // cs
2253 *pipelineLayout, // layout
2254 (vk::VkPipeline)0, // basePipelineHandle
2255 0u, // basePipelineIndex
2256 };
2257 pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
2258 }
2259 else if (m_data.stage == STAGE_RAYGEN_NV)
2260 {
2261 const Unique<VkShaderModule> shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0));
2262
2263 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2264 {
2265 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2266 DE_NULL, // const void* pNext;
2267 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2268 VK_SHADER_STAGE_RAYGEN_BIT_NV, // VkShaderStageFlagBits stage;
2269 *shader, // VkShaderModule module;
2270 "main", // const char* pName;
2271 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
2272 };
2273
2274 VkRayTracingShaderGroupCreateInfoNV group =
2275 {
2276 VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV, // VkStructureType sType;
2277 DE_NULL, // const void* pNext;
2278 VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV, // VkRayTracingShaderGroupTypeNV type;
2279 0, // deUint32 generalShader;
2280 VK_SHADER_UNUSED_NV, // deUint32 closestHitShader;
2281 VK_SHADER_UNUSED_NV, // deUint32 anyHitShader;
2282 VK_SHADER_UNUSED_NV, // deUint32 intersectionShader;
2283 };
2284
2285 VkRayTracingPipelineCreateInfoNV pipelineCreateInfo =
2286 {
2287 VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV, // VkStructureType sType;
2288 DE_NULL, // const void* pNext;
2289 0, // VkPipelineCreateFlags flags;
2290 1, // deUint32 stageCount;
2291 &shaderCreateInfo, // const VkPipelineShaderStageCreateInfo* pStages;
2292 1, // deUint32 groupCount;
2293 &group, // const VkRayTracingShaderGroupCreateInfoNV* pGroups;
2294 0, // deUint32 maxRecursionDepth;
2295 *pipelineLayout, // VkPipelineLayout layout;
2296 (vk::VkPipeline)0, // VkPipeline basePipelineHandle;
2297 0u, // deInt32 basePipelineIndex;
2298 };
2299
2300 pipeline = createRayTracingPipelineNV(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
2301
2302 const auto allocSize = de::roundUp(static_cast<VkDeviceSize>(shaderGroupHandleSize), properties.properties.limits.nonCoherentAtomSize);
2303
2304 sbtBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator,
2305 makeBufferCreateInfo(allocSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_RAY_TRACING_BIT_NV), MemoryRequirement::HostVisible));
2306
2307 const auto& alloc = sbtBuffer->getAllocation();
2308 const auto ptr = reinterpret_cast<deUint32*>(alloc.getHostPtr());
2309
2310 invalidateAlloc(vk, device, alloc);
2311 vk.getRayTracingShaderGroupHandlesNV(device, *pipeline, 0, 1, static_cast<deUintptr>(allocSize), ptr);
2312 }
2313 else if (m_data.stage == STAGE_RAYGEN)
2314 {
2315 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2316
2317 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 0);
2318
2319 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2320
2321 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2322 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2323 }
2324 else if (m_data.stage == STAGE_INTERSECT)
2325 {
2326 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2327
2328 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2329 rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 1);
2330
2331 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2332
2333 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2334 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2335
2336 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2337 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2338 }
2339 else if (m_data.stage == STAGE_ANY_HIT)
2340 {
2341 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2342
2343 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2344 rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 1);
2345
2346 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2347
2348 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2349 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2350
2351 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2352 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2353 }
2354 else if (m_data.stage == STAGE_CLOSEST_HIT)
2355 {
2356 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2357
2358 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2359 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 1);
2360
2361 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2362
2363 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2364 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2365
2366 hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2367 hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2368 }
2369 else if (m_data.stage == STAGE_MISS)
2370 {
2371 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2372
2373 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2374 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 1);
2375
2376 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2377
2378 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2379 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2380
2381 missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2382 missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2383 }
2384 else if (m_data.stage == STAGE_CALLABLE)
2385 {
2386 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2387
2388 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2389 rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0), 1);
2390
2391 pipeline = rayTracingPipeline->createPipeline(vk, device, *pipelineLayout);
2392
2393 raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2394 raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2395
2396 callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2397 callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2398 }
2399 else
2400 {
2401 const VkAttachmentDescription attachmentDescription =
2402 {
2403 // Input attachment
2404 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
2405 VK_FORMAT_R32_SINT, // VkFormat format
2406 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2407 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
2408 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
2409 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
2410 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
2411 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout initialLayout
2412 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout
2413 };
2414
2415 vector<VkAttachmentDescription> attachmentDescriptions (inputAttachments.size(), attachmentDescription);
2416 vector<VkAttachmentReference> attachmentReferences;
2417
2418 attachmentReferences.reserve(inputAttachments.size());
2419 VkAttachmentReference attachmentReference =
2420 {
2421 0u,
2422 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
2423 };
2424 for (size_t i = 0; i < inputAttachments.size(); ++i)
2425 {
2426 attachmentReference.attachment = static_cast<deUint32>(i);
2427 attachmentReferences.push_back(attachmentReference);
2428 }
2429
2430 const VkSubpassDescription subpassDesc =
2431 {
2432 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
2433 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2434 static_cast<deUint32>(attachmentReferences.size()), // deUint32 inputAttachmentCount
2435 (attachmentReferences.empty() ? DE_NULL : attachmentReferences.data()), // const VkAttachmentReference* pInputAttachments
2436 0u, // deUint32 colorAttachmentCount
2437 DE_NULL, // const VkAttachmentReference* pColorAttachments
2438 DE_NULL, // const VkAttachmentReference* pResolveAttachments
2439 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
2440 0u, // deUint32 preserveAttachmentCount
2441 DE_NULL // const deUint32* pPreserveAttachments
2442 };
2443
2444 const VkSubpassDependency subpassDependency =
2445 {
2446 VK_SUBPASS_EXTERNAL, // deUint32 srcSubpass
2447 0, // deUint32 dstSubpass
2448 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
2449 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // dstStageMask
2450 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
2451 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
2452 VK_DEPENDENCY_BY_REGION_BIT // VkDependencyFlags dependencyFlags
2453 };
2454
2455 const VkRenderPassCreateInfo renderPassParams =
2456 {
2457 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureTypei sType
2458 DE_NULL, // const void* pNext
2459 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
2460 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount
2461 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
2462 1u, // deUint32 subpassCount
2463 &subpassDesc, // const VkSubpassDescription* pSubpasses
2464 1u, // deUint32 dependencyCount
2465 &subpassDependency // const VkSubpassDependency* pDependencies
2466 };
2467
2468 renderPass = createRenderPass(vk, device, &renderPassParams);
2469
2470 vector<VkImageView> rawInputAttachmentViews;
2471 rawInputAttachmentViews.reserve(inputAttachmentViews.size());
2472 transform(begin(inputAttachmentViews), end(inputAttachmentViews), back_inserter(rawInputAttachmentViews),
2473 [](const Move<VkImageView>& ptr) { return ptr.get(); });
2474
2475 const vk::VkFramebufferCreateInfo framebufferParams =
2476 {
2477 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
2478 DE_NULL, // pNext
2479 (vk::VkFramebufferCreateFlags)0,
2480 *renderPass, // renderPass
2481 static_cast<deUint32>(rawInputAttachmentViews.size()), // attachmentCount
2482 rawInputAttachmentViews.data(), // pAttachments
2483 DIM, // width
2484 DIM, // height
2485 1u, // layers
2486 };
2487
2488 framebuffer = createFramebuffer(vk, device, &framebufferParams);
2489
2490 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
2491 {
2492 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2493 DE_NULL, // const void* pNext;
2494 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2495 0u, // deUint32 vertexBindingDescriptionCount;
2496 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2497 0u, // deUint32 vertexAttributeDescriptionCount;
2498 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
2499 };
2500
2501 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
2502 {
2503 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2504 DE_NULL, // const void* pNext;
2505 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
2506 (m_data.stage == STAGE_VERTEX) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
2507 VK_FALSE // VkBool32 primitiveRestartEnable;
2508 };
2509
2510 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
2511 {
2512 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2513 DE_NULL, // const void* pNext;
2514 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
2515 VK_FALSE, // VkBool32 depthClampEnable;
2516 (m_data.stage == STAGE_VERTEX) ? VK_TRUE : VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2517 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2518 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
2519 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
2520 VK_FALSE, // VkBool32 depthBiasEnable;
2521 0.0f, // float depthBiasConstantFactor;
2522 0.0f, // float depthBiasClamp;
2523 0.0f, // float depthBiasSlopeFactor;
2524 1.0f // float lineWidth;
2525 };
2526
2527 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
2528 {
2529 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
2530 DE_NULL, // const void* pNext
2531 0u, // VkPipelineMultisampleStateCreateFlags flags
2532 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
2533 VK_FALSE, // VkBool32 sampleShadingEnable
2534 1.0f, // float minSampleShading
2535 DE_NULL, // const VkSampleMask* pSampleMask
2536 VK_FALSE, // VkBool32 alphaToCoverageEnable
2537 VK_FALSE // VkBool32 alphaToOneEnable
2538 };
2539
2540 VkViewport viewport = makeViewport(DIM, DIM);
2541 VkRect2D scissor = makeRect2D(DIM, DIM);
2542
2543 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
2544 {
2545 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
2546 DE_NULL, // const void* pNext
2547 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
2548 1u, // deUint32 viewportCount
2549 &viewport, // const VkViewport* pViewports
2550 1u, // deUint32 scissorCount
2551 &scissor // const VkRect2D* pScissors
2552 };
2553
2554 Move<VkShaderModule> fs;
2555 Move<VkShaderModule> vs;
2556
2557 deUint32 numStages;
2558 if (m_data.stage == STAGE_VERTEX)
2559 {
2560 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
2561 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); // bogus
2562 numStages = 1u;
2563 }
2564 else
2565 {
2566 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
2567 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0);
2568 numStages = 2u;
2569 }
2570
2571 const VkPipelineShaderStageCreateInfo shaderCreateInfo[2] =
2572 {
2573 {
2574 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2575 DE_NULL,
2576 (VkPipelineShaderStageCreateFlags)0,
2577 VK_SHADER_STAGE_VERTEX_BIT, // stage
2578 *vs, // shader
2579 "main",
2580 DE_NULL, // pSpecializationInfo
2581 },
2582 {
2583 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2584 DE_NULL,
2585 (VkPipelineShaderStageCreateFlags)0,
2586 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
2587 *fs, // shader
2588 "main",
2589 DE_NULL, // pSpecializationInfo
2590 }
2591 };
2592
2593 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
2594 {
2595 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2596 DE_NULL, // const void* pNext;
2597 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2598 numStages, // deUint32 stageCount;
2599 &shaderCreateInfo[0], // const VkPipelineShaderStageCreateInfo* pStages;
2600 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2601 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2602 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2603 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
2604 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
2605 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2606 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2607 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2608 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2609 pipelineLayout.get(), // VkPipelineLayout layout;
2610 renderPass.get(), // VkRenderPass renderPass;
2611 0u, // deUint32 subpass;
2612 DE_NULL, // VkPipeline basePipelineHandle;
2613 0 // int basePipelineIndex;
2614 };
2615
2616 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo);
2617 }
2618
2619 const VkImageMemoryBarrier imageBarrier =
2620 {
2621 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
2622 DE_NULL, // const void* pNext
2623 0u, // VkAccessFlags srcAccessMask
2624 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
2625 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
2626 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
2627 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
2628 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
2629 **image, // VkImage image
2630 {
2631 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
2632 0u, // uint32_t baseMipLevel
2633 1u, // uint32_t mipLevels,
2634 0u, // uint32_t baseArray
2635 1u, // uint32_t arraySize
2636 }
2637 };
2638
2639 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2640 (VkDependencyFlags)0,
2641 0, (const VkMemoryBarrier*)DE_NULL,
2642 0, (const VkBufferMemoryBarrier*)DE_NULL,
2643 1, &imageBarrier);
2644
2645 vk.cmdBindPipeline(*cmdBuffer, bindPoint, *pipeline);
2646
2647 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2648 VkClearValue clearColor = makeClearValueColorU32(0,0,0,0);
2649
2650 VkMemoryBarrier memBarrier =
2651 {
2652 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
2653 DE_NULL, // pNext
2654 0u, // srcAccessMask
2655 0u, // dstAccessMask
2656 };
2657
2658 vk.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
2659
2660 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2661 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2662 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, m_data.allPipelineStages,
2663 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2664
2665 if (m_data.stage == STAGE_COMPUTE)
2666 {
2667 vk.cmdDispatch(*cmdBuffer, DIM, DIM, 1);
2668 }
2669 else if (m_data.stage == STAGE_RAYGEN_NV)
2670 {
2671 vk.cmdTraceRaysNV(*cmdBuffer,
2672 **sbtBuffer, 0,
2673 DE_NULL, 0, 0,
2674 DE_NULL, 0, 0,
2675 DE_NULL, 0, 0,
2676 DIM, DIM, 1);
2677 }
2678 else if (isRayTracingStageKHR(m_data.stage))
2679 {
2680 cmdTraceRays(vk,
2681 *cmdBuffer,
2682 &raygenShaderBindingTableRegion,
2683 &missShaderBindingTableRegion,
2684 &hitShaderBindingTableRegion,
2685 &callableShaderBindingTableRegion,
2686 DIM, DIM, 1);
2687 }
2688 else
2689 {
2690 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
2691 makeRect2D(DIM, DIM),
2692 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2693 // Draw a point cloud for vertex shader testing, and a single quad for fragment shader testing
2694 if (m_data.stage == STAGE_VERTEX)
2695 {
2696 vk.cmdDraw(*cmdBuffer, DIM*DIM, 1u, 0u, 0u);
2697 }
2698 else
2699 {
2700 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
2701 }
2702 endRenderPass(vk, *cmdBuffer);
2703 }
2704
2705 memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
2706 memBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
2707 vk.cmdPipelineBarrier(*cmdBuffer, m_data.allPipelineStages, VK_PIPELINE_STAGE_TRANSFER_BIT,
2708 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2709
2710 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(DIM, DIM, 1u),
2711 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2712 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **copyBuffer, 1u, ©Region);
2713
2714 const VkBufferMemoryBarrier copyBufferBarrier =
2715 {
2716 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2717 DE_NULL, // const void* pNext;
2718 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2719 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2720 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2721 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2722 **copyBuffer, // VkBuffer buffer;
2723 0u, // VkDeviceSize offset;
2724 VK_WHOLE_SIZE, // VkDeviceSize size;
2725 };
2726
2727 // Add a barrier to read the copy buffer after copying.
2728 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0u, DE_NULL, 1u, ©BufferBarrier, 0u, DE_NULL);
2729
2730 // Copy all storage images to the storage image buffer.
2731 VkBufferImageCopy storageImgCopyRegion =
2732 {
2733 0u, // VkDeviceSize bufferOffset;
2734 0u, // uint32_t bufferRowLength;
2735 0u, // uint32_t bufferImageHeight;
2736 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
2737 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
2738 makeExtent3D(1u, 1u, 1u), // VkExtent3D imageExtent;
2739 };
2740
2741 for (deUint32 i = 0; i < storageImageCount; ++i)
2742 {
2743 storageImgCopyRegion.bufferOffset = sizeof(deInt32) * i;
2744 vk.cmdCopyImageToBuffer(*cmdBuffer, storageImages[i].get(), VK_IMAGE_LAYOUT_GENERAL, **storageImgBuffer, 1u, &storageImgCopyRegion);
2745 }
2746
2747 const VkBufferMemoryBarrier storageImgBufferBarrier =
2748 {
2749 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2750 DE_NULL, // const void* pNext;
2751 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2752 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2753 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2754 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2755 **storageImgBuffer, // VkBuffer buffer;
2756 0u, // VkDeviceSize offset;
2757 VK_WHOLE_SIZE, // VkDeviceSize size;
2758 };
2759
2760 // Add a barrier to read the storage image buffer after copying.
2761 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0u, DE_NULL, 1u, &storageImgBufferBarrier, 0u, DE_NULL);
2762
2763 const VkBufferMemoryBarrier descriptorBufferBarrier =
2764 {
2765 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2766 DE_NULL, // const void* pNext;
2767 (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT), // VkAccessFlags srcAccessMask;
2768 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2769 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2770 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2771 **buffer, // VkBuffer buffer;
2772 0u, // VkDeviceSize offset;
2773 VK_WHOLE_SIZE, // VkDeviceSize size;
2774 };
2775
2776 // Add a barrier to read stored data from shader writes in descriptor memory for other types of descriptors.
2777 vk.cmdPipelineBarrier(*cmdBuffer, m_data.allPipelineStages, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &descriptorBufferBarrier, 0u, nullptr);
2778
2779 endCommandBuffer(vk, *cmdBuffer);
2780
2781 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2782
2783 // Verify output image.
2784 deUint32 *ptr = (deUint32 *)copyBuffer->getAllocation().getHostPtr();
2785 invalidateAlloc(vk, device, copyBuffer->getAllocation());
2786
2787 deUint32 failures = 0;
2788 auto& log = m_context.getTestContext().getLog();
2789
2790 for (deUint32 i = 0; i < DIM*DIM; ++i)
2791 {
2792 if (ptr[i] != 1)
2793 {
2794 failures++;
2795 log << tcu::TestLog::Message << "Failure in copy buffer, ptr[" << i << "] = " << ptr[i] << tcu::TestLog::EndMessage;
2796 }
2797 }
2798
2799 // Verify descriptors with writes.
2800 invalidateMappedMemoryRange(vk, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2801 invalidateMappedMemoryRange(vk, device, storageImgBuffer->getAllocation().getMemory(), storageImgBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2802
2803 for (const auto& descIdWriteInfo : randomLayout.descriptorWrites)
2804 {
2805 const auto& writeInfo = descIdWriteInfo.second;
2806 if (writeInfo.writeGenerated && *writeInfo.ptr != writeInfo.expected)
2807 {
2808 failures++;
2809 log << tcu::TestLog::Message << "Failure in write operation; expected " << writeInfo.expected << " and found " << *writeInfo.ptr << tcu::TestLog::EndMessage;
2810 }
2811 }
2812
2813 if (failures == 0)
2814 return tcu::TestStatus::pass("Pass");
2815 else
2816 return tcu::TestStatus::fail("Fail (failures=" + de::toString(failures) + ")");
2817 }
2818
2819 } // anonymous
2820
createDescriptorSetRandomTests(tcu::TestContext & testCtx)2821 tcu::TestCaseGroup* createDescriptorSetRandomTests (tcu::TestContext& testCtx)
2822 {
2823 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "descriptorset_random", "Randomly-generated desciptor set layouts"));
2824
2825 deUint32 seed = 0;
2826
2827 typedef struct
2828 {
2829 deUint32 count;
2830 const char* name;
2831 const char* description;
2832 } TestGroupCase;
2833
2834 TestGroupCase setsCases[] =
2835 {
2836 { 4, "sets4", "4 descriptor sets" },
2837 { 8, "sets8", "8 descriptor sets" },
2838 { 16, "sets16", "16 descriptor sets" },
2839 { 32, "sets32", "32 descriptor sets" },
2840 };
2841
2842 TestGroupCase indexCases[] =
2843 {
2844 { INDEX_TYPE_NONE, "noarray", "all descriptor declarations are not arrays" },
2845 { INDEX_TYPE_CONSTANT, "constant", "constant indexing of descriptor arrays" },
2846 { INDEX_TYPE_PUSHCONSTANT, "unifindexed", "indexing descriptor arrays with push constants" },
2847 { INDEX_TYPE_DEPENDENT, "dynindexed", "dynamically uniform indexing descriptor arrays" },
2848 { INDEX_TYPE_RUNTIME_SIZE, "runtimesize", "runtime-size declarations of descriptor arrays" },
2849 };
2850
2851 TestGroupCase uboCases[] =
2852 {
2853 { 0, "noubo", "no ubos" },
2854 { 12, "ubolimitlow", "spec minmax ubo limit" },
2855 { 4096, "ubolimithigh", "high ubo limit" },
2856 };
2857
2858 TestGroupCase sboCases[] =
2859 {
2860 { 0, "nosbo", "no ssbos" },
2861 { 4, "sbolimitlow", "spec minmax ssbo limit" },
2862 { 4096, "sbolimithigh", "high ssbo limit" },
2863 };
2864
2865 TestGroupCase iaCases[] =
2866 {
2867 { 0, "noia", "no input attachments" },
2868 { 4, "ialimitlow", "spec minmax input attachment limit" },
2869 { 64, "ialimithigh", "high input attachment limit" },
2870 };
2871
2872 TestGroupCase sampledImgCases[] =
2873 {
2874 { 0, "nosampledimg", "no sampled images" },
2875 { 16, "sampledimglow", "spec minmax image limit" },
2876 { 4096, "sampledimghigh", "high image limit" },
2877 };
2878
2879 const struct
2880 {
2881 deUint32 sImgCount;
2882 deUint32 sTexCount;
2883 const char* name;
2884 const char* description;
2885 } sImgTexCases[] =
2886 {
2887 { 1, 0, "outimgonly", "output storage image only" },
2888 { 1, 3, "outimgtexlow", "output image low storage tex limit" },
2889 { 4, 0, "lowimgnotex", "minmax storage images and no storage tex" },
2890 { 3, 1, "lowimgsingletex", "low storage image single storage texel" },
2891 { 2048, 2048, "storageimghigh", "high limit of storage images and texel buffers" },
2892 };
2893
2894 const struct
2895 {
2896 deUint32 iubCount;
2897 deUint32 iubSize;
2898 const char* name;
2899 const char* description;
2900 } iubCases[] =
2901 {
2902 { 0, 0, "noiub", "no inline uniform blocks" },
2903 { 4, 256, "iublimitlow", "inline uniform blocks low limit" },
2904 { 8, 4096, "iublimithigh", "inline uniform blocks high limit" },
2905 };
2906
2907 TestGroupCase stageCases[] =
2908 {
2909 { STAGE_COMPUTE, "comp", "compute" },
2910 { STAGE_FRAGMENT, "frag", "fragment" },
2911 { STAGE_VERTEX, "vert", "vertex" },
2912 { STAGE_RAYGEN_NV, "rgnv", "raygen_nv" },
2913 { STAGE_RAYGEN, "rgen", "raygen" },
2914 { STAGE_INTERSECT, "sect", "intersect" },
2915 { STAGE_ANY_HIT, "ahit", "any_hit" },
2916 { STAGE_CLOSEST_HIT,"chit", "closest_hit" },
2917 { STAGE_MISS, "miss", "miss" },
2918 { STAGE_CALLABLE, "call", "callable" },
2919 };
2920
2921 TestGroupCase uabCases[] =
2922 {
2923 { UPDATE_AFTER_BIND_DISABLED, "nouab", "no update after bind" },
2924 { UPDATE_AFTER_BIND_ENABLED, "uab", "enable update after bind" },
2925 };
2926
2927 for (int setsNdx = 0; setsNdx < DE_LENGTH_OF_ARRAY(setsCases); setsNdx++)
2928 {
2929 de::MovePtr<tcu::TestCaseGroup> setsGroup(new tcu::TestCaseGroup(testCtx, setsCases[setsNdx].name, setsCases[setsNdx].description));
2930 for (int indexNdx = 0; indexNdx < DE_LENGTH_OF_ARRAY(indexCases); indexNdx++)
2931 {
2932 de::MovePtr<tcu::TestCaseGroup> indexGroup(new tcu::TestCaseGroup(testCtx, indexCases[indexNdx].name, indexCases[indexNdx].description));
2933 for (int uboNdx = 0; uboNdx < DE_LENGTH_OF_ARRAY(uboCases); uboNdx++)
2934 {
2935 de::MovePtr<tcu::TestCaseGroup> uboGroup(new tcu::TestCaseGroup(testCtx, uboCases[uboNdx].name, uboCases[uboNdx].description));
2936 for (int sboNdx = 0; sboNdx < DE_LENGTH_OF_ARRAY(sboCases); sboNdx++)
2937 {
2938 de::MovePtr<tcu::TestCaseGroup> sboGroup(new tcu::TestCaseGroup(testCtx, sboCases[sboNdx].name, sboCases[sboNdx].description));
2939 for (int sampledImgNdx = 0; sampledImgNdx < DE_LENGTH_OF_ARRAY(sampledImgCases); sampledImgNdx++)
2940 {
2941 de::MovePtr<tcu::TestCaseGroup> sampledImgGroup(new tcu::TestCaseGroup(testCtx, sampledImgCases[sampledImgNdx].name, sampledImgCases[sampledImgNdx].description));
2942 for (int storageImgNdx = 0; storageImgNdx < DE_LENGTH_OF_ARRAY(sImgTexCases); ++storageImgNdx)
2943 {
2944 de::MovePtr<tcu::TestCaseGroup> storageImgGroup(new tcu::TestCaseGroup(testCtx, sImgTexCases[storageImgNdx].name, sImgTexCases[storageImgNdx].description));
2945 for (int iubNdx = 0; iubNdx < DE_LENGTH_OF_ARRAY(iubCases); iubNdx++)
2946 {
2947 de::MovePtr<tcu::TestCaseGroup> iubGroup(new tcu::TestCaseGroup(testCtx, iubCases[iubNdx].name, iubCases[iubNdx].description));
2948 for (int uabNdx = 0; uabNdx < DE_LENGTH_OF_ARRAY(uabCases); uabNdx++)
2949 {
2950 de::MovePtr<tcu::TestCaseGroup> uabGroup(new tcu::TestCaseGroup(testCtx, uabCases[uabNdx].name, uabCases[uabNdx].description));
2951 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stageCases); stageNdx++)
2952 {
2953 const Stage currentStage = static_cast<Stage>(stageCases[stageNdx].count);
2954 const VkFlags rtShaderStagesNV = currentStage == STAGE_RAYGEN_NV ? VK_SHADER_STAGE_RAYGEN_BIT_NV : 0;
2955 const VkFlags rtPipelineStagesNV = currentStage == STAGE_RAYGEN_NV ? VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV : 0;
2956 const VkFlags rtShaderStagesKHR = isRayTracingStageKHR(currentStage) ? ALL_RAY_TRACING_STAGES : 0;
2957 const VkFlags rtPipelineStagesKHR = isRayTracingStageKHR(currentStage) ? VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR : 0;
2958 const VkFlags rtShaderStages = rtShaderStagesNV | rtShaderStagesKHR;
2959 const VkFlags rtPipelineStages = rtPipelineStagesNV | rtPipelineStagesKHR;
2960
2961 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stageCases[stageNdx].name, stageCases[stageNdx].description));
2962 for (int iaNdx = 0; iaNdx < DE_LENGTH_OF_ARRAY(iaCases); ++iaNdx)
2963 {
2964 // Input attachments can only be used in the fragment stage.
2965 if (currentStage != STAGE_FRAGMENT && iaCases[iaNdx].count > 0u)
2966 continue;
2967
2968 // Allow only one high limit or all of them.
2969 deUint32 highLimitCount = 0u;
2970 if (uboNdx == DE_LENGTH_OF_ARRAY(uboCases) - 1) ++highLimitCount;
2971 if (sboNdx == DE_LENGTH_OF_ARRAY(sboCases) - 1) ++highLimitCount;
2972 if (sampledImgNdx == DE_LENGTH_OF_ARRAY(sampledImgCases) - 1) ++highLimitCount;
2973 if (storageImgNdx == DE_LENGTH_OF_ARRAY(sImgTexCases) - 1) ++highLimitCount;
2974 if (iaNdx == DE_LENGTH_OF_ARRAY(iaCases) - 1) ++highLimitCount;
2975
2976 if (highLimitCount > 1 && highLimitCount < 5)
2977 continue;
2978
2979 // Allow only all, all-but-one, none or one "zero limits" at the same time, except for inline uniform blocks.
2980 deUint32 zeroLimitCount = 0u;
2981 if (uboNdx == 0) ++zeroLimitCount;
2982 if (sboNdx == 0) ++zeroLimitCount;
2983 if (sampledImgNdx == 0) ++zeroLimitCount;
2984 if (storageImgNdx == 0) ++zeroLimitCount;
2985 if (iaNdx == 0) ++zeroLimitCount;
2986
2987 if (zeroLimitCount > 1 && zeroLimitCount < 4)
2988 continue;
2989
2990 // Avoid using multiple storage images if no dynamic indexing is being used.
2991 if (storageImgNdx >= 2 && indexNdx < 2)
2992 continue;
2993
2994 // Skip the case of no UBOs, SSBOs or sampled images when no dynamic indexing is being used.
2995 if ((uboNdx == 0 || sboNdx == 0 || sampledImgNdx == 0) && indexNdx < 2)
2996 continue;
2997
2998 de::MovePtr<tcu::TestCaseGroup> iaGroup(new tcu::TestCaseGroup(testCtx, iaCases[iaNdx].name, iaCases[iaNdx].description));
2999
3000 // Generate 10 random cases when working with only 4 sets and the number of descriptors is low. Otherwise just one case.
3001 // Exception: the case of no descriptors of any kind only needs one case.
3002 const deUint32 numSeeds = (setsCases[setsNdx].count == 4 && uboNdx < 2 && sboNdx < 2 && sampledImgNdx < 2 && storageImgNdx < 4 && iubNdx == 0 && iaNdx < 2 &&
3003 (uboNdx != 0 || sboNdx != 0 || sampledImgNdx != 0 || storageImgNdx != 0 || iaNdx != 0)) ? 10 : 1;
3004
3005 for (deUint32 rnd = 0; rnd < numSeeds; ++rnd)
3006 {
3007 const VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
3008 const VkFlags allPipelineStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
3009
3010 CaseDef c =
3011 {
3012 (IndexType)indexCases[indexNdx].count, // IndexType indexType;
3013 setsCases[setsNdx].count, // deUint32 numDescriptorSets;
3014 uboCases[uboNdx].count, // deUint32 maxPerStageUniformBuffers;
3015 8, // deUint32 maxUniformBuffersDynamic;
3016 sboCases[sboNdx].count, // deUint32 maxPerStageStorageBuffers;
3017 4, // deUint32 maxStorageBuffersDynamic;
3018 sampledImgCases[sampledImgNdx].count, // deUint32 maxPerStageSampledImages;
3019 sImgTexCases[storageImgNdx].sImgCount, // deUint32 maxPerStageStorageImages;
3020 sImgTexCases[storageImgNdx].sTexCount, // deUint32 maxPerStageStorageTexelBuffers;
3021 iubCases[iubNdx].iubCount, // deUint32 maxInlineUniformBlocks;
3022 iubCases[iubNdx].iubSize, // deUint32 maxInlineUniformBlockSize;
3023 iaCases[iaNdx].count, // deUint32 maxPerStageInputAttachments;
3024 currentStage, // Stage stage;
3025 (UpdateAfterBind)uabCases[uabNdx].count, // UpdateAfterBind uab;
3026 seed++, // deUint32 seed;
3027 rtShaderStages ? rtShaderStages : allShaderStages, // VkFlags allShaderStages;
3028 rtPipelineStages ? rtPipelineStages : allPipelineStages, // VkFlags allPipelineStages;
3029 nullptr, // std::shared_ptr<RandomLayout> randomLayout;
3030 };
3031
3032 string name = de::toString(rnd);
3033 iaGroup->addChild(new DescriptorSetRandomTestCase(testCtx, name.c_str(), "test", c));
3034 }
3035 stageGroup->addChild(iaGroup.release());
3036 }
3037 uabGroup->addChild(stageGroup.release());
3038 }
3039 iubGroup->addChild(uabGroup.release());
3040 }
3041 storageImgGroup->addChild(iubGroup.release());
3042 }
3043 sampledImgGroup->addChild(storageImgGroup.release());
3044 }
3045 sboGroup->addChild(sampledImgGroup.release());
3046 }
3047 uboGroup->addChild(sboGroup.release());
3048 }
3049 indexGroup->addChild(uboGroup.release());
3050 }
3051 setsGroup->addChild(indexGroup.release());
3052 }
3053 group->addChild(setsGroup.release());
3054 }
3055 return group.release();
3056 }
3057
3058 } // BindingModel
3059 } // vkt
3060