• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::__anon13c2e8e70111::DescriptorId116 	DescriptorId (deUint32 set_, deUint32 binding_, deUint32 number_)
117 		: set(set_), binding(binding_), number(number_)
118 		{}
119 
operator <vkt::BindingModel::__anon13c2e8e70111::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::__anon13c2e8e70111::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, &copyRegion);
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, &copyBufferBarrier, 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