• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Vulkan Decriptor Indexing Tests
22 *//*--------------------------------------------------------------------*/
23 
24 #include <algorithm>
25 #include <iostream>
26 #include <iterator>
27 #include <functional>
28 #include <sstream>
29 #include <utility>
30 #include <vector>
31 
32 #include "vktDescriptorSetsIndexingTests.hpp"
33 
34 #include "vkBuilderUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkDefs.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkPlatform.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 
43 #include "tcuTestLog.hpp"
44 #include "tcuResource.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuCommandLine.hpp"
47 #include "tcuStringTemplate.hpp"
48 #include "tcuSurface.hpp"
49 #include "tcuVectorUtil.hpp"
50 
51 #include "deRandom.hpp"
52 #include "deMath.h"
53 #include "deStringUtil.hpp"
54 
55 namespace vkt
56 {
57 namespace DescriptorIndexing
58 {
59 namespace
60 {
61 using namespace vk;
62 using tcu::UVec2;
63 using tcu::Vec4;
64 using tcu::TestStatus;
65 using tcu::PixelBufferAccess;
66 using tcu::Texture2D;
67 
68 #define RESOLUTION_width	64
69 #define RESOLUTION_height	64
70 static const VkExtent3D RESOLUTION = { RESOLUTION_width, RESOLUTION_height, 1 };
71 
72 #define MAX_DESCRIPTORS		4200
73 #define FUZZY_COMPARE		DE_FALSE
74 #define	CMP_THRESHOLD		0.02f
75 
76 #define BINDING_Undefined				0
77 #define BINDING_UniformBuffer			1
78 #define BINDING_StorageBuffer			2
79 #define BINDING_UniformTexelBuffer		3
80 #define BINDING_StorageTexelBuffer		4
81 #define BINDING_Sampler					5
82 #define BINDING_SampledImage			6
83 #define BINDING_CombinedImageSampler	7
84 #define BINDING_UniformBufferDynamic	8
85 #define BINDING_StorageBufferDynamic	9
86 #define BINDING_InputAttachment			10
87 #define BINDING_StorageImage			11
88 #define BINDING_DescriptorEnumerator	12
89 
90 static const VkExtent3D			smallImageExtent				= { 4, 4, 1 };
91 static const VkExtent3D			bigImageExtent					= { 32, 32, 1 };
92 static const VkDescriptorType	VK_DESCRIPTOR_TYPE_UNDEFINED = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
93 
94 template<deUint32 BindingNumber>
95 struct Binding
96 {
97 	static const deUint32	binding	= BindingNumber;
98 };
99 
100 struct BindingUniformBuffer : Binding<BINDING_UniformBuffer>
101 {
102 	typedef struct
103 	{
104 		tcu::Vec4 c;
105 	} Data;
106 };
107 
108 struct BindingStorageBuffer : Binding<BINDING_StorageBuffer>
109 {
110 	typedef struct
111 	{
112 		tcu::Vec4 cnew;
113 		tcu::Vec4 cold;
114 	} Data;
115 };
116 
117 struct TestCaseParams
118 {
119 	VkDescriptorType	descriptorType;		// used only to distinguish test class instance
120 	VkShaderStageFlags	stageFlags;			// used only to build a proper program
121 	VkExtent3D			frameResolution;	// target frame buffer resolution
122 	bool				updateAfterBind;	// whether a test will use update after bind feature
123 	bool				calculateInLoop;	// perform calculation in a loop
124 	bool				usesMipMaps;		// this makes a sense and affects in image test cases only
125 	bool				minNonUniform;		// whether a test will use the minimum nonUniform decorations
126 	deBool				fuzzyComparison;	// if true then a test will use fuzzy comparison, otherwise float threshold
127 	float				thresholdValue;		// a threshold that will be used for both, float and fuzzy comparisons
128 };
129 
130 struct TestParams
131 {
132 	VkShaderStageFlags	stageFlags;
133 	VkDescriptorType	descriptorType;
134 	deUint32			descriptorBinding;
135 	VkDescriptorType	additionalDescriptorType;
136 	deUint32			additionalDescriptorBinding;
137 	bool				copyBuffersToImages;
138 	bool				allowVertexStoring;
139 	VkExtent3D			frameResolution;
140 	bool				updateAfterBind;
141 	bool				calculateInLoop;
142 	bool				usesMipMaps;
143 	bool				minNonUniform;
144 	deBool				fuzzyComparison;
145 	float				thresholdValue;
146 
TestParamsvkt::DescriptorIndexing::__anonefe559e50111::TestParams147 	TestParams			(VkShaderStageFlags		stageFlags_,
148 						VkDescriptorType		descriptorType_,
149 						deUint32				descriptorBinding_,
150 						VkDescriptorType		additionalDescriptorType_,
151 						deUint32				additionalDescriptorBinding_,
152 						bool					copyBuffersToImages_,
153 						bool					allowVertexStoring_,
154 						const TestCaseParams&	caseParams)
155 		: stageFlags							(stageFlags_)
156 		, descriptorType						(descriptorType_)
157 		, descriptorBinding						(descriptorBinding_)
158 		, additionalDescriptorType				(additionalDescriptorType_)
159 		, additionalDescriptorBinding			(additionalDescriptorBinding_)
160 		, copyBuffersToImages					(copyBuffersToImages_)
161 		, allowVertexStoring					(allowVertexStoring_)
162 		, frameResolution						(caseParams.frameResolution)
163 		, updateAfterBind						(caseParams.updateAfterBind)
164 		, calculateInLoop						(caseParams.calculateInLoop)
165 		, usesMipMaps							(caseParams.usesMipMaps)
166 		, minNonUniform							(caseParams.minNonUniform)
167 		, fuzzyComparison						(caseParams.fuzzyComparison ? true : false)
168 		, thresholdValue						(caseParams.thresholdValue)
169 	{
170 	}
171 };
172 
173 struct DescriptorEnumerator
174 {
175 	ut::BufferHandleAllocSp							buffer;
176 	ut::BufferViewSp								bufferView;
177 	VkDeviceSize									bufferSize;
178 
179 	Move<VkDescriptorSetLayout>						descriptorSetLayout;
180 	Move<VkDescriptorPool>							descriptorPool;
181 	Move<VkDescriptorSet>							descriptorSet;
182 
183 	void init(const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount);
184 	void update(const vkt::Context& context);
185 };
186 
187 struct IterateCommonVariables
188 {
189 	// An amount of descriptors of a given type available on the platform
190 	deUint32										availableDescriptorCount;
191 	// An amount of valid descriptors that have connected a buffers to them
192 	deUint32										validDescriptorCount;
193 	// As the name suggests, sometimes it is used as invocationCount
194 	deUint32										vertexCount;
195 	VkRect2D										renderArea;
196 	VkDeviceSize									dataAlignment;
197 	deUint32										lowerBound;
198 	deUint32										upperBound;
199 
200 	DescriptorEnumerator							descriptorEnumerator;
201 
202 	ut::BufferHandleAllocSp							vertexAttributesBuffer;
203 	ut::BufferHandleAllocSp							descriptorsBuffer;
204 	std::vector<VkDescriptorBufferInfo>				descriptorsBufferInfos;
205 	std::vector<ut::BufferViewSp>					descriptorsBufferViews;
206 	std::vector<ut::ImageViewSp>					descriptorImageViews;
207 	std::vector<ut::SamplerSp>						descriptorSamplers;
208 	std::vector<ut::ImageHandleAllocSp>				descriptorsImages;
209 	ut::FrameBufferSp								frameBuffer;
210 
211 	Move<VkDescriptorSetLayout>						descriptorSetLayout;
212 	Move<VkDescriptorPool>							descriptorPool;
213 	Move<VkDescriptorSet>							descriptorSet;
214 	Move<VkPipelineLayout>							pipelineLayout;
215 	Move<VkRenderPass>								renderPass;
216 	Move<VkPipeline>								pipeline;
217 	Move<VkCommandBuffer>							commandBuffer;
218 };
219 
220 class CommonDescriptorInstance : public TestInstance
221 {
222 public:
223 								CommonDescriptorInstance		(Context&									context,
224 																const TestParams&							testParams);
225 
226 	deUint32					computeAvailableDescriptorCount	(VkDescriptorType							descriptorType,
227 																 bool										reserveUniformTexelBuffer) const;
228 
229 	Move<VkDescriptorSetLayout>	createDescriptorSetLayout		(bool										reserveUniformTexelBuffer,
230 																 deUint32&									descriptorCount) const;
231 
232 	Move<VkDescriptorPool>		createDescriptorPool			(deUint32									descriptorCount) const;
233 
234 	Move<VkDescriptorSet>		createDescriptorSet				(VkDescriptorPool							dsPool,
235 																 VkDescriptorSetLayout						dsLayout) const;
236 
237 	struct attributes
238 	{
239 		typedef tcu::Vec4	vec4;
240 		typedef tcu::Vec2	vec2;
241 		typedef tcu::IVec4	ivec4;
242 		vec4			position;
243 		vec2			normalpos;
244 		ivec4			index;
operator ()vkt::DescriptorIndexing::__anonefe559e50111::CommonDescriptorInstance::attributes245 		attributes& operator()(const vec4& pos)
246 		{
247 			position = pos;
248 
249 			normalpos.x() = (pos.x() + 1.0f) / 2.0f;
250 			normalpos.y() = (pos.y() + 1.0f) / 2.0f;
251 
252 			return *this;
253 		}
254 	};
255 	void						createVertexAttributeBuffer		(ut::BufferHandleAllocSp&					buffer,
256 																 deUint32									availableDescriptorCount) const;
257 
258 	static std::string			substBinding					(deUint32									binding,
259 																 const char*								str,
260 																 deUint32									count = 0,
261 																 const char*								name = DE_NULL);
262 
263 	static const char*			getVertexShaderProlog			(void);
264 
265 	static const char*			getFragmentShaderProlog			(void);
266 
267 	static const char*			getShaderEpilog					(void);
268 
269 	static bool					performWritesInVertex			(VkDescriptorType							descriptorType);
270 
271 	static bool					performWritesInVertex			(VkDescriptorType							descriptorType,
272 																 const Context&						        context);
273 
274 	static std::string			getShaderAsm					(VkShaderStageFlagBits						shaderType,
275 																 const TestCaseParams&						testCaseParams,
276 																 bool										allowVertexStoring);
277 
278 	static std::string			getShaderSource                 (VkShaderStageFlagBits						shaderType,
279 		                                                         const TestCaseParams&						testCaseParams,
280 		                                                         bool										allowVertexStoring);
281 
282 	static std::string			getColorAccess					(VkDescriptorType							descriptorType,
283 																 const char*								indexVariableName,
284 																 bool										usesMipMaps);
285 
286 	static std::string			getFragmentReturnSource			(const std::string&							colorAccess);
287 
288 	static std::string			getFragmentLoopSource			(const std::string&							colorAccess1,
289 																 const std::string&							colorAccess2);
290 
291 	virtual Move<VkRenderPass>	createRenderPass				(const IterateCommonVariables&				variables);
292 
293 	struct push_constant
294 	{
295 		deInt32	lowerBound;
296 		deInt32	upperBound;
297 	};
298 	VkPushConstantRange			makePushConstantRange			(void) const;
299 
300 	Move<VkPipelineLayout>		createPipelineLayout			(const std::vector<VkDescriptorSetLayout>&	descriptorSetLayouts) const;
301 
302 	// Creates graphics or compute pipeline and appropriate shaders' modules according the testCaseParams.stageFlags
303 	// In the case of compute pipeline renderPass parameter is ignored.
304 	// Viewport will be created with a width and a height taken from testCaseParam.fragResolution.
305 	Move<VkPipeline>			createPipeline					(VkPipelineLayout							pipelineLayout,
306 																 VkRenderPass								renderPass);
307 
308 	virtual void				createFramebuffer				(ut::FrameBufferSp&							frameBuffer,
309 																 VkRenderPass								renderPass,
310 																 const IterateCommonVariables&				variables);
311 
312 	// Creates one big stagging buffer cutted out on chunks that can accomodate an element of elementSize size
313 	VkDeviceSize				createBuffers					(std::vector<VkDescriptorBufferInfo>&		bufferInfos,
314 																 ut::BufferHandleAllocSp&					buffer,
315 																 deUint32									elementCount,
316 																 deUint32									elementSize,
317 																 VkDeviceSize								alignment,
318 																 VkBufferUsageFlags							bufferUsage);
319 
320 	// Creates and binds an imagesCount of images with given parameters.
321 	// Additionally creates stagging buffer for their data and PixelBufferAccess for particular images.
322 	VkDeviceSize				createImages					(std::vector<ut::ImageHandleAllocSp>&		images,
323 																 std::vector<VkDescriptorBufferInfo>&		bufferInfos,
324 																 ut::BufferHandleAllocSp&					buffer,
325 																 VkBufferUsageFlags							bufferUsage,
326 																 const VkExtent3D&							imageExtent,
327 																 VkFormat									imageFormat,
328 																 VkImageLayout								imageLayout,
329 																 deUint32									imageCount,
330 																 bool										withMipMaps = false);
331 
332 	void						createBuffersViews				(std::vector<ut::BufferViewSp>&				views,
333 																 const std::vector<VkDescriptorBufferInfo>&	bufferInfos,
334 																 VkFormat									format);
335 
336 	void						createImagesViews				(std::vector<ut::ImageViewSp>&				views,
337 																 const std::vector<ut::ImageHandleAllocSp>&	images,
338 																 VkFormat									format);
339 
340 	virtual void				copyBuffersToImages				(IterateCommonVariables&					variables);
341 
342 	virtual void				copyImagesToBuffers				(IterateCommonVariables&					variables);
343 
344 	PixelBufferAccess			getPixelAccess					(deUint32									imageIndex,
345 																 const VkExtent3D&							imageExtent,
346 																 VkFormat									imageFormat,
347 																 const std::vector<VkDescriptorBufferInfo>&	bufferInfos,
348 																 const ut::BufferHandleAllocSp&				buffer,
349 																 deUint32									mipLevel = 0u) const;
350 
351 	virtual void				createAndPopulateDescriptors	(IterateCommonVariables&					variables) = 0;
352 
353 	virtual void				updateDescriptors				(IterateCommonVariables&					variables);
354 
355 	virtual void				iterateCollectResults			(ut::UpdatablePixelBufferAccessPtr&			result,
356 																 const IterateCommonVariables&				variables,
357 																 bool										fromTest);
358 
359 	void						iterateCommandSetup				(IterateCommonVariables&					variables);
360 
361 	void						iterateCommandBegin				(IterateCommonVariables&					variables,
362 																bool										firstPass = true);
363 
364 	void						iterateCommandEnd				(IterateCommonVariables&					variables,
365 																ut::UpdatablePixelBufferAccessPtr&	programResult,
366 																ut::UpdatablePixelBufferAccessPtr&	referenceResult,
367 																 bool										collectBeforeSubmit = true);
368 
369 	bool						iterateVerifyResults			(IterateCommonVariables&					variables,
370 																	 ut::UpdatablePixelBufferAccessPtr	programResult,
371 																	 ut::UpdatablePixelBufferAccessPtr	referenceResult);
372 
373 	Move<VkCommandBuffer>		createCmdBuffer					(void);
374 
375 	void						commandBindPipeline				(VkCommandBuffer							commandBuffer,
376 																 VkPipeline									pipeline);
377 
378 	void						commandBindVertexAttributes		(VkCommandBuffer							commandBuffer,
379 																 const ut::BufferHandleAllocSp&				vertexAttributesBuffer);
380 
381 	void						commandBindDescriptorSets		(VkCommandBuffer							commandBuffer,
382 																 VkPipelineLayout							pipelineLayout,
383 																 VkDescriptorSet							descriptorSet,
384 																 deUint32									descriptorSetIndex);
385 
386 	void						commandReadFrameBuffer			(ut::BufferHandleAllocSp&					content,
387 																 VkCommandBuffer							commandBuffer,
388 																 const ut::FrameBufferSp&					frameBuffer);
389 	ut::UpdatablePixelBufferAccessPtr
390 								commandReadFrameBuffer			(VkCommandBuffer							commandBuffer,
391 																 const ut::FrameBufferSp&					frameBuffer);
392 
393 	Move<VkFence>				commandSubmit					(VkCommandBuffer							commandBuffer);
394 
395 	virtual bool				verifyVertexWriteResults		(IterateCommonVariables&					variables);
396 
397 protected:
398 	virtual tcu::TestStatus		iterate							(void);
399 
400 protected:
401 	const VkDevice				m_vkd;
402 	const DeviceInterface&		m_vki;
403 	Allocator&					m_allocator;
404 	const VkQueue				m_queue;
405 	const deUint32				m_queueFamilyIndex;
406 	const Move<VkCommandPool>	m_commandPool;
407 	const VkFormat				m_colorFormat;
408 	const TestParams			m_testParams;
409 	static const tcu::Vec4		m_clearColor;
410 	const std::vector<float>	m_colorScheme;
411 	const deUint32				m_schemeSize;
412 
413 private:
414 
415 	Move<VkPipeline>			createGraphicsPipeline			(VkPipelineLayout							pipelineLayout,
416 																 VkRenderPass								renderPass);
417 
418 	Move<VkPipeline>			createComputePipeline			(VkPipelineLayout							pipelineLayout);
419 
420 	int							constructShaderModules			(void);
421 
422 	static std::vector<float>	createColorScheme();
423 
424 	Move<VkShaderModule>		m_vertexModule;
425 	Move<VkShaderModule>		m_fragmentModule;
426 	Move<VkShaderModule>		m_computeModule;
427 };
428 const tcu::Vec4 CommonDescriptorInstance::m_clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
429 
init(const vkt::Context & context,deUint32 vertexCount,deUint32 availableDescriptorCount)430 void DescriptorEnumerator::init (const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount)
431 {
432 	const VkDevice					device = context.getDevice();
433 	const DeviceInterface&			deviceInterface = context.getDeviceInterface();
434 
435 	const VkFormat					imageFormat = VK_FORMAT_R32G32B32A32_SINT;
436 	typedef ut::mapVkFormat2Type<imageFormat>::type pixelType;
437 	const VkDeviceSize				dataSize = vertexCount * sizeof(pixelType);
438 	const std::vector<deUint32>		primes = ut::generatePrimes(availableDescriptorCount);
439 	const deUint32					primeCount = static_cast<deUint32>(primes.size());
440 
441 	std::vector<pixelType>	data(vertexCount);
442 	// e.g. 2,3,5,7,11,13,2,3,5,7,...
443 	for (deUint32 idx = 0; idx < vertexCount; ++idx)
444 	{
445 		data[idx].x() = static_cast<pixelType::Element>(primes[idx % primeCount]);
446 		data[idx].y() = static_cast<pixelType::Element>(idx);
447 	}
448 
449 	bufferSize = ut::createBufferAndBind(buffer, context, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, dataSize);
450 	deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(dataSize));
451 
452 	const VkBufferViewCreateInfo bufferViewCreateInfo =
453 	{
454 		VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,		// sType
455 		DE_NULL,										// pNext
456 		0u,												// flags
457 		*(buffer.get()->buffer),						// buffer
458 		imageFormat,									// format
459 		0u,												// offset
460 		bufferSize,										// range
461 	};
462 
463 	bufferView = ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(deviceInterface, device, &bufferViewCreateInfo)));
464 
465 	const VkDescriptorSetLayoutBinding	binding =
466 	{
467 		BINDING_DescriptorEnumerator,					// binding
468 		VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		// descriptorType
469 		1u,												// descriptorCount
470 		VK_SHADER_STAGE_ALL,							// stageFlags
471 		DE_NULL,										// pImmutableSamplers
472 	};
473 
474 	const VkDescriptorSetLayoutCreateInfo	layoutCreateInfo =
475 	{
476 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
477 		DE_NULL,										// pNext
478 		0u,												// flags
479 		1u,												// bindingCount
480 		&binding,										// pBindings
481 	};
482 
483 	descriptorSetLayout = vk::createDescriptorSetLayout(deviceInterface, device, &layoutCreateInfo);
484 	descriptorPool = DescriptorPoolBuilder().addType(binding.descriptorType)
485 		.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
486 
487 	const VkDescriptorSetAllocateInfo	dsAllocInfo =
488 	{
489 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// sType
490 		DE_NULL,										// pNext
491 		*descriptorPool,								// descriptorPool
492 		1u,												// descriptorSetCount
493 		&(*descriptorSetLayout)							// pSetLayouts
494 	};
495 
496 	descriptorSet = vk::allocateDescriptorSet(deviceInterface, device, &dsAllocInfo);
497 }
498 
update(const vkt::Context & context)499 void DescriptorEnumerator::update (const vkt::Context& context)
500 {
501 	const VkDescriptorBufferInfo bufferInfo =
502 	{
503 		*(buffer.get()->buffer),					// buffer
504 		0u,											// offset
505 		bufferSize,									// range
506 	};
507 
508 	const VkWriteDescriptorSet writeInfo =
509 	{
510 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
511 		DE_NULL,									// pNext
512 		*descriptorSet,								// dstSet
513 		BINDING_DescriptorEnumerator,				// dstBinding
514 		0u,											// dstArrayElement
515 		1u,											// descriptorCount
516 		VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,	// descriptorType
517 		DE_NULL,									// pImageInfo
518 		&bufferInfo,								// pBufferInfo
519 		&(**bufferView),							// pTexelBufferView
520 	};
521 
522 	context.getDeviceInterface().updateDescriptorSets(context.getDevice(), 1u, &writeInfo, 0u, DE_NULL);
523 }
524 
CommonDescriptorInstance(Context & context,const TestParams & testParams)525 CommonDescriptorInstance::CommonDescriptorInstance					(Context&								context,
526 																	const TestParams&						testParams)
527 	: TestInstance		(context)
528 	, m_vkd				(context.getDevice())
529 	, m_vki				(context.getDeviceInterface())
530 	, m_allocator		(context.getDefaultAllocator())
531 	, m_queue			(context.getUniversalQueue())
532 	, m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
533 	, m_commandPool		(vk::createCommandPool(m_vki, m_vkd, (VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), m_queueFamilyIndex))
534 	, m_colorFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
535 	, m_testParams		(testParams)
536 	, m_colorScheme		(createColorScheme())
537 	, m_schemeSize		(static_cast<deUint32>(m_colorScheme.size()))
538 {
539 }
540 
computeAvailableDescriptorCount(VkDescriptorType descriptorType,bool reserveUniformTexelBuffer) const541 deUint32 CommonDescriptorInstance::computeAvailableDescriptorCount	(VkDescriptorType						descriptorType,
542 																	 bool									reserveUniformTexelBuffer) const
543 {
544 	DE_UNREF(descriptorType);
545 	const deUint32 vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
546 	const deUint32 availableDescriptorsOnDevice = ut::DeviceProperties(m_context).computeMaxPerStageDescriptorCount(m_testParams.descriptorType, m_testParams.updateAfterBind, reserveUniformTexelBuffer);
547 	return deMinu32(deMinu32(vertexCount, availableDescriptorsOnDevice), MAX_DESCRIPTORS);
548 }
549 
createDescriptorSetLayout(bool reserveUniformTexelBuffer,deUint32 & descriptorCount) const550 Move<VkDescriptorSetLayout>	CommonDescriptorInstance::createDescriptorSetLayout (bool						reserveUniformTexelBuffer,
551 																				 deUint32&					descriptorCount) const
552 {
553 	descriptorCount = computeAvailableDescriptorCount(m_testParams.descriptorType, reserveUniformTexelBuffer);
554 
555 	bool optional = (m_testParams.additionalDescriptorBinding != BINDING_Undefined) && (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED);
556 
557 	const VkDescriptorSetLayoutBinding	bindings[] =
558 	{
559 		{
560 			m_testParams.descriptorBinding,				// binding
561 			m_testParams.descriptorType,				// descriptorType
562 			descriptorCount,							// descriptorCount
563 			m_testParams.stageFlags,					// stageFlags
564 			DE_NULL,									// pImmutableSamplers
565 		},
566 		{
567 			m_testParams.additionalDescriptorBinding,	// binding
568 			m_testParams.additionalDescriptorType,		// descriptorType
569 			1,											// descriptorCount
570 			m_testParams.stageFlags,					// stageFlags
571 			DE_NULL,									// pImmutableSamplers
572 		}
573 	};
574 
575 	const VkDescriptorBindingFlags	bindingFlagUpdateAfterBind =
576 		m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0;
577 
578 	const VkDescriptorBindingFlags bindingFlags[] =
579 	{
580 		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind,
581 		VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind
582 	};
583 
584 	const VkDescriptorSetLayoutBindingFlagsCreateInfo	bindingCreateInfo =
585 	{
586 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
587 		DE_NULL,
588 		optional ? 2u : 1u,	// bindingCount
589 		bindingFlags,		// pBindingFlags
590 	};
591 
592 	const VkDescriptorSetLayoutCreateFlags	layoutCreateFlags =
593 		m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT : 0;
594 
595 	const VkDescriptorSetLayoutCreateInfo	layoutCreateInfo =
596 	{
597 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
598 		&bindingCreateInfo,		// pNext
599 		layoutCreateFlags,		// flags
600 		optional ? 2u : 1u,		// bindingCount
601 		bindings,				// pBindings
602 	};
603 
604 	return vk::createDescriptorSetLayout(m_vki, m_vkd, &layoutCreateInfo);
605 }
606 
createDescriptorPool(deUint32 descriptorCount) const607 Move<VkDescriptorPool>	CommonDescriptorInstance::createDescriptorPool (deUint32							descriptorCount) const
608 {
609 	const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
610 
611 	DescriptorPoolBuilder builder;
612 
613 	builder.addType(m_testParams.descriptorType, descriptorCount);
614 
615 	if (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED && m_testParams.additionalDescriptorBinding != BINDING_Undefined)
616 	{
617 		builder.addType(m_testParams.additionalDescriptorType, 1);
618 	}
619 
620 	return builder.build(m_vki, m_vkd, (VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | pcf), 1u);
621 }
622 
createDescriptorSet(VkDescriptorPool dsPool,VkDescriptorSetLayout dsLayout) const623 Move<VkDescriptorSet> CommonDescriptorInstance::createDescriptorSet	(VkDescriptorPool						dsPool,
624 																	 VkDescriptorSetLayout					dsLayout) const
625 {
626 	const VkDescriptorSetAllocateInfo	dsAllocInfo =
627 	{
628 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// sType;
629 		DE_NULL,											// pNext;
630 		dsPool,												// descriptorPool;
631 		1u,													// descriptorSetCount
632 		&dsLayout											// pSetLayouts
633 	};
634 
635 	return vk::allocateDescriptorSet(m_vki, m_vkd, &dsAllocInfo);
636 }
637 
createVertexAttributeBuffer(ut::BufferHandleAllocSp & buffer,deUint32 availableDescriptorCount) const638 void CommonDescriptorInstance::createVertexAttributeBuffer			(ut::BufferHandleAllocSp&				buffer,
639 																	 deUint32								availableDescriptorCount) const
640 {
641 	float						xSize			= 0.0f;
642 	float						ySize			= 0.0f;
643 
644 	const deUint32				invocationCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
645 	const std::vector<Vec4>		vertices		= ut::createVertices(m_testParams.frameResolution.width, m_testParams.frameResolution.height, xSize, ySize);
646 	const std::vector<deUint32>	primes			= ut::generatePrimes(availableDescriptorCount);
647 	const deUint32				primeCount		= static_cast<deUint32>(primes.size());
648 
649 	std::vector<attributes> data(vertices.size());
650 	std::transform(vertices.begin(), vertices.end(), data.begin(), attributes());
651 
652 	for (deUint32 invIdx = 0; invIdx < invocationCount; ++invIdx)
653 	{
654 		// r: 2,3,5,7,11,13,2,3,5,7,...
655 		data[invIdx].index.x() = primes[invIdx % primeCount];
656 
657 		// b: x index in texel coordinate
658 		data[invIdx].index.z() = invIdx % m_testParams.frameResolution.width;
659 
660 		//a: y index in texel coordinate
661 		data[invIdx].index.w() = invIdx / m_testParams.frameResolution.width;
662 	}
663 
664 	// g: 0,0,2,3,0,5,0,7,0,0,0,11,0,13,...
665 	for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
666 	{
667 		const deUint32 prime = primes[primeIdx];
668 		DE_ASSERT(prime < invocationCount);
669 		data[prime].index.y() = prime;
670 	}
671 
672 	const VkDeviceSize		dataSize = data.size() * sizeof(attributes);
673 
674 	VkDeviceSize			deviceSize = ut::createBufferAndBind(buffer, m_context, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, dataSize);
675 
676 	deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(deviceSize));
677 
678 	vk::flushAlloc(m_vki, m_vkd, *buffer->alloc);
679 }
680 
substBinding(deUint32 binding,const char * str,deUint32 count,const char * name)681 std::string CommonDescriptorInstance::substBinding					(deUint32								binding,
682 																	 const char*							str,
683 																	 deUint32								count,
684 																	 const char*							name)
685 {
686 	std::map<std::string, std::string> vars;
687 	vars["?"]	= de::toString(binding);
688 	vars["*"]	= (0 == count)		? ""		: de::toString(count);
689 	vars["VAR"]	= (DE_NULL == name)	? "data"	: name;
690 	return tcu::StringTemplate(str).specialize(vars);
691 }
692 
getVertexShaderProlog(void)693 const char* CommonDescriptorInstance::getVertexShaderProlog			(void)
694 {
695 	return
696 		"layout(location = 0) in  vec4  in_position;	\n"
697 		"layout(location = 1) in  vec2  in_normalpos;	\n"
698 		"layout(location = 2) in  ivec4 index;			\n"
699 		"layout(location = 0) out vec4  position;	\n"
700 		"layout(location = 1) out vec2  normalpos;	\n"
701 		"layout(location = 2) out int   vIndex;		\n"
702 		"layout(location = 3) out int   rIndex;		\n"
703 		"layout(location = 4) out int   gIndex;		\n"
704 		"layout(location = 5) out int   bIndex;		\n"
705 		"layout(location = 6) out int   aIndex;		\n"
706 		"void main()							\n"
707 		"{										\n"
708 		"    gl_PointSize = 0.2f;				\n"
709 		"    position = in_position;			\n"
710 		"    normalpos = in_normalpos;			\n"
711 		"    gl_Position = position;			\n"
712 		"    vIndex = gl_VertexIndex;			\n"
713 		"    rIndex = index.x;					\n"
714 		"    gIndex = index.y;					\n"
715 		"    bIndex = index.z;					\n"
716 		"    aIndex = index.w;					\n";
717 }
718 
getFragmentShaderProlog(void)719 const char* CommonDescriptorInstance::getFragmentShaderProlog		(void)
720 {
721 	return
722 		"layout(location = 0) out vec4     FragColor;	\n"
723 		"layout(location = 0) in flat vec4 position;	\n"
724 		"layout(location = 1) in flat vec2 normalpos;	\n"
725 		"layout(location = 2) in flat int  vIndex;		\n"
726 		"layout(location = 3) in flat int  rIndex;		\n"
727 		"layout(location = 4) in flat int  gIndex;		\n"
728 		"layout(location = 5) in flat int  bIndex;		\n"
729 		"layout(location = 6) in flat int  aIndex;		\n"
730 		"void main()									\n"
731 		"{												\n";
732 }
733 
getShaderEpilog(void)734 const char* CommonDescriptorInstance::getShaderEpilog				(void)
735 {
736 	return "}											\n";
737 }
738 
constructShaderModules(void)739 int	CommonDescriptorInstance::constructShaderModules				(void)
740 {
741 	int								result	= 0;
742 	tcu::TestLog&					log		= m_context.getTestContext().getLog();
743 
744 	if (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
745 	{
746 		++result;
747 		const std::string name = ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, false);
748 		m_computeModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
749 	}
750 	if (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
751 	{
752 		++result;
753 		const std::string name = ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
754 		m_fragmentModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
755 		log << tcu::TestLog::Message << "Finally used fragment shader: " << name << '\n' << tcu::TestLog::EndMessage;
756 	}
757 	if (m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
758 	{
759 		++result;
760 		const std::string name = ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
761 		m_vertexModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
762 		log << tcu::TestLog::Message << "Finally used vertex shader: " << name << '\n' << tcu::TestLog::EndMessage;
763 	}
764 
765 	DE_ASSERT(result > 0);
766 
767 	return result;
768 }
769 
createRenderPass(const IterateCommonVariables & variables)770 Move<VkRenderPass> CommonDescriptorInstance::createRenderPass		(const IterateCommonVariables&			variables)
771 {
772 	DE_UNREF(variables);
773 	if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
774 	{
775 		// Use VK_ATTACHMENT_LOAD_OP_LOAD to make the utility function select initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
776 		return vk::makeRenderPass(m_vki, m_vkd, m_colorFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD);
777 	}
778 	return Move<VkRenderPass>();
779 }
780 
makePushConstantRange(void) const781 VkPushConstantRange CommonDescriptorInstance::makePushConstantRange	(void) const
782 {
783 	const VkPushConstantRange pcr =
784 	{
785 		m_testParams.stageFlags,							// stageFlags
786 		0u,													// offset
787 		static_cast<deUint32>(sizeof(push_constant))		// size
788 	};
789 	return pcr;
790 }
791 
createPipelineLayout(const std::vector<VkDescriptorSetLayout> & descriptorSetLayouts) const792 Move<VkPipelineLayout> CommonDescriptorInstance::createPipelineLayout (const std::vector<VkDescriptorSetLayout>&	descriptorSetLayouts) const
793 {
794 	const VkPushConstantRange pcr = makePushConstantRange();
795 
796 	const VkPipelineLayoutCreateInfo createInfo =
797 	{
798 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// sType
799 		DE_NULL,											// pNext
800 		(VkPipelineLayoutCreateFlags)0,						// flags
801 		static_cast<deUint32>(descriptorSetLayouts.size()),	// setLayoutCount
802 		descriptorSetLayouts.data(),						// pSetLayouts;
803 		m_testParams.calculateInLoop ? 1u : 0u,				// pushConstantRangeCount
804 		m_testParams.calculateInLoop ? &pcr : DE_NULL,		// pPushConstantRanges
805 	};
806 
807 	return vk::createPipelineLayout(m_vki, m_vkd, &createInfo);
808 }
809 
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)810 void CommonDescriptorInstance::createFramebuffer					(ut::FrameBufferSp&							frameBuffer,
811 																	 VkRenderPass								renderPass,
812 																	 const IterateCommonVariables&				variables)
813 {
814 	DE_UNREF(variables);
815 	ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass);
816 }
817 
createPipeline(VkPipelineLayout pipelineLayout,VkRenderPass renderPass)818 Move<VkPipeline> CommonDescriptorInstance::createPipeline			(VkPipelineLayout							pipelineLayout,
819 																	 VkRenderPass								renderPass)
820 {	DE_ASSERT(VK_SHADER_STAGE_ALL != m_testParams.stageFlags);
821 
822 	constructShaderModules();
823 
824 	return (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
825 		? createComputePipeline(pipelineLayout)
826 		: createGraphicsPipeline(pipelineLayout, renderPass);
827 }
828 
createComputePipeline(VkPipelineLayout pipelineLayout)829 Move<VkPipeline> CommonDescriptorInstance::createComputePipeline	(VkPipelineLayout							pipelineLayout)
830 {
831 	const VkPipelineShaderStageCreateInfo	shaderStaegCreateInfo =
832 	{
833 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
834 		DE_NULL,								// pNext
835 		(VkPipelineShaderStageCreateFlags)0,	// flags
836 		VK_SHADER_STAGE_COMPUTE_BIT,			// stage
837 		*m_computeModule,						// module
838 		"main",									// pName
839 		(VkSpecializationInfo*)DE_NULL			// pSpecializationInfo
840 	};
841 
842 	const VkComputePipelineCreateInfo		pipelineCreateInfo =
843 	{
844 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
845 		DE_NULL,								// pNext
846 		0u,										// flags
847 		shaderStaegCreateInfo,					// stage
848 		pipelineLayout,							// layout
849 		(VkPipeline)0,							// basePipelineHandle
850 		0u,										// basePipelineIndex
851 	};
852 	return vk::createComputePipeline(m_vki, m_vkd, (VkPipelineCache)0u, &pipelineCreateInfo);
853 }
854 
createGraphicsPipeline(VkPipelineLayout pipelineLayout,VkRenderPass renderPass)855 Move<VkPipeline> CommonDescriptorInstance::createGraphicsPipeline	(VkPipelineLayout							pipelineLayout,
856 																	 VkRenderPass								renderPass)
857 {
858 	const VkVertexInputBindingDescription			bindingDescriptions[] =
859 	{
860 		{
861 			0u,													// binding
862 			sizeof(attributes),									// stride
863 			VK_VERTEX_INPUT_RATE_VERTEX,						// inputRate
864 		},
865 	};
866 
867 	const VkVertexInputAttributeDescription			attributeDescriptions[] =
868 	{
869 		{
870 			0u,													// location
871 			0u,													// binding
872 			ut::mapType2vkFormat<attributes::vec4>::value,		// format
873 			0u													// offset
874 		},														// @in_position
875 		{
876 			1u,													// location
877 			0u,													// binding
878 			ut::mapType2vkFormat<attributes::vec2>::value,		// format
879 			static_cast<deUint32>(sizeof(attributes::vec4))		// offset
880 		},														// @normalpos
881 		{
882 			2u,													// location
883 			0u,													// binding
884 			ut::mapType2vkFormat<attributes::ivec4>::value,		// format
885 			static_cast<deUint32>(sizeof(attributes::vec2)
886 								+ sizeof(attributes::vec4))		// offset
887 		},														// @index
888 	};
889 
890 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateCreateInfo	=
891 	{
892 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
893 		DE_NULL,
894 		(VkPipelineVertexInputStateCreateFlags)0,	// flags
895 		DE_LENGTH_OF_ARRAY(bindingDescriptions),	// vertexBindingDescriptionCount
896 		bindingDescriptions,						// pVertexBindingDescriptions
897 		DE_LENGTH_OF_ARRAY(attributeDescriptions),	// vertexAttributeDescriptionCount
898 		attributeDescriptions						// pVertexAttributeDescriptions
899 	};
900 
901 	const	VkDynamicState							dynamicStates[]				=
902 	{
903 		VK_DYNAMIC_STATE_SCISSOR
904 	};
905 
906 	const VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfo =
907 	{
908 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,  // sType
909 		DE_NULL,											   // pNext
910 		0u,													   // flags
911 		DE_LENGTH_OF_ARRAY(dynamicStates),					   // dynamicStateCount
912 		dynamicStates										   // pDynamicStates
913 	};
914 
915 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
916 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(0u, 0u));
917 
918 	DE_ASSERT(m_vertexModule && m_fragmentModule);
919 
920 	return vk::makeGraphicsPipeline(
921 		m_vki,											// vk
922 		m_vkd,											// device
923 		pipelineLayout,									// pipelineLayout
924 		*m_vertexModule,								// vertexShaderModule
925 		DE_NULL,										// tessellationControlModule
926 		DE_NULL,										// tessellationEvalModule
927 		DE_NULL,										// geometryShaderModule
928 		*m_fragmentModule,								// fragmentShaderModule
929 		renderPass,										// renderPass
930 		viewports,										// viewports
931 		scissors,										// scissors
932 		VK_PRIMITIVE_TOPOLOGY_POINT_LIST,				// topology
933 		0U,												// subpass
934 		0U,												// patchControlPoints
935 		&vertexInputStateCreateInfo,					// vertexInputStateCreateInfo
936 		nullptr,										// rasterizationStateCreateInfo
937 		nullptr,										// multisampleStateCreateInfo
938 		nullptr,										// depthStencilStateCreateInfo
939 		nullptr,										// colorBlendStateCreateInfo
940 		&dynamicStateCreateInfo);						// dynamicStateCreateInfo
941 }
942 
createBuffers(std::vector<VkDescriptorBufferInfo> & bufferInfos,ut::BufferHandleAllocSp & buffer,deUint32 elementCount,deUint32 elementSize,VkDeviceSize alignment,VkBufferUsageFlags bufferUsage)943 VkDeviceSize CommonDescriptorInstance::createBuffers				(std::vector<VkDescriptorBufferInfo>&		bufferInfos,
944 																	 ut::BufferHandleAllocSp&					buffer,
945 																	 deUint32									elementCount,
946 																	 deUint32									elementSize,
947 																	 VkDeviceSize								alignment,
948 																	 VkBufferUsageFlags							bufferUsage)
949 {
950 	const VkDeviceSize	roundedSize = deAlign64(elementSize, alignment);
951 	VkDeviceSize		bufferSize	= ut::createBufferAndBind(buffer, m_context, bufferUsage, (roundedSize * elementCount));
952 
953 	for (deUint32 elementIdx = 0; elementIdx < elementCount; ++elementIdx)
954 	{
955 		const VkDescriptorBufferInfo bufferInfo =
956 		{
957 			*buffer.get()->buffer,		//buffer;
958 			elementIdx * roundedSize,	//offset;
959 			elementSize,				// range;
960 
961 		};
962 		bufferInfos.push_back(bufferInfo);
963 	}
964 
965 	return bufferSize;
966 }
967 
createImages(std::vector<ut::ImageHandleAllocSp> & images,std::vector<VkDescriptorBufferInfo> & bufferInfos,ut::BufferHandleAllocSp & buffer,VkBufferUsageFlags bufferUsage,const VkExtent3D & imageExtent,VkFormat imageFormat,VkImageLayout imageLayout,deUint32 imageCount,bool withMipMaps)968 VkDeviceSize CommonDescriptorInstance::createImages					(std::vector<ut::ImageHandleAllocSp>&		images,
969 																	 std::vector<VkDescriptorBufferInfo>&		bufferInfos,
970 																	 ut::BufferHandleAllocSp&					buffer,
971 																	 VkBufferUsageFlags							bufferUsage,
972 																	 const VkExtent3D&							imageExtent,
973 																	 VkFormat									imageFormat,
974 																	 VkImageLayout								imageLayout,
975 																	 deUint32									imageCount,
976 																	 bool										withMipMaps)
977 
978 {
979 	const deUint32		imageSize	= ut::computeImageSize(imageExtent, imageFormat, withMipMaps);
980 
981 	const VkDeviceSize	bufferSize	= createBuffers(bufferInfos, buffer, imageCount, imageSize, sizeof(tcu::Vec4), bufferUsage);
982 
983 	for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
984 	{
985 		ut::ImageHandleAllocSp image;
986 		ut::createImageAndBind(image, m_context, imageFormat, imageExtent, imageLayout, withMipMaps);
987 		images.push_back(image);
988 	}
989 
990 	return bufferSize;
991 }
992 
createBuffersViews(std::vector<ut::BufferViewSp> & views,const std::vector<VkDescriptorBufferInfo> & bufferInfos,VkFormat format)993 void CommonDescriptorInstance::createBuffersViews					(std::vector<ut::BufferViewSp>&				views,
994 																	 const std::vector<VkDescriptorBufferInfo>&	bufferInfos,
995 																	 VkFormat									format)
996 {
997 	const deUint32 infoCount = static_cast<deUint32>(bufferInfos.size());
998 	for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
999 	{
1000 		const VkDescriptorBufferInfo&	bufferInfo = bufferInfos[infoIdx];
1001 		const VkBufferViewCreateInfo	bufferViewInfo =
1002 		{
1003 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// sType
1004 			DE_NULL,									// pNext
1005 			(VkBufferViewCreateFlags)0,					// flags
1006 			bufferInfo.buffer,							// buffer
1007 			format,										// format
1008 			bufferInfo.offset,							// offset
1009 			bufferInfo.range							// range;
1010 		};
1011 		views.push_back(ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(m_vki, m_vkd, &bufferViewInfo))));
1012 	}
1013 }
1014 
createImagesViews(std::vector<ut::ImageViewSp> & views,const std::vector<ut::ImageHandleAllocSp> & images,VkFormat format)1015 void CommonDescriptorInstance::createImagesViews					(std::vector<ut::ImageViewSp>&				views,
1016 																	 const std::vector<ut::ImageHandleAllocSp>&	images,
1017 																	 VkFormat									format)
1018 {
1019 	const deUint32 imageCount = static_cast<deUint32>(images.size());
1020 	for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
1021 	{
1022 		const VkImageViewCreateInfo createInfo =
1023 		{
1024 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// sType
1025 			DE_NULL,									// pNext
1026 			(VkImageViewCreateFlags)0,					// flags
1027 			*images[imageIdx]->image,					// image
1028 			VK_IMAGE_VIEW_TYPE_2D,						// viewType
1029 			format,										// format
1030 			vk::makeComponentMappingRGBA(),				// components
1031 			{
1032 				VK_IMAGE_ASPECT_COLOR_BIT,				// aspectMask
1033 				(deUint32)0,							// baseMipLevel
1034 				images[imageIdx]->levels,				// mipLevels
1035 				(deUint32)0,							// baseArrayLayer
1036 				(deUint32)1u,							// arraySize
1037 			},
1038 		};
1039 		views.push_back(ut::ImageViewSp(new Move<VkImageView>(vk::createImageView(m_vki, m_vkd, &createInfo))));
1040 	}
1041 }
1042 
copyBuffersToImages(IterateCommonVariables & variables)1043 void CommonDescriptorInstance::copyBuffersToImages					(IterateCommonVariables&					variables)
1044 {
1045 	const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1046 	DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1047 	const VkPipelineStageFlagBits dstStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1048 		? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1049 		: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
1050 	for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1051 	{
1052 		ut::recordCopyBufferToImage(
1053 			*variables.commandBuffer,						// commandBuffer
1054 			m_vki,											// interface
1055 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// srcStageMask
1056 			dstStageMask,									// dstStageMask
1057 			variables.descriptorsBufferInfos[infoIdx],		// bufferInfo
1058 			*(variables.descriptorsImages[infoIdx]->image),	// image
1059 			variables.descriptorsImages[infoIdx]->extent,	// imageExtent
1060 			variables.descriptorsImages[infoIdx]->format,	// imageFormat
1061 			VK_IMAGE_LAYOUT_UNDEFINED,						// oldImageLayout
1062 			VK_IMAGE_LAYOUT_GENERAL,						// newImageLayout
1063 			variables.descriptorsImages[infoIdx]->levels);	// mipLevelCount
1064 	}
1065 }
1066 
copyImagesToBuffers(IterateCommonVariables & variables)1067 void CommonDescriptorInstance::copyImagesToBuffers					(IterateCommonVariables&					variables)
1068 {
1069 	const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
1070 	DE_ASSERT(variables.descriptorsImages.size() == infoCount);
1071 	const VkPipelineStageFlagBits srcStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
1072 		? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
1073 		: VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1074 
1075 	for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
1076 	{
1077 		ut::recordCopyImageToBuffer(
1078 			*variables.commandBuffer,						// commandBuffer
1079 			m_vki,											// interface
1080 			srcStageMask,									// srcStageMask
1081 			VK_PIPELINE_STAGE_HOST_BIT,						// dstStageMask
1082 			*(variables.descriptorsImages[infoIdx]->image),	// image
1083 			variables.descriptorsImages[infoIdx]->extent,	// imageExtent
1084 			variables.descriptorsImages[infoIdx]->format,	// imageFormat
1085 			VK_IMAGE_LAYOUT_GENERAL,						// oldImageLayout
1086 			VK_IMAGE_LAYOUT_GENERAL,						// newImageLayout
1087 			variables.descriptorsBufferInfos[infoIdx]);		// bufferInfo
1088 	}
1089 }
1090 
getPixelAccess(deUint32 imageIndex,const VkExtent3D & imageExtent,VkFormat imageFormat,const std::vector<VkDescriptorBufferInfo> & bufferInfos,const ut::BufferHandleAllocSp & buffer,deUint32 mipLevel) const1091 PixelBufferAccess CommonDescriptorInstance::getPixelAccess			(deUint32									imageIndex,
1092 																	 const VkExtent3D&							imageExtent,
1093 																	 VkFormat									imageFormat,
1094 																	 const std::vector<VkDescriptorBufferInfo>&	bufferInfos,
1095 																	 const ut::BufferHandleAllocSp&				buffer,
1096 																	 deUint32									mipLevel) const
1097 {
1098 	DE_ASSERT(bufferInfos[imageIndex].buffer == *buffer.get()->buffer);
1099 	DE_ASSERT(ut::computeImageSize(imageExtent, imageFormat, true, (mipLevel ? ut::maxDeUint32 : 0)) <= bufferInfos[imageIndex].range);
1100 	DE_ASSERT(imageExtent.width		>> mipLevel);
1101 	DE_ASSERT(imageExtent.height	>> mipLevel);
1102 
1103 	deUint32 mipOffset = 0;
1104 
1105 	for (deUint32 level = 0; mipLevel && level < mipLevel; ++level)
1106 	{
1107 		mipOffset += ut::computeImageSize(imageExtent, imageFormat, true, level);
1108 	}
1109 
1110 	unsigned char* hostPtr	= static_cast<unsigned char*>(buffer->alloc->getHostPtr());
1111 	unsigned char* data = hostPtr + bufferInfos[imageIndex].offset + mipOffset;
1112 	return tcu::PixelBufferAccess(vk::mapVkFormat(imageFormat), (imageExtent.width >> mipLevel), (imageExtent.height >> mipLevel), imageExtent.depth, data);
1113 }
1114 
updateDescriptors(IterateCommonVariables & variables)1115 void CommonDescriptorInstance::updateDescriptors					(IterateCommonVariables&					variables)
1116 {
1117 	const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
1118 	const deUint32				primeCount = static_cast<deUint32>(primes.size());
1119 
1120 	for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
1121 	{
1122 		const VkDescriptorBufferInfo*	pBufferInfo			= DE_NULL;
1123 		const VkDescriptorImageInfo*	pImageInfo			= DE_NULL;
1124 		const VkBufferView*				pTexelBufferView	= DE_NULL;
1125 
1126 		VkDescriptorImageInfo		imageInfo =
1127 		{
1128 			static_cast<VkSampler>(0),
1129 			static_cast<VkImageView>(0),
1130 			VK_IMAGE_LAYOUT_GENERAL
1131 		};
1132 
1133 		switch (m_testParams.descriptorType)
1134 		{
1135 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1136 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1137 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1138 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1139 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1140 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1141 			{
1142 				pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
1143 				switch (m_testParams.descriptorType)
1144 				{
1145 				case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1146 				case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1147 					pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
1148 					break;
1149 				default:
1150 					break;
1151 				}
1152 			}
1153 			break;
1154 
1155 		case VK_DESCRIPTOR_TYPE_SAMPLER:
1156 			imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
1157 			pImageInfo = &imageInfo;
1158 			break;
1159 
1160 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1161 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1162 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1163 			imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
1164 			pImageInfo = &imageInfo;
1165 			break;
1166 
1167 		default:	break;
1168 		}
1169 
1170 		const VkWriteDescriptorSet writeInfo =
1171 		{
1172 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
1173 			DE_NULL,										// pNext
1174 			*variables.descriptorSet,						// descriptorSet
1175 			m_testParams.descriptorBinding,					// descriptorBinding;
1176 			primes[primeIdx],								// elementIndex
1177 			1u,												// descriptorCount
1178 			m_testParams.descriptorType,					// descriptorType
1179 			pImageInfo,										// pImageInfo
1180 			pBufferInfo,									// pBufferInfo
1181 			pTexelBufferView								// pTexelBufferView
1182 		};
1183 
1184 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
1185 	}
1186 }
1187 
iterateCommandSetup(IterateCommonVariables & variables)1188 void CommonDescriptorInstance::iterateCommandSetup					(IterateCommonVariables&					variables)
1189 {
1190 	variables.dataAlignment				= 0;
1191 
1192 	variables.renderArea.offset.x		= 0;
1193 	variables.renderArea.offset.y		= 0;
1194 	variables.renderArea.extent.width	= m_testParams.frameResolution.width;
1195 	variables.renderArea.extent.height	= m_testParams.frameResolution.height;
1196 
1197 	variables.vertexCount				= m_testParams.frameResolution.width * m_testParams.frameResolution.height;
1198 
1199 	variables.lowerBound				= 0;
1200 	variables.upperBound				= variables.vertexCount;
1201 
1202 	variables.descriptorSetLayout		= createDescriptorSetLayout(m_testParams.calculateInLoop, variables.availableDescriptorCount);
1203 	variables.validDescriptorCount		= ut::computePrimeCount(variables.availableDescriptorCount);
1204 	variables.descriptorPool			= createDescriptorPool(variables.availableDescriptorCount);
1205 	variables.descriptorSet				= createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
1206 
1207 	std::vector<VkDescriptorSetLayout>	descriptorSetLayouts;
1208 	descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
1209 	if (m_testParams.calculateInLoop)
1210 	{
1211 		variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
1212 		descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
1213 	}
1214 
1215 	variables.pipelineLayout			= createPipelineLayout(descriptorSetLayouts);
1216 
1217 	createAndPopulateDescriptors		(variables);
1218 
1219 	variables.renderPass				= createRenderPass(variables);
1220 	variables.pipeline					= createPipeline(*variables.pipelineLayout, *variables.renderPass);
1221 
1222 	variables.commandBuffer				= createCmdBuffer();
1223 
1224 	if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1225 	{
1226 		createVertexAttributeBuffer		(variables.vertexAttributesBuffer, variables.availableDescriptorCount);
1227 		createFramebuffer				(variables.frameBuffer, *variables.renderPass, variables);
1228 	}
1229 
1230 	if (m_testParams.calculateInLoop)
1231 	{
1232 		variables.descriptorEnumerator.update(m_context);
1233 	}
1234 
1235 	if (!m_testParams.updateAfterBind)
1236 	{
1237 		updateDescriptors				(variables);
1238 	}
1239 
1240 }
1241 
iterateCommandBegin(IterateCommonVariables & variables,bool firstPass)1242 void CommonDescriptorInstance::iterateCommandBegin					(IterateCommonVariables&					variables,	bool firstPass)
1243 {
1244 	vk::beginCommandBuffer				(m_vki, *variables.commandBuffer);
1245 
1246 	// Clear color attachment, and transition it to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1247 	if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1248 	{
1249 		if (firstPass)
1250 		{
1251 			const VkImageMemoryBarrier preImageBarrier =
1252 			{
1253 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType		sType
1254 				DE_NULL,											// const void*			pNext
1255 				0u,													// VkAccessFlags		srcAccessMask
1256 				VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags		dstAccessMask
1257 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout		oldLayout
1258 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout		newLayout
1259 				VK_QUEUE_FAMILY_IGNORED,							// uint32_t				srcQueueFamilyIndex
1260 				VK_QUEUE_FAMILY_IGNORED,							// uint32_t				dstQueueFamilyIndex
1261 				*variables.frameBuffer->image->image,				// VkImage				image
1262 				{
1263 					VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask
1264 					0u,										// uint32_t				baseMipLevel
1265 					VK_REMAINING_MIP_LEVELS,				// uint32_t				mipLevels,
1266 					0u,										// uint32_t				baseArray
1267 					VK_REMAINING_ARRAY_LAYERS,				// uint32_t				arraySize
1268 				}
1269 			};
1270 
1271 			m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1272 									(VkDependencyFlags)0,
1273 									0, (const VkMemoryBarrier*)DE_NULL,
1274 									0, (const VkBufferMemoryBarrier*)DE_NULL,
1275 									1, &preImageBarrier);
1276 
1277 			const VkClearColorValue	clearColorValue		= makeClearValueColor(m_clearColor).color;
1278 
1279 			m_vki.cmdClearColorImage(*variables.commandBuffer, *variables.frameBuffer->image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &preImageBarrier.subresourceRange);
1280 
1281 			const VkImageMemoryBarrier postImageBarrier =
1282 			{
1283 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType		sType
1284 				DE_NULL,											// const void*			pNext
1285 				VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags		srcAccessMask
1286 				VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags		dstAccessMask
1287 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout		oldLayout
1288 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout		newLayout
1289 				VK_QUEUE_FAMILY_IGNORED,							// uint32_t				srcQueueFamilyIndex
1290 				VK_QUEUE_FAMILY_IGNORED,							// uint32_t				dstQueueFamilyIndex
1291 				*variables.frameBuffer->image->image,				// VkImage				image
1292 				{
1293 					VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask
1294 					0u,										// uint32_t				baseMipLevel
1295 					VK_REMAINING_MIP_LEVELS,				// uint32_t				mipLevels,
1296 					0u,										// uint32_t				baseArray
1297 					VK_REMAINING_ARRAY_LAYERS,				// uint32_t				arraySize
1298 				}
1299 			};
1300 
1301 			m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1302 									(VkDependencyFlags)0,
1303 									0, (const VkMemoryBarrier*)DE_NULL,
1304 									0, (const VkBufferMemoryBarrier*)DE_NULL,
1305 									1, &postImageBarrier);
1306 
1307 		}
1308 	}
1309 
1310 	if (m_testParams.calculateInLoop)
1311 	{
1312 		deRandom rnd;
1313 		deRandom_init(&rnd, static_cast<deUint32>(m_testParams.descriptorType));
1314 		const deUint32 quarter = variables.vertexCount / 4;
1315 
1316 		variables.lowerBound			= deRandom_getUint32(&rnd) % quarter;
1317 		variables.upperBound			= (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
1318 
1319 		const push_constant pc =
1320 		{
1321 			static_cast<deInt32>(variables.lowerBound),
1322 			static_cast<deInt32>(variables.upperBound)
1323 		};
1324 
1325 		m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u, static_cast<deUint32>(sizeof(pc)), &pc);
1326 	}
1327 
1328 	if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
1329 	{
1330 		commandBindVertexAttributes		(*variables.commandBuffer, variables.vertexAttributesBuffer);
1331 	}
1332 
1333 	if (m_testParams.calculateInLoop)
1334 	{
1335 		commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorEnumerator.descriptorSet, 1);
1336 	}
1337 
1338 	if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
1339 	{
1340 		commandBindDescriptorSets		(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
1341 	}
1342 
1343 	commandBindPipeline					(*variables.commandBuffer, *variables.pipeline);
1344 }
1345 
iterate(void)1346 tcu::TestStatus	CommonDescriptorInstance::iterate					(void)
1347 {
1348 	IterateCommonVariables	v;
1349 	ut::UpdatablePixelBufferAccessPtr	programResult;
1350 	ut::UpdatablePixelBufferAccessPtr	referenceResult;
1351 
1352 	bool firstPass = true;
1353 
1354 	iterateCommandSetup		(v);
1355 
1356 	v.renderArea.extent.width	= m_testParams.frameResolution.width/4;
1357 	v.renderArea.extent.height	= m_testParams.frameResolution.height/4;
1358 
1359 	for (int x = 0; x < 4; x++)
1360 		for (int y= 0; y < 4; y++)
1361 		{
1362 			iterateCommandBegin		(v, firstPass);
1363 
1364 			if (true == firstPass && true == m_testParams.copyBuffersToImages)
1365 			{
1366 				copyBuffersToImages	(v);
1367 			}
1368 
1369 			firstPass = false;
1370 
1371 			if (true == m_testParams.updateAfterBind)
1372 			{
1373 				updateDescriptors	(v);
1374 			}
1375 
1376 			v.renderArea.offset.x		= x * m_testParams.frameResolution.width/4;
1377 			v.renderArea.offset.y		= y * m_testParams.frameResolution.height/4;
1378 
1379 			vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
1380 			m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
1381 
1382 			vk::beginRenderPass		(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
1383 			m_vki.cmdDraw			(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
1384 			vk::endRenderPass		(m_vki, *v.commandBuffer);
1385 
1386 			iterateCommandEnd(v, programResult, referenceResult);
1387 			programResult->invalidate();
1388 		}
1389 
1390 	return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
1391 }
1392 
createColorScheme(void)1393 std::vector<float> CommonDescriptorInstance::createColorScheme		(void)
1394 {
1395 	std::vector<float> cs;
1396 	int divider = 2;
1397 	for (int i = 0; i < 10; ++i)
1398 	{
1399 		cs.push_back(1.0f / float(divider));
1400 		divider *= 2;
1401 	}
1402 	return cs;
1403 }
1404 
iterateCommandEnd(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr & programResult,ut::UpdatablePixelBufferAccessPtr & referenceResult,bool collectBeforeSubmit)1405 void CommonDescriptorInstance::iterateCommandEnd					(IterateCommonVariables&					variables,
1406 																	 ut::UpdatablePixelBufferAccessPtr&	programResult,
1407 																	 ut::UpdatablePixelBufferAccessPtr&	referenceResult,
1408 																	 bool										collectBeforeSubmit)
1409 {
1410 	if (collectBeforeSubmit)
1411 	{
1412 		iterateCollectResults(programResult, variables, true);
1413 		iterateCollectResults(referenceResult, variables, false);
1414 	}
1415 
1416 	VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
1417 	Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
1418 	m_vki.waitForFences(m_vkd, 1, &(*fence), DE_TRUE, ~0ull);
1419 
1420 	if (false == collectBeforeSubmit)
1421 	{
1422 		iterateCollectResults(programResult, variables, true);
1423 		iterateCollectResults(referenceResult, variables, false);
1424 	}
1425 }
1426 
iterateVerifyResults(IterateCommonVariables & variables,ut::UpdatablePixelBufferAccessPtr programResult,ut::UpdatablePixelBufferAccessPtr referenceResult)1427 bool CommonDescriptorInstance::iterateVerifyResults			(IterateCommonVariables&					variables,
1428 																	 ut::UpdatablePixelBufferAccessPtr	programResult,
1429 																	 ut::UpdatablePixelBufferAccessPtr	referenceResult)
1430 {
1431 	bool result = false;
1432 	if (m_testParams.fuzzyComparison)
1433 	{
1434 		result = tcu::fuzzyCompare(m_context.getTestContext().getLog(),
1435 			"Fuzzy Compare", "Comparison result", *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
1436 	}
1437 	else
1438 	{
1439 		result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1440 			"Float Threshold Compare", "Comparison result", *referenceResult.get(), *programResult.get(), tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
1441 	}
1442 
1443 	if (m_testParams.allowVertexStoring)
1444 	{
1445 		result = verifyVertexWriteResults(variables);
1446 	}
1447 
1448 	return result;
1449 }
1450 
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)1451 void CommonDescriptorInstance::iterateCollectResults				(ut::UpdatablePixelBufferAccessPtr&			result,
1452 																	 const IterateCommonVariables&				variables,
1453 																	 bool										fromTest)
1454 {
1455 	if (fromTest)
1456 	{
1457 		result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
1458 	}
1459 	else
1460 	{
1461 		result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
1462 
1463 		for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
1464 		{
1465 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
1466 			{
1467 				const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
1468 				result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
1469 			}
1470 		}
1471 	}
1472 }
1473 
createCmdBuffer(void)1474 Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer		(void)
1475 {
1476 	return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1477 }
1478 
commandSubmit(VkCommandBuffer cmd)1479 Move<VkFence> CommonDescriptorInstance::commandSubmit				(VkCommandBuffer							cmd)
1480 {
1481 	Move<VkFence>	fence(vk::createFence(m_vki, m_vkd));
1482 
1483 	const VkSubmitInfo	submitInfo =
1484 	{
1485 		VK_STRUCTURE_TYPE_SUBMIT_INFO,						// sType
1486 		DE_NULL,											// pNext
1487 		0u,													// waitSemaphoreCount
1488 		static_cast<VkSemaphore*>(DE_NULL),					// pWaitSemaphores
1489 		static_cast<const VkPipelineStageFlags*>(DE_NULL),	// pWaitDstStageMask
1490 		1u,													// commandBufferCount
1491 		&cmd,												// pCommandBuffers
1492 		0u,													// signalSemaphoreCount
1493 		static_cast<VkSemaphore*>(DE_NULL)					// pSignalSemaphores
1494 	};
1495 
1496 	VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
1497 
1498 	return fence;
1499 }
1500 
verifyVertexWriteResults(IterateCommonVariables & variables)1501 bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables&					variables)
1502 {
1503 	DE_UNREF(variables);
1504 	return true;
1505 }
1506 
commandBindPipeline(VkCommandBuffer commandBuffer,VkPipeline pipeline)1507 void CommonDescriptorInstance::commandBindPipeline					(VkCommandBuffer							commandBuffer,
1508 																	 VkPipeline									pipeline)
1509 {
1510 	const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1511 	m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
1512 }
1513 
commandBindVertexAttributes(VkCommandBuffer commandBuffer,const ut::BufferHandleAllocSp & vertexAttributesBuffer)1514 void CommonDescriptorInstance::commandBindVertexAttributes			(VkCommandBuffer							commandBuffer,
1515 																	 const ut::BufferHandleAllocSp&				vertexAttributesBuffer)
1516 {
1517 	const VkDeviceSize	offsets[] = { 0u };
1518 	const VkBuffer		buffers[] = { *vertexAttributesBuffer->buffer };
1519 	m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
1520 }
1521 
commandBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineLayout pipelineLayout,VkDescriptorSet descriptorSet,deUint32 descriptorSetIndex)1522 void CommonDescriptorInstance::commandBindDescriptorSets			(VkCommandBuffer							commandBuffer,
1523 																	 VkPipelineLayout							pipelineLayout,
1524 																	 VkDescriptorSet							descriptorSet,
1525 																	 deUint32									descriptorSetIndex)
1526 {
1527 	const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1528 	m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u, &descriptorSet, 0u, static_cast<deUint32*>(DE_NULL));
1529 }
1530 
1531 ut::UpdatablePixelBufferAccessPtr
commandReadFrameBuffer(VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1532 CommonDescriptorInstance::commandReadFrameBuffer					(VkCommandBuffer							commandBuffer,
1533 																	 const ut::FrameBufferSp&					frameBuffer)
1534 {
1535 	ut::BufferHandleAllocSp frameBufferContent;
1536 	commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
1537 	return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
1538 		m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
1539 		de::SharedPtr< Move<VkBuffer> >(new Move<VkBuffer>(frameBufferContent->buffer)),
1540 		de::SharedPtr< de::MovePtr<Allocation> >(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
1541 }
1542 
commandReadFrameBuffer(ut::BufferHandleAllocSp & content,VkCommandBuffer commandBuffer,const ut::FrameBufferSp & frameBuffer)1543 void CommonDescriptorInstance::commandReadFrameBuffer				(ut::BufferHandleAllocSp&					content,
1544 																	 VkCommandBuffer							commandBuffer,
1545 																	 const ut::FrameBufferSp&					frameBuffer)
1546 {
1547 	Move<VkBuffer>			buffer;
1548 	de::MovePtr<Allocation>	allocation;
1549 
1550 	const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
1551 
1552 	// create a buffer and an host allocation for it
1553 	{
1554 		const VkBufferCreateInfo bufferCreateInfo =
1555 		{
1556 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
1557 			DE_NULL,									// pNext
1558 			0u,											// flags
1559 			bufferSize,									// size
1560 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
1561 			VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
1562 			1u,											// queueFamilyIndexCoun
1563 			&m_queueFamilyIndex							// pQueueFamilyIndices
1564 		};
1565 
1566 		buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
1567 		const VkMemoryRequirements	memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
1568 		allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
1569 
1570 		VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
1571 	}
1572 
1573 	const VkImage& image = *frameBuffer->image->image;
1574 
1575 	VkImageSubresourceRange		subresourceRange =
1576 	{
1577 		VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
1578 		0u,											// baseMipLevel
1579 		1u,											// levelCount
1580 		0u,											// baseArrayLayer
1581 		1u											// layerCount
1582 	};
1583 
1584 	const VkImageMemoryBarrier	barrierBefore =
1585 	{
1586 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType;
1587 		DE_NULL,									// pNext;
1588 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// srcAccessMask;
1589 		VK_ACCESS_TRANSFER_READ_BIT,				// dstAccessMask;
1590 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// oldLayout
1591 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// newLayout;
1592 		VK_QUEUE_FAMILY_IGNORED,					// srcQueueFamilyIndex;
1593 		VK_QUEUE_FAMILY_IGNORED,					// dstQueueFamilyIndex;
1594 		image,										// image;
1595 		subresourceRange							// subresourceRange;
1596 	};
1597 
1598 	const VkBufferImageCopy		copyRegion =
1599 	{
1600 		0u,											// bufferOffset
1601 		frameBuffer->image->extent.width,				// bufferRowLength
1602 		frameBuffer->image->extent.height,			// bufferImageHeight
1603 		{											// VkImageSubresourceLayers
1604 			VK_IMAGE_ASPECT_COLOR_BIT,				// aspect
1605 			0u,										// mipLevel
1606 			0u,										// baseArrayLayer
1607 			1u,										// layerCount
1608 		},
1609 		{ 0, 0, 0 },								// imageOffset
1610 		frameBuffer->image->extent					// imageExtent
1611 	};
1612 
1613 	const VkBufferMemoryBarrier	bufferBarrier =
1614 	{
1615 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// sType;
1616 		DE_NULL,									// pNext;
1617 		VK_ACCESS_TRANSFER_WRITE_BIT,				// srcAccessMask;
1618 		VK_ACCESS_HOST_READ_BIT,					// dstAccessMask;
1619 		VK_QUEUE_FAMILY_IGNORED,					// srcQueueFamilyIndex;
1620 		VK_QUEUE_FAMILY_IGNORED,					// dstQueueFamilyIndex;
1621 		*buffer,									// buffer;
1622 		0u,											// offset;
1623 		bufferSize									// size;
1624 	};
1625 
1626 	const VkImageMemoryBarrier	barrierAfter =
1627 	{
1628 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
1629 		DE_NULL,										// pNext;
1630 		VK_ACCESS_TRANSFER_READ_BIT,					// srcAccessMask;
1631 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// dstAccessMask;
1632 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// oldLayout;
1633 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// newLayout;
1634 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
1635 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
1636 		image,											// image
1637 		subresourceRange								// subresourceRange
1638 	};
1639 
1640 
1641 	m_vki.cmdPipelineBarrier(commandBuffer,												// commandBuffer
1642 		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,	// srcStageMask, dstStageMask
1643 		(VkDependencyFlags)0,															// dependencyFlags
1644 		0u, DE_NULL,																	// memoryBarrierCount, pMemoryBarriers
1645 		0u, DE_NULL,																	// bufferBarrierCount, pBufferBarriers
1646 		1u, &barrierBefore);																// imageBarrierCount, pImageBarriers
1647 
1648 	m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1649 
1650 	m_vki.cmdPipelineBarrier(commandBuffer,
1651 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1652 		(VkDependencyFlags)0,
1653 		0u, DE_NULL,
1654 		1u, &bufferBarrier,
1655 		1u, &barrierAfter);
1656 
1657 	content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
1658 }
1659 
getColorAccess(VkDescriptorType descriptorType,const char * indexVariableName,bool usesMipMaps)1660 std::string CommonDescriptorInstance::getColorAccess				(VkDescriptorType							descriptorType,
1661 																	 const char*								indexVariableName,
1662 																	 bool										usesMipMaps)
1663 {
1664 	std::string text;
1665 	std::map<std::string, std::string> vars;
1666 	vars["INDEX"] = indexVariableName;
1667 
1668 	switch (descriptorType)
1669 	{
1670 	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1671 	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1672 		text = "data[nonuniformEXT(${INDEX})].c";
1673 		break;
1674 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1675 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1676 		text = "data[nonuniformEXT(${INDEX})].cold";
1677 		break;
1678 	case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1679 		text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
1680 		break;
1681 	case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1682 		text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
1683 		break;
1684 	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1685 		text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
1686 		break;
1687 	case VK_DESCRIPTOR_TYPE_SAMPLER:
1688 		text = usesMipMaps
1689 			? "textureLod(nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos, 1)"
1690 			: "texture(   nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos   )";
1691 		break;
1692 	case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1693 		text = usesMipMaps
1694 			? "textureLod( nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0), textureQueryLevels(nonuniformEXT(sampler2D(data[${INDEX}], samp[0])))-1)"
1695 			: "texture(    nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0)   )";
1696 		break;
1697 	case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1698 		text = usesMipMaps
1699 			? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)"
1700 			: "texture(    data[nonuniformEXT(${INDEX})], uvec2(0,0)   )";
1701 		break;
1702 	default:
1703 		TCU_THROW(InternalError, "Not implemented descriptor type");
1704 	}
1705 
1706 	return tcu::StringTemplate(text).specialize(vars);
1707 }
1708 
getFragmentReturnSource(const std::string & colorAccess)1709 std::string CommonDescriptorInstance::getFragmentReturnSource		(const std::string&							colorAccess)
1710 {
1711 	return "  FragColor = " + colorAccess + ";\n";
1712 }
1713 
getFragmentLoopSource(const std::string & colorAccess1,const std::string & colorAccess2)1714 std::string CommonDescriptorInstance::getFragmentLoopSource			(const std::string&							colorAccess1,
1715 																	 const std::string&							colorAccess2)
1716 {
1717 	std::map < std::string, std::string > vars;
1718 	vars["COLOR_ACCESS_1"] = colorAccess1;
1719 	vars["COLOR_ACCESS_2"] = colorAccess2;
1720 
1721 	const char* s =
1722 		"  vec4 sumClr1 = vec4(0,0,0,0);		\n"
1723 		"  vec4 sumClr2 = vec4(0,0,0,0);		\n"
1724 		"  for (int i = pc.lowerBound; i < pc.upperBound; ++i)	\n"
1725 		"  {\n"
1726 		"    int loopIdx = texelFetch(iter, i).x;				\n"
1727 		"    sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1};	\n"
1728 		"    sumClr2 += ${COLOR_ACCESS_2};						\n"
1729 		"  }\n"
1730 		"  FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1);	\n";
1731 
1732 	return tcu::StringTemplate(s).specialize(vars);
1733 }
1734 
performWritesInVertex(VkDescriptorType descriptorType)1735 bool CommonDescriptorInstance::performWritesInVertex				(VkDescriptorType							descriptorType)
1736 {
1737 	bool result = false;
1738 
1739 	switch (descriptorType)
1740 	{
1741 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1742 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1743 	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1744 		result = true;
1745 		break;
1746 	default:
1747 		result = false;
1748 		break;
1749 	}
1750 
1751 	return result;
1752 }
1753 
performWritesInVertex(VkDescriptorType descriptorType,const Context & context)1754 bool CommonDescriptorInstance::performWritesInVertex				(VkDescriptorType							descriptorType,
1755 																	const Context&								context)
1756 {
1757 	bool result = false;
1758 
1759 	ut::DeviceProperties			dp		(context);
1760 	const VkPhysicalDeviceFeatures&	feats	= dp.physicalDeviceFeatures();
1761 
1762 	if (feats.vertexPipelineStoresAndAtomics != DE_FALSE)
1763 	{
1764 		result = CommonDescriptorInstance::performWritesInVertex(descriptorType);
1765 	}
1766 
1767 	return result;
1768 }
1769 
getShaderAsm(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)1770 std::string CommonDescriptorInstance::getShaderAsm					(VkShaderStageFlagBits						shaderType,
1771 																	 const TestCaseParams&						testCaseParams,
1772 																	 bool										allowVertexStoring)
1773 {
1774 	std::stringstream	s;
1775 	switch (shaderType)
1776 	{
1777 		case VK_SHADER_STAGE_VERTEX_BIT:
1778 			switch (testCaseParams.descriptorType)
1779 			{
1780 				case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1781 				case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1782 				case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1783 					s << "               OpCapability Shader\n";
1784 					s << "               OpCapability SampledBuffer\n";
1785 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1786 					s << "               OpMemoryModel Logical GLSL450\n";
1787 					s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex\n";
1788 					s << "               OpSource GLSL 450\n";
1789 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1790 					s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
1791 					s << "               OpName %main \"main\"\n";
1792 					s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1793 					s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1794 					s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1795 					s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1796 					s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1797 					s << "               OpName %_ \"\"\n";
1798 					s << "               OpName %position \"position\"\n";
1799 					s << "               OpName %in_position \"in_position\"\n";
1800 					s << "               OpName %normalpos \"normalpos\"\n";
1801 					s << "               OpName %in_normalpos \"in_normalpos\"\n";
1802 					s << "               OpName %vIndex \"vIndex\"\n";
1803 					s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1804 					s << "               OpName %rIndex \"rIndex\"\n";
1805 					s << "               OpName %index \"index\"\n";
1806 					s << "               OpName %gIndex \"gIndex\"\n";
1807 					s << "               OpName %bIndex \"bIndex\"\n";
1808 					s << "               OpName %aIndex \"aIndex\"\n";
1809 					s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1810 					s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1811 					s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1812 					s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1813 					s << "               OpDecorate %gl_PerVertex Block\n";
1814 					s << "               OpDecorate %position Location 0\n";
1815 					s << "               OpDecorate %in_position Location 0\n";
1816 					s << "               OpDecorate %normalpos Location 1\n";
1817 					s << "               OpDecorate %in_normalpos Location 1\n";
1818 					s << "               OpDecorate %vIndex Location 2\n";
1819 					s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1820 					s << "               OpDecorate %rIndex Location 3\n";
1821 					s << "               OpDecorate %index Location 2\n";
1822 					s << "               OpDecorate %gIndex Location 4\n";
1823 					s << "               OpDecorate %bIndex Location 5\n";
1824 					s << "               OpDecorate %aIndex Location 6\n";
1825 					s << "       %void = OpTypeVoid\n";
1826 					s << "          %3 = OpTypeFunction %void\n";
1827 					s << "      %float = OpTypeFloat 32\n";
1828 					s << "    %v4float = OpTypeVector %float 4\n";
1829 					s << "       %uint = OpTypeInt 32 0\n";
1830 					s << "     %uint_1 = OpConstant %uint 1\n";
1831 					s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1832 					s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1833 					s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1834 					s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1835 					s << "        %int = OpTypeInt 32 1\n";
1836 					s << "      %int_1 = OpConstant %int 1\n";
1837 					s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1838 					s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1839 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1840 					s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1841 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1842 					s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1843 					s << "    %v2float = OpTypeVector %float 2\n";
1844 					s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1845 					s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1846 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1847 					s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1848 					s << "      %int_0 = OpConstant %int 0\n";
1849 					s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1850 					s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1851 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1852 					s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1853 					s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1854 					s << "      %v4int = OpTypeVector %int 4\n";
1855 					s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1856 					s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1857 					s << "     %uint_0 = OpConstant %uint 0\n";
1858 					s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1859 					s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1860 					s << "     %uint_2 = OpConstant %uint 2\n";
1861 					s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1862 					s << "     %uint_3 = OpConstant %uint 3\n";
1863 					s << "       %main = OpFunction %void None %3\n";
1864 					s << "          %5 = OpLabel\n";
1865 					s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
1866 					s << "               OpStore %18 %float_0_200000003\n";
1867 					s << "         %23 = OpLoad %v4float %in_position\n";
1868 					s << "               OpStore %position %23\n";
1869 					s << "         %29 = OpLoad %v2float %in_normalpos\n";
1870 					s << "               OpStore %normalpos %29\n";
1871 					s << "         %31 = OpLoad %v4float %position\n";
1872 					s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
1873 					s << "               OpStore %32 %31\n";
1874 					s << "         %37 = OpLoad %int %gl_VertexIndex\n";
1875 					s << "               OpStore %vIndex %37\n";
1876 					s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
1877 					s << "         %44 = OpLoad %int %43\n";
1878 					s << "               OpStore %rIndex %44\n";
1879 					s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
1880 					s << "         %47 = OpLoad %int %46\n";
1881 					s << "               OpStore %gIndex %47\n";
1882 					s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
1883 					s << "         %51 = OpLoad %int %50\n";
1884 					s << "               OpStore %bIndex %51\n";
1885 					s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
1886 					s << "         %55 = OpLoad %int %54\n";
1887 					s << "               OpStore %aIndex %55\n";
1888 					s << "               OpReturn\n";
1889 					s << "               OpFunctionEnd\n";
1890 					break;
1891 				case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1892 					s << "               OpCapability Shader\n";
1893 					s << "               OpCapability ImageBuffer\n";
1894 					if (allowVertexStoring)
1895 					{
1896 						s << "               OpCapability ShaderNonUniform\n";
1897 						s << "               OpCapability RuntimeDescriptorArray\n";
1898 						s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
1899 						s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
1900 					}
1901 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
1902 					s << "               OpMemoryModel Logical GLSL450\n";
1903 					s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
1904 					s << "               OpSource GLSL 450\n";
1905 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
1906 					s << "               OpName %main \"main\"\n";
1907 					s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
1908 					s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
1909 					s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
1910 					s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
1911 					s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
1912 					s << "               OpName %_ \"\"\n";
1913 					s << "               OpName %position \"position\"\n";
1914 					s << "               OpName %in_position \"in_position\"\n";
1915 					s << "               OpName %normalpos \"normalpos\"\n";
1916 					s << "               OpName %in_normalpos \"in_normalpos\"\n";
1917 					s << "               OpName %vIndex \"vIndex\"\n";
1918 					s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
1919 					s << "               OpName %rIndex \"rIndex\"\n";
1920 					s << "               OpName %index \"index\"\n";
1921 					s << "               OpName %gIndex \"gIndex\"\n";
1922 					s << "               OpName %bIndex \"bIndex\"\n";
1923 					s << "               OpName %aIndex \"aIndex\"\n";
1924 					s << "               OpName %data \"data\"\n";
1925 					s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
1926 					s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
1927 					s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
1928 					s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
1929 					s << "               OpDecorate %gl_PerVertex Block\n";
1930 					s << "               OpDecorate %position Location 0\n";
1931 					s << "               OpDecorate %in_position Location 0\n";
1932 					s << "               OpDecorate %normalpos Location 1\n";
1933 					s << "               OpDecorate %in_normalpos Location 1\n";
1934 					s << "               OpDecorate %vIndex Location 2\n";
1935 					s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
1936 					s << "               OpDecorate %rIndex Location 3\n";
1937 					s << "               OpDecorate %index Location 2\n";
1938 					s << "               OpDecorate %gIndex Location 4\n";
1939 					s << "               OpDecorate %bIndex Location 5\n";
1940 					s << "               OpDecorate %aIndex Location 6\n";
1941 					s << "               OpDecorate %data DescriptorSet 0\n";
1942 					s << "               OpDecorate %data Binding 4\n";
1943 					if (allowVertexStoring)
1944 					{
1945 						// s << "               OpDecorate %66 NonUniform\n";
1946 						// s << "               OpDecorate %68 NonUniform\n";
1947 						s << "               OpDecorate %69 NonUniform\n";
1948 						// s << "               OpDecorate %71 NonUniform\n";
1949 						// s << "               OpDecorate %72 NonUniform\n";
1950 						s << "               OpDecorate %73 NonUniform\n";
1951 					}
1952 					s << "       %void = OpTypeVoid\n";
1953 					s << "          %3 = OpTypeFunction %void\n";
1954 					s << "      %float = OpTypeFloat 32\n";
1955 					s << "    %v4float = OpTypeVector %float 4\n";
1956 					s << "       %uint = OpTypeInt 32 0\n";
1957 					s << "     %uint_1 = OpConstant %uint 1\n";
1958 					s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
1959 					s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
1960 					s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
1961 					s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
1962 					s << "        %int = OpTypeInt 32 1\n";
1963 					s << "      %int_1 = OpConstant %int 1\n";
1964 					s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
1965 					s << "%_ptr_Output_float = OpTypePointer Output %float\n";
1966 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
1967 					s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
1968 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
1969 					s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
1970 					s << "    %v2float = OpTypeVector %float 2\n";
1971 					s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
1972 					s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
1973 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
1974 					s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
1975 					s << "      %int_0 = OpConstant %int 0\n";
1976 					s << "%_ptr_Output_int = OpTypePointer Output %int\n";
1977 					s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
1978 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
1979 					s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
1980 					s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
1981 					s << "      %v4int = OpTypeVector %int 4\n";
1982 					s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
1983 					s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
1984 					s << "     %uint_0 = OpConstant %uint 0\n";
1985 					s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
1986 					s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
1987 					s << "     %uint_2 = OpConstant %uint 2\n";
1988 					s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
1989 					s << "     %uint_3 = OpConstant %uint 3\n";
1990 					if (allowVertexStoring)
1991 					{
1992 						s << "        %bool = OpTypeBool\n";
1993 						s << "          %61 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
1994 						s << " %_runtimearr_61 = OpTypeRuntimeArray %61\n";
1995 						s << " %_ptr_UniformConstant__runtimearr_61 = OpTypePointer UniformConstant %_runtimearr_61\n";
1996 						s << "        %data = OpVariable %_ptr_UniformConstant__runtimearr_61 UniformConstant\n";
1997 						s << " %_ptr_UniformConstant_61 = OpTypePointer UniformConstant %61\n";
1998 					}
1999 					else
2000 					{
2001 						s << "         %56 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2002 						s << "%_arr_56_uint_1 = OpTypeArray %56 %uint_1\n";
2003 						s << "%_ptr_UniformConstant__arr_56_uint_1 = OpTypePointer UniformConstant %_arr_56_uint_1\n";
2004 						s << "       %data = OpVariable %_ptr_UniformConstant__arr_56_uint_1 UniformConstant\n";
2005 					}
2006 					s << "       %main = OpFunction %void None %3\n";
2007 					s << "          %5 = OpLabel\n";
2008 					s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2009 					s << "               OpStore %18 %float_0_200000003\n";
2010 					s << "         %23 = OpLoad %v4float %in_position\n";
2011 					s << "               OpStore %position %23\n";
2012 					s << "         %29 = OpLoad %v2float %in_normalpos\n";
2013 					s << "               OpStore %normalpos %29\n";
2014 					s << "         %31 = OpLoad %v4float %position\n";
2015 					s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2016 					s << "               OpStore %32 %31\n";
2017 					s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2018 					s << "               OpStore %vIndex %37\n";
2019 					s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2020 					s << "         %44 = OpLoad %int %43\n";
2021 					s << "               OpStore %rIndex %44\n";
2022 					s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2023 					s << "         %47 = OpLoad %int %46\n";
2024 					s << "               OpStore %gIndex %47\n";
2025 					s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2026 					s << "         %51 = OpLoad %int %50\n";
2027 					s << "               OpStore %bIndex %51\n";
2028 					s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2029 					s << "         %55 = OpLoad %int %54\n";
2030 					s << "               OpStore %aIndex %55\n";
2031 					if (allowVertexStoring)
2032 					{
2033 						s << "          %56 = OpLoad %int %gIndex\n";
2034 						s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2035 						s << "                OpSelectionMerge %60 None\n";
2036 						s << "                OpBranchConditional %58 %59 %60\n";
2037 						s << "          %59 = OpLabel\n";
2038 						s << "          %65 = OpLoad %int %gIndex\n";
2039 						s << "          %66 = OpCopyObject %int %65\n";
2040 						s << "          %68 = OpAccessChain %_ptr_UniformConstant_61 %data %66\n";
2041 						s << "          %69 = OpLoad %61 %68\n";
2042 						s << "          %70 = OpLoad %int %rIndex\n";
2043 						s << "          %71 = OpCopyObject %int %70\n";
2044 						s << "          %72 = OpAccessChain %_ptr_UniformConstant_61 %data %71\n";
2045 						s << "          %73 = OpLoad %61 %72\n";
2046 						s << "          %74 = OpImageRead %v4float %73 %int_0\n";
2047 						s << "                OpImageWrite %69 %int_1 %74\n";
2048 						s << "                OpBranch %60\n";
2049 						s << "          %60 = OpLabel\n";
2050 					}
2051 					s << "               OpReturn\n";
2052 					s << "               OpFunctionEnd\n";
2053 					break;
2054 				case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2055 					s << "               OpCapability Shader\n";
2056 					if (allowVertexStoring)
2057 					{
2058 						s << "               OpCapability ShaderNonUniform\n";
2059 						s << "               OpCapability RuntimeDescriptorArray\n";
2060 						s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2061 						s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2062 					}
2063 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2064 					s << "               OpMemoryModel Logical GLSL450\n";
2065 					s << "               OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
2066 					s << "               OpSource GLSL 450\n";
2067 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2068 					s << "               OpName %main \"main\"\n";
2069 					s << "               OpName %gl_PerVertex \"gl_PerVertex\"\n";
2070 					s << "               OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
2071 					s << "               OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
2072 					s << "               OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
2073 					s << "               OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
2074 					s << "               OpName %_ \"\"\n";
2075 					s << "               OpName %position \"position\"\n";
2076 					s << "               OpName %in_position \"in_position\"\n";
2077 					s << "               OpName %normalpos \"normalpos\"\n";
2078 					s << "               OpName %in_normalpos \"in_normalpos\"\n";
2079 					s << "               OpName %vIndex \"vIndex\"\n";
2080 					s << "               OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
2081 					s << "               OpName %rIndex \"rIndex\"\n";
2082 					s << "               OpName %index \"index\"\n";
2083 					s << "               OpName %gIndex \"gIndex\"\n";
2084 					s << "               OpName %bIndex \"bIndex\"\n";
2085 					s << "               OpName %aIndex \"aIndex\"\n";
2086 					s << "               OpName %Data \"Data\"\n";
2087 					s << "               OpMemberName %Data 0 \"cnew\"\n";
2088 					s << "               OpMemberName %Data 1 \"cold\"\n";
2089 					s << "               OpName %data \"data\"\n";
2090 					s << "               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
2091 					s << "               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
2092 					s << "               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
2093 					s << "               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
2094 					s << "               OpDecorate %gl_PerVertex Block\n";
2095 					s << "               OpDecorate %position Location 0\n";
2096 					s << "               OpDecorate %in_position Location 0\n";
2097 					s << "               OpDecorate %normalpos Location 1\n";
2098 					s << "               OpDecorate %in_normalpos Location 1\n";
2099 					s << "               OpDecorate %vIndex Location 2\n";
2100 					s << "               OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
2101 					s << "               OpDecorate %rIndex Location 3\n";
2102 					s << "               OpDecorate %index Location 2\n";
2103 					s << "               OpDecorate %gIndex Location 4\n";
2104 					s << "               OpDecorate %bIndex Location 5\n";
2105 					s << "               OpDecorate %aIndex Location 6\n";
2106 					s << "               OpMemberDecorate %Data 0 Offset 0\n";
2107 					s << "               OpMemberDecorate %Data 1 Offset 16\n";
2108 					s << "               OpDecorate %Data Block\n";
2109 					s << "               OpDecorate %data DescriptorSet 0\n";
2110 					s << "               OpDecorate %data Binding 2\n";
2111 					if (allowVertexStoring)
2112 					{
2113 						// s << "               OpDecorate %66 NonUniform\n";
2114 						// s << "               OpDecorate %68 NonUniform\n";
2115 						s << "               OpDecorate %70 NonUniform\n";
2116 						// s << "               OpDecorate %71 NonUniform\n";
2117 						s << "               OpDecorate %72 NonUniform\n";
2118 					}
2119 					s << "       %void = OpTypeVoid\n";
2120 					s << "          %3 = OpTypeFunction %void\n";
2121 					s << "      %float = OpTypeFloat 32\n";
2122 					s << "    %v4float = OpTypeVector %float 4\n";
2123 					s << "       %uint = OpTypeInt 32 0\n";
2124 					s << "     %uint_1 = OpConstant %uint 1\n";
2125 					s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
2126 					s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
2127 					s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
2128 					s << "          %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
2129 					s << "        %int = OpTypeInt 32 1\n";
2130 					s << "      %int_1 = OpConstant %int 1\n";
2131 					s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
2132 					s << "%_ptr_Output_float = OpTypePointer Output %float\n";
2133 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2134 					s << "   %position = OpVariable %_ptr_Output_v4float Output\n";
2135 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2136 					s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
2137 					s << "    %v2float = OpTypeVector %float 2\n";
2138 					s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
2139 					s << "  %normalpos = OpVariable %_ptr_Output_v2float Output\n";
2140 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2141 					s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
2142 					s << "      %int_0 = OpConstant %int 0\n";
2143 					s << "%_ptr_Output_int = OpTypePointer Output %int\n";
2144 					s << "     %vIndex = OpVariable %_ptr_Output_int Output\n";
2145 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2146 					s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
2147 					s << "     %rIndex = OpVariable %_ptr_Output_int Output\n";
2148 					s << "      %v4int = OpTypeVector %int 4\n";
2149 					s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
2150 					s << "      %index = OpVariable %_ptr_Input_v4int Input\n";
2151 					s << "     %uint_0 = OpConstant %uint 0\n";
2152 					s << "     %gIndex = OpVariable %_ptr_Output_int Output\n";
2153 					s << "     %bIndex = OpVariable %_ptr_Output_int Output\n";
2154 					s << "     %uint_2 = OpConstant %uint 2\n";
2155 					s << "     %aIndex = OpVariable %_ptr_Output_int Output\n";
2156 					s << "     %uint_3 = OpConstant %uint 3\n";
2157 					s << "       %Data = OpTypeStruct %v4float %v4float\n";
2158 					if (allowVertexStoring)
2159 					{
2160 						s << "       %bool = OpTypeBool\n";
2161 						s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2162 						s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2163 						s << "       %data = OpVariable  %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2164 						s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2165 					}
2166 					else
2167 					{
2168 						s << "%_arr_Data_uint_1 = OpTypeArray %Data %uint_1\n";
2169 						s << "%_ptr_StorageBuffer__arr_Data_uint_1 = OpTypePointer StorageBuffer %_arr_Data_uint_1\n";
2170 						s << "       %data = OpVariable %_ptr_StorageBuffer__arr_Data_uint_1 StorageBuffer\n";
2171 					}
2172 					s << "       %main = OpFunction %void None %3\n";
2173 					s << "          %5 = OpLabel\n";
2174 					s << "         %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
2175 					s << "               OpStore %18 %float_0_200000003\n";
2176 					s << "         %23 = OpLoad %v4float %in_position\n";
2177 					s << "               OpStore %position %23\n";
2178 					s << "         %29 = OpLoad %v2float %in_normalpos\n";
2179 					s << "               OpStore %normalpos %29\n";
2180 					s << "         %31 = OpLoad %v4float %position\n";
2181 					s << "         %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
2182 					s << "               OpStore %32 %31\n";
2183 					s << "         %37 = OpLoad %int %gl_VertexIndex\n";
2184 					s << "               OpStore %vIndex %37\n";
2185 					s << "         %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
2186 					s << "         %44 = OpLoad %int %43\n";
2187 					s << "               OpStore %rIndex %44\n";
2188 					s << "         %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
2189 					s << "         %47 = OpLoad %int %46\n";
2190 					s << "               OpStore %gIndex %47\n";
2191 					s << "         %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
2192 					s << "         %51 = OpLoad %int %50\n";
2193 					s << "               OpStore %bIndex %51\n";
2194 					s << "         %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
2195 					s << "         %55 = OpLoad %int %54\n";
2196 					s << "               OpStore %aIndex %55\n";
2197 					if (allowVertexStoring)
2198 					{
2199 						s << "          %56 = OpLoad %int %gIndex\n";
2200 						s << "          %58 = OpINotEqual %bool %56 %int_0\n";
2201 						s << "                OpSelectionMerge %60 None\n";
2202 						s << "                OpBranchConditional %58 %59 %60\n";
2203 						s << "          %59 = OpLabel\n";
2204 						s << "          %65 = OpLoad %int %gIndex\n";
2205 						s << "          %66 = OpCopyObject %int %65\n";
2206 						s << "          %67 = OpLoad %int %rIndex\n";
2207 						s << "          %68 = OpCopyObject %int %67\n";
2208 						s << "          %70 = OpAccessChain %_ptr_StorageBuffer_v4float %data %68 %int_1\n";
2209 						s << "          %71 = OpLoad %v4float %70\n";
2210 						s << "          %72 = OpAccessChain %_ptr_StorageBuffer_v4float %data %66 %int_0\n";
2211 						s << "                OpStore %72 %71\n";
2212 						s << "                OpBranch %60\n";
2213 						s << "          %60 = OpLabel\n";
2214 					}
2215 					s << "               OpReturn\n";
2216 					s << "               OpFunctionEnd\n";
2217 					break;
2218 				default:
2219 					TCU_THROW(InternalError, "Unexpected descriptor type");
2220 					break;
2221 			}
2222 			break;
2223 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2224 			switch (testCaseParams.descriptorType)
2225 			{
2226 				case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2227 					s << "               OpCapability Shader\n";
2228 					if (testCaseParams.usesMipMaps)
2229 					{
2230 						s << "               OpCapability ImageQuery\n";
2231 					}
2232 					s << "               OpCapability ShaderNonUniform\n";
2233 					s << "               OpCapability RuntimeDescriptorArray\n";
2234 					s << "               OpCapability SampledImageArrayNonUniformIndexing\n";
2235 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2236 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2237 					s << "               OpMemoryModel Logical GLSL450\n";
2238 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2239 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2240 					s << "               OpSource GLSL 450\n";
2241 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2242 					s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2243 					s << "               OpName %main \"main\"\n";
2244 					s << "               OpName %FragColor \"FragColor\"\n";
2245 					s << "               OpName %data \"data\"\n";
2246 					s << "               OpName %rIndex \"rIndex\"\n";
2247 					s << "               OpName %position \"position\"\n";
2248 					s << "               OpName %normalpos \"normalpos\"\n";
2249 					s << "               OpName %vIndex \"vIndex\"\n";
2250 					s << "               OpName %gIndex \"gIndex\"\n";
2251 					s << "               OpName %bIndex \"bIndex\"\n";
2252 					s << "               OpName %aIndex \"aIndex\"\n";
2253 					s << "               OpDecorate %FragColor Location 0\n";
2254 					s << "               OpDecorate %data DescriptorSet 0\n";
2255 					s << "               OpDecorate %data Binding 7\n";
2256 					s << "               OpDecorate %rIndex Flat\n";
2257 					s << "               OpDecorate %rIndex Location 3\n";
2258 					// s << "               OpDecorate %19 NonUniform\n";
2259 					// s << "               OpDecorate %21 NonUniform\n";
2260 					s << "               OpDecorate %22 NonUniform\n";
2261 					if (testCaseParams.usesMipMaps)
2262 					{
2263 						// s << "               OpDecorate %27 NonUniform\n";
2264 						// s << "               OpDecorate %28 NonUniform\n";
2265 						// s << "               OpDecorate %29 NonUniform\n";
2266 						s << "               OpDecorate %30 NonUniform\n";
2267 					}
2268 					s << "               OpDecorate %position Flat\n";
2269 					s << "               OpDecorate %position Location 0\n";
2270 					s << "               OpDecorate %normalpos Flat\n";
2271 					s << "               OpDecorate %normalpos Location 1\n";
2272 					s << "               OpDecorate %vIndex Flat\n";
2273 					s << "               OpDecorate %vIndex Location 2\n";
2274 					s << "               OpDecorate %gIndex Flat\n";
2275 					s << "               OpDecorate %gIndex Location 4\n";
2276 					s << "               OpDecorate %bIndex Flat\n";
2277 					s << "               OpDecorate %bIndex Location 5\n";
2278 					s << "               OpDecorate %aIndex Flat\n";
2279 					s << "               OpDecorate %aIndex Location 6\n";
2280 					s << "       %void = OpTypeVoid\n";
2281 					s << "          %3 = OpTypeFunction %void\n";
2282 					s << "      %float = OpTypeFloat 32\n";
2283 					s << "    %v4float = OpTypeVector %float 4\n";
2284 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2285 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2286 					s << "         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
2287 					s << "         %11 = OpTypeSampledImage %10\n";
2288 					s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2289 					s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2290 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2291 					s << "        %int = OpTypeInt 32 1\n";
2292 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2293 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2294 					s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2295 					s << "    %v2float = OpTypeVector %float 2\n";
2296 					s << "    %float_0 = OpConstant %float 0\n";
2297 					s << "      %int_1 = OpConstant %int 1\n";
2298 					s << "         %25 = OpConstantComposite %v2float %float_0 %float_0\n";
2299 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2300 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2301 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2302 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2303 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2304 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2305 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2306 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2307 					s << "       %main = OpFunction %void None %3\n";
2308 					s << "          %5 = OpLabel\n";
2309 					s << "         %18 = OpLoad %int %rIndex\n";
2310 					s << "         %19 = OpCopyObject %int %18\n";
2311 					s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2312 					s << "         %22 = OpLoad %11 %21\n";
2313 					if (testCaseParams.usesMipMaps)
2314 					{
2315 						s << "          %26 = OpLoad %int %rIndex\n";
2316 						s << "          %27 = OpCopyObject %int %26\n";
2317 						s << "          %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
2318 						s << "          %29 = OpLoad %11 %28\n";
2319 						s << "          %30 = OpImage %10 %29\n";
2320 						s << "          %31 = OpImageQueryLevels %int %30\n";
2321 						s << "          %33 = OpISub %int %31 %int_1\n";
2322 						s << "          %34 = OpConvertSToF %float %33\n";
2323 						s << "          %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
2324 						s << "                OpStore %FragColor %35\n";
2325 					}
2326 					else
2327 					{
2328 						s << "         %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
2329 						s << "               OpStore %FragColor %26\n";
2330 					}
2331 					s << "               OpReturn\n";
2332 					s << "               OpFunctionEnd\n";
2333 					break;
2334 				case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2335 					s << "               OpCapability Shader\n";
2336 					s << "               OpCapability SampledBuffer\n";
2337 					s << "               OpCapability ShaderNonUniform\n";
2338 					s << "               OpCapability RuntimeDescriptorArray\n";
2339 					s << "               OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
2340 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2341 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2342 					s << "               OpMemoryModel Logical GLSL450\n";
2343 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2344 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2345 					s << "               OpSource GLSL 450\n";
2346 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2347 					s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2348 					s << "               OpName %main \"main\"\n";
2349 					s << "               OpName %FragColor \"FragColor\"\n";
2350 					s << "               OpName %data \"data\"\n";
2351 					s << "               OpName %rIndex \"rIndex\"\n";
2352 					s << "               OpName %position \"position\"\n";
2353 					s << "               OpName %normalpos \"normalpos\"\n";
2354 					s << "               OpName %vIndex \"vIndex\"\n";
2355 					s << "               OpName %gIndex \"gIndex\"\n";
2356 					s << "               OpName %bIndex \"bIndex\"\n";
2357 					s << "               OpName %aIndex \"aIndex\"\n";
2358 					s << "               OpDecorate %FragColor Location 0\n";
2359 					s << "               OpDecorate %data DescriptorSet 0\n";
2360 					s << "               OpDecorate %data Binding 3\n";
2361 					s << "               OpDecorate %rIndex Flat\n";
2362 					s << "               OpDecorate %rIndex Location 3\n";
2363 					// s << "               OpDecorate %19 NonUniform\n";
2364 					// s << "               OpDecorate %21 NonUniform\n";
2365 					// s << "               OpDecorate %22 NonUniform\n";
2366 					s << "               OpDecorate %24 NonUniform\n";
2367 					s << "               OpDecorate %position Flat\n";
2368 					s << "               OpDecorate %position Location 0\n";
2369 					s << "               OpDecorate %normalpos Flat\n";
2370 					s << "               OpDecorate %normalpos Location 1\n";
2371 					s << "               OpDecorate %vIndex Flat\n";
2372 					s << "               OpDecorate %vIndex Location 2\n";
2373 					s << "               OpDecorate %gIndex Flat\n";
2374 					s << "               OpDecorate %gIndex Location 4\n";
2375 					s << "               OpDecorate %bIndex Flat\n";
2376 					s << "               OpDecorate %bIndex Location 5\n";
2377 					s << "               OpDecorate %aIndex Flat\n";
2378 					s << "               OpDecorate %aIndex Location 6\n";
2379 					s << "       %void = OpTypeVoid\n";
2380 					s << "          %3 = OpTypeFunction %void\n";
2381 					s << "      %float = OpTypeFloat 32\n";
2382 					s << "    %v4float = OpTypeVector %float 4\n";
2383 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2384 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2385 					s << "         %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
2386 					s << "         %11 = OpTypeSampledImage %10\n";
2387 					s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2388 					s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2389 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2390 					s << "        %int = OpTypeInt 32 1\n";
2391 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2392 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2393 					s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2394 					s << "      %int_0 = OpConstant %int 0\n";
2395 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2396 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2397 					s << "    %v2float = OpTypeVector %float 2\n";
2398 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2399 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2400 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2401 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2402 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2403 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2404 					s << "       %main = OpFunction %void None %3\n";
2405 					s << "          %5 = OpLabel\n";
2406 					s << "         %18 = OpLoad %int %rIndex\n";
2407 					s << "         %19 = OpCopyObject %int %18\n";
2408 					s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2409 					s << "         %22 = OpLoad %11 %21\n";
2410 					s << "         %24 = OpImage %10 %22\n";
2411 					s << "         %25 = OpImageFetch %v4float %24 %int_0\n";
2412 					s << "               OpStore %FragColor %25\n";
2413 					s << "               OpReturn\n";
2414 					s << "               OpFunctionEnd\n";
2415 					break;
2416 				case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2417 					s << "               OpCapability Shader\n";
2418 					s << "               OpCapability ImageBuffer\n";
2419 					s << "               OpCapability ShaderNonUniform\n";
2420 					s << "               OpCapability RuntimeDescriptorArray\n";
2421 					s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
2422 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2423 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2424 					s << "               OpMemoryModel Logical GLSL450\n";
2425 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2426 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2427 					s << "               OpSource GLSL 450\n";
2428 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2429 					s << "               OpName %main \"main\"\n";
2430 					s << "               OpName %FragColor \"FragColor\"\n";
2431 					s << "               OpName %data \"data\"\n";
2432 					s << "               OpName %rIndex \"rIndex\"\n";
2433 					s << "               OpName %position \"position\"\n";
2434 					s << "               OpName %normalpos \"normalpos\"\n";
2435 					s << "               OpName %vIndex \"vIndex\"\n";
2436 					s << "               OpName %gIndex \"gIndex\"\n";
2437 					s << "               OpName %bIndex \"bIndex\"\n";
2438 					s << "               OpName %aIndex \"aIndex\"\n";
2439 					s << "               OpDecorate %FragColor Location 0\n";
2440 					s << "               OpDecorate %data DescriptorSet 0\n";
2441 					s << "               OpDecorate %data Binding 4\n";
2442 					s << "               OpDecorate %rIndex Flat\n";
2443 					s << "               OpDecorate %rIndex Location 3\n";
2444 					// s << "               OpDecorate %18 NonUniform\n";
2445 					// s << "               OpDecorate %20 NonUniform\n";
2446 					s << "               OpDecorate %21 NonUniform\n";
2447 					s << "               OpDecorate %position Flat\n";
2448 					s << "               OpDecorate %position Location 0\n";
2449 					s << "               OpDecorate %normalpos Flat\n";
2450 					s << "               OpDecorate %normalpos Location 1\n";
2451 					s << "               OpDecorate %vIndex Flat\n";
2452 					s << "               OpDecorate %vIndex Location 2\n";
2453 					s << "               OpDecorate %gIndex Flat\n";
2454 					s << "               OpDecorate %gIndex Location 4\n";
2455 					s << "               OpDecorate %bIndex Flat\n";
2456 					s << "               OpDecorate %bIndex Location 5\n";
2457 					s << "               OpDecorate %aIndex Flat\n";
2458 					s << "               OpDecorate %aIndex Location 6\n";
2459 					s << "       %void = OpTypeVoid\n";
2460 					s << "          %3 = OpTypeFunction %void\n";
2461 					s << "      %float = OpTypeFloat 32\n";
2462 					s << "    %v4float = OpTypeVector %float 4\n";
2463 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2464 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2465 					s << "         %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2466 					s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2467 					s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2468 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2469 					s << "        %int = OpTypeInt 32 1\n";
2470 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2471 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2472 					s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2473 					s << "      %int_0 = OpConstant %int 0\n";
2474 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2475 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2476 					s << "    %v2float = OpTypeVector %float 2\n";
2477 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2478 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2479 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2480 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2481 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2482 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2483 					s << "       %main = OpFunction %void None %3\n";
2484 					s << "          %5 = OpLabel\n";
2485 					s << "         %17 = OpLoad %int %rIndex\n";
2486 					s << "         %18 = OpCopyObject %int %17\n";
2487 					s << "         %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
2488 					s << "         %21 = OpLoad %10 %20\n";
2489 					s << "         %23 = OpImageRead %v4float %21 %int_0\n";
2490 					s << "               OpStore %FragColor %23\n";
2491 					s << "               OpReturn\n";
2492 					s << "               OpFunctionEnd\n";
2493 					break;
2494 				case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2495 					s << "               OpCapability Shader\n";
2496 					s << "               OpCapability ShaderNonUniform\n";
2497 					s << "               OpCapability RuntimeDescriptorArray\n";
2498 					s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2499 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2500 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2501 					s << "               OpMemoryModel Logical GLSL450\n";
2502 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2503 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2504 					s << "               OpSource GLSL 450\n";
2505 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2506 					s << "               OpName %main \"main\"\n";
2507 					s << "               OpName %FragColor \"FragColor\"\n";
2508 					s << "               OpName %Data \"Data\"\n";
2509 					s << "               OpMemberName %Data 0 \"cnew\"\n";
2510 					s << "               OpMemberName %Data 1 \"cold\"\n";
2511 					s << "               OpName %data \"data\"\n";
2512 					s << "               OpName %rIndex \"rIndex\"\n";
2513 					s << "               OpName %position \"position\"\n";
2514 					s << "               OpName %normalpos \"normalpos\"\n";
2515 					s << "               OpName %vIndex \"vIndex\"\n";
2516 					s << "               OpName %gIndex \"gIndex\"\n";
2517 					s << "               OpName %bIndex \"bIndex\"\n";
2518 					s << "               OpName %aIndex \"aIndex\"\n";
2519 					s << "               OpDecorate %FragColor Location 0\n";
2520 					s << "               OpMemberDecorate %Data 0 Offset 0\n";
2521 					s << "               OpMemberDecorate %Data 1 Offset 16\n";
2522 					s << "               OpDecorate %Data Block\n";
2523 					s << "               OpDecorate %data DescriptorSet 0\n";
2524 					s << "               OpDecorate %data Binding 2\n";
2525 					s << "               OpDecorate %rIndex Flat\n";
2526 					s << "               OpDecorate %rIndex Location 3\n";
2527 					// s << "               OpDecorate %18 NonUniform\n";
2528 					s << "               OpDecorate %21 NonUniform\n";
2529 					// s << "               OpDecorate %22 NonUniform\n";
2530 					s << "               OpDecorate %position Flat\n";
2531 					s << "               OpDecorate %position Location 0\n";
2532 					s << "               OpDecorate %normalpos Flat               OpDecorate %normalpos Location 1\n";
2533 					s << "               OpDecorate %vIndex Flat\n";
2534 					s << "               OpDecorate %vIndex Location 2\n";
2535 					s << "               OpDecorate %gIndex Flat\n";
2536 					s << "               OpDecorate %gIndex Location 4\n";
2537 					s << "               OpDecorate %bIndex Flat\n";
2538 					s << "               OpDecorate %bIndex Location 5\n";
2539 					s << "               OpDecorate %aIndex Flat\n";
2540 					s << "               OpDecorate %aIndex Location 6\n";
2541 					s << "       %void = OpTypeVoid\n";
2542 					s << "          %3 = OpTypeFunction %void\n";
2543 					s << "      %float = OpTypeFloat 32\n";
2544 					s << "    %v4float = OpTypeVector %float 4\n";
2545 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2546 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2547 					s << "       %Data = OpTypeStruct %v4float %v4float\n";
2548 					s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2549 					s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2550 					s << "       %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2551 					s << "        %int = OpTypeInt 32 1\n";
2552 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2553 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2554 					s << "      %int_1 = OpConstant %int 1\n";
2555 					s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2556 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2557 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2558 					s << "    %v2float = OpTypeVector %float 2\n";
2559 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2560 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2561 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2562 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2563 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2564 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2565 					s << "       %main = OpFunction %void None %3\n";
2566 					s << "          %5 = OpLabel\n";
2567 					s << "         %17 = OpLoad %int %rIndex\n";
2568 					s << "         %18 = OpCopyObject %int %17\n";
2569 					s << "         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
2570 					s << "         %22 = OpLoad %v4float %21\n";
2571 					s << "               OpStore %FragColor %22\n";
2572 					s << "               OpReturn\n";
2573 					s << "               OpFunctionEnd\n";
2574 					break;
2575 				case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2576 					s << "               OpCapability Shader\n";
2577 					s << "               OpCapability ShaderNonUniform\n";
2578 					s << "               OpCapability RuntimeDescriptorArray\n";
2579 					s << "               OpCapability UniformBufferArrayNonUniformIndexing\n";
2580 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2581 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2582 					s << "               OpMemoryModel Logical GLSL450\n";
2583 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2584 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2585 					s << "               OpSource GLSL 450\n";
2586 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2587 					s << "               OpName %main \"main\"\n";
2588 					s << "               OpName %FragColor \"FragColor\"\n";
2589 					s << "               OpName %Data \"Data\"\n";
2590 					s << "               OpMemberName %Data 0 \"c\"\n";
2591 					s << "               OpName %data \"data\"\n";
2592 					s << "               OpName %rIndex \"rIndex\"\n";
2593 					s << "               OpName %position \"position\"\n";
2594 					s << "               OpName %normalpos \"normalpos\"\n";
2595 					s << "               OpName %vIndex \"vIndex\"\n";
2596 					s << "               OpName %gIndex \"gIndex\"\n";
2597 					s << "               OpName %bIndex \"bIndex\"\n";
2598 					s << "               OpName %aIndex \"aIndex\"\n";
2599 					s << "               OpDecorate %FragColor Location 0\n";
2600 					s << "               OpMemberDecorate %Data 0 Offset 0\n";
2601 					s << "               OpDecorate %Data Block\n";
2602 					s << "               OpDecorate %data DescriptorSet 0\n";
2603 					s << "               OpDecorate %data Binding 1\n";
2604 					s << "               OpDecorate %rIndex Flat\n";
2605 					s << "               OpDecorate %rIndex Location 3\n";
2606 					// s << "               OpDecorate %18 NonUniform\n";
2607 					s << "               OpDecorate %21 NonUniform\n";
2608 					// s << "               OpDecorate %22 NonUniform\n";
2609 					s << "               OpDecorate %position Flat\n";
2610 					s << "               OpDecorate %position Location 0\n";
2611 					s << "               OpDecorate %normalpos Flat\n";
2612 					s << "               OpDecorate %normalpos Location 1\n";
2613 					s << "               OpDecorate %vIndex Flat\n";
2614 					s << "               OpDecorate %vIndex Location 2\n";
2615 					s << "               OpDecorate %gIndex Flat\n";
2616 					s << "               OpDecorate %gIndex Location 4\n";
2617 					s << "               OpDecorate %bIndex Flat\n";
2618 					s << "               OpDecorate %bIndex Location 5\n";
2619 					s << "               OpDecorate %aIndex Flat\n";
2620 					s << "               OpDecorate %aIndex Location 6\n";
2621 					s << "       %void = OpTypeVoid\n";
2622 					s << "          %3 = OpTypeFunction %void\n";
2623 					s << "      %float = OpTypeFloat 32\n";
2624 					s << "    %v4float = OpTypeVector %float 4\n";
2625 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2626 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2627 					s << "       %Data = OpTypeStruct %v4float\n";
2628 					s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2629 					s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
2630 					s << "       %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
2631 					s << "        %int = OpTypeInt 32 1\n";
2632 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2633 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2634 					s << "      %int_0 = OpConstant %int 0\n";
2635 					s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
2636 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2637 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2638 					s << "    %v2float = OpTypeVector %float 2\n";
2639 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2640 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2641 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2642 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2643 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2644 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2645 					s << "       %main = OpFunction %void None %3\n";
2646 					s << "          %5 = OpLabel\n";
2647 					s << "         %17 = OpLoad %int %rIndex\n";
2648 					s << "         %18 = OpCopyObject %int %17\n";
2649 					s << "         %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
2650 					s << "         %22 = OpLoad %v4float %21\n";
2651 					s << "               OpStore %FragColor %22\n";
2652 					s << "               OpReturn\n";
2653 					s << "               OpFunctionEnd\n";
2654 					break;
2655 				default:
2656 					TCU_THROW(InternalError, "Unexpected descriptor type");
2657 					break;
2658 			}
2659 		    break;
2660 		case VK_SHADER_STAGE_COMPUTE_BIT:
2661 			switch (testCaseParams.descriptorType)
2662 			{
2663 				case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2664 					s << "               OpCapability Shader\n";
2665 					s << "               OpCapability ShaderNonUniform\n";
2666 					s << "               OpCapability RuntimeDescriptorArray\n";
2667 					s << "               OpCapability StorageImageArrayNonUniformIndexing\n";
2668 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2669 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2670 					s << "               OpMemoryModel Logical GLSL450\n";
2671 					s << "               OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
2672 					s << "               OpExecutionMode %main LocalSize 1 1 1\n";
2673 					s << "               OpSource GLSL 450\n";
2674 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2675 					s << "               OpName %main \"main\"\n";
2676 					s << "               OpName %c \"c\"\n";
2677 					s << "               OpName %idxs \"idxs\"\n";
2678 					s << "               OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
2679 					s << "               OpName %data \"data\"\n";
2680 					s << "               OpDecorate %idxs DescriptorSet 0\n";
2681 					s << "               OpDecorate %idxs Binding 12\n";
2682 					s << "               OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
2683 					s << "               OpDecorate %data DescriptorSet 0\n";
2684 					s << "               OpDecorate %data Binding 11\n";
2685 					// s << "               OpDecorate %36 NonUniform\n";
2686 					// s << "               OpDecorate %37 NonUniform\n";
2687 					s << "               OpDecorate %41 NonUniform\n";
2688 					s << "               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
2689 					s << "       %void = OpTypeVoid\n";
2690 					s << "          %3 = OpTypeFunction %void\n";
2691 					s << "       %uint = OpTypeInt 32 0\n";
2692 					s << "     %v4uint = OpTypeVector %uint 4\n";
2693 					s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
2694 					s << "         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
2695 					s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2696 					s << "       %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
2697 					s << "     %v3uint = OpTypeVector %uint 3\n";
2698 					s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
2699 					s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
2700 					s << "     %uint_0 = OpConstant %uint 0\n";
2701 					s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
2702 					s << "        %int = OpTypeInt 32 1\n";
2703 					s << "     %uint_1 = OpConstant %uint 1\n";
2704 					s << "      %v2int = OpTypeVector %int 2\n";
2705 					s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2706 					s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2707 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2708 					s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
2709 					s << "      %int_0 = OpConstant %int 0\n";
2710 					s << "         %39 = OpConstantComposite %v2int %int_0 %int_0\n";
2711 					s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
2712 					s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
2713 					s << "       %main = OpFunction %void None %3\n";
2714 					s << "          %5 = OpLabel\n";
2715 					s << "          %c = OpVariable %_ptr_Function_v4uint Function\n";
2716 					s << "         %13 = OpLoad %10 %idxs\n";
2717 					s << "         %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
2718 					s << "         %20 = OpLoad %uint %19\n";
2719 					s << "         %22 = OpBitcast %int %20\n";
2720 					s << "         %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
2721 					s << "         %25 = OpLoad %uint %24\n";
2722 					s << "         %26 = OpBitcast %int %25\n";
2723 					s << "         %28 = OpCompositeConstruct %v2int %22 %26\n";
2724 					s << "         %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
2725 					s << "               OpStore %c %29\n";
2726 					s << "         %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
2727 					s << "         %35 = OpLoad %uint %34\n";
2728 					s << "         %36 = OpCopyObject %uint %35\n";
2729 					s << "         %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
2730 					s << "         %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
2731 					s << "         %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
2732 					s << "               OpReturn\n";
2733 					s << "               OpFunctionEnd\n";
2734 					break;
2735 				default:
2736 					TCU_THROW(InternalError, "Unexpected descriptor type");
2737 					break;
2738 			}
2739 			break;
2740 		default:
2741 			TCU_THROW(InternalError, "Unexpected stage");
2742 			break;
2743 	}
2744 
2745 	return s.str();
2746 }
2747 
getShaderSource(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)2748 std::string CommonDescriptorInstance::getShaderSource				(VkShaderStageFlagBits						shaderType,
2749 																	 const TestCaseParams&						testCaseParams,
2750 																	 bool										allowVertexStoring)
2751 {
2752 	std::stringstream	s;
2753 
2754 	s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
2755 	s << "#extension GL_EXT_nonuniform_qualifier : require	\n";
2756 
2757 	if (testCaseParams.calculateInLoop)
2758 	{
2759 		s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
2760 		s << substBinding(BINDING_DescriptorEnumerator,
2761 			"layout(set=1,binding=${?}) uniform isamplerBuffer iter;	\n");
2762 	}
2763 
2764 	switch (testCaseParams.descriptorType)
2765 	{
2766 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2767 			s << substBinding(BINDING_StorageBuffer,
2768 				"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2769 			break;
2770 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2771 			s << substBinding(BINDING_StorageBufferDynamic,
2772 				"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2773 			break;
2774 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2775 			s << substBinding(BINDING_UniformBuffer,
2776 				"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2777 			break;
2778 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2779 			s << substBinding(BINDING_UniformBufferDynamic,
2780 				"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2781 			break;
2782 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2783 			s << substBinding(BINDING_StorageTexelBuffer,
2784 				"layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
2785 			break;
2786 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2787 			s << "#extension GL_EXT_texture_buffer : require	\n";
2788 			s << substBinding(BINDING_UniformTexelBuffer,
2789 				"layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
2790 			break;
2791 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2792 			// Left for the consistent of code.
2793 			// Header is set one swicth below
2794 			break;
2795 		case VK_DESCRIPTOR_TYPE_SAMPLER:
2796 			s << "#extension GL_EXT_texture_buffer : require	\n";
2797 			s << substBinding(BINDING_SampledImage,
2798 				"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
2799 			s << substBinding(BINDING_Sampler,
2800 				"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
2801 			break;
2802 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2803 			s << "#extension GL_EXT_texture_buffer : require	\n";
2804 			s << substBinding(BINDING_Sampler,
2805 				"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
2806 			s << substBinding(BINDING_SampledImage,
2807 				"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
2808 			break;
2809 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2810 			s << "#extension GL_EXT_texture_buffer : require	\n";
2811 			s << substBinding(BINDING_CombinedImageSampler,
2812 				"layout(set=0,binding=${?}) uniform sampler2D data[];\n");
2813 			break;
2814 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2815 			s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in;	\n";
2816 			s << substBinding(BINDING_StorageImage + 1,
2817 				"layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs;	\n");
2818 			s << substBinding(BINDING_StorageImage,
2819 				"layout(r32ui,set=0,binding=${?}) uniform uimage2D data[];	\n");
2820 			break;
2821 		default:
2822 			TCU_THROW(InternalError, "Not implemented descriptor type");
2823 	}
2824 
2825 	switch (shaderType)
2826 	{
2827 		case VK_SHADER_STAGE_VERTEX_BIT:	s << getVertexShaderProlog();	break;
2828 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2829 			{
2830 				if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
2831 				{
2832 					s << substBinding(BINDING_InputAttachment,
2833 						"layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[];	\n");
2834 				}
2835 				s << getFragmentShaderProlog();
2836 			}
2837 			break;
2838 		case VK_SHADER_STAGE_COMPUTE_BIT:
2839 			break;
2840 		default:
2841 			TCU_THROW(InternalError, "Not implemented shader stage");
2842 	}
2843 
2844 	switch (shaderType)
2845 	{
2846 		case VK_SHADER_STAGE_VERTEX_BIT:
2847 		{
2848 			switch (testCaseParams.descriptorType)
2849 			{
2850 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2851 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2852 				if (allowVertexStoring)
2853 					s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;	\n";
2854 				break;
2855 			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2856 				if (allowVertexStoring)
2857 					s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, imageLoad(data[nonuniformEXT(rIndex)], 0));	\n";
2858 				break;
2859 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2860 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2861 			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2862 			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2863 			case VK_DESCRIPTOR_TYPE_SAMPLER:
2864 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2865 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2866 				break;
2867 
2868 			default:
2869 				TCU_THROW(InternalError, "Not implemented descriptor type");
2870 			}
2871 		}
2872 		break;
2873 
2874 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2875 		{
2876 			switch (testCaseParams.descriptorType)
2877 			{
2878 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2879 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2880 			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2881 				{
2882 					if (testCaseParams.calculateInLoop)
2883 						s << getFragmentLoopSource(
2884 							getColorAccess(testCaseParams.descriptorType, "rIndex", false),
2885 							getColorAccess(testCaseParams.descriptorType, "loopIdx", false));
2886 					else
2887 						s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", false));
2888 				}
2889 				break;
2890 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2891 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2892 			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2893 			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2894 			case VK_DESCRIPTOR_TYPE_SAMPLER:
2895 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2896 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2897 				if (testCaseParams.calculateInLoop)
2898 					s << getFragmentLoopSource(
2899 						getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
2900 						getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
2901 				else
2902 					s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
2903 				break;
2904 			default:	TCU_THROW(InternalError, "Not implemented descriptor type");
2905 			}
2906 		}
2907 		break;
2908 
2909 		case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
2910 			s << "void main(void)\n{\n";
2911 			if (testCaseParams.calculateInLoop)
2912 				s << "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)	\n"
2913 					"    imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, i).x)], ivec2(0, 0), 1);			\n";
2914 			else
2915 				s << "  uvec4 c = imageLoad(idxs, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y));	\n"
2916 					"  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);								\n";
2917 			break;
2918 
2919 		default:	TCU_THROW(InternalError, "Not implemented shader stage");
2920 	}
2921 
2922 	s << getShaderEpilog();
2923 
2924 	return s.str();
2925 }
2926 
2927 class StorageBufferInstance : virtual public CommonDescriptorInstance
2928 {
2929 public:
2930 								StorageBufferInstance				(Context&									context,
2931 																	 const TestCaseParams&						testCaseParams);
2932 protected:
2933 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
2934 
2935 	virtual bool				verifyVertexWriteResults			(IterateCommonVariables&					variables);
2936 };
2937 
StorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)2938 StorageBufferInstance::StorageBufferInstance						(Context&									context,
2939 																	 const TestCaseParams&						testCaseParams)
2940 	: CommonDescriptorInstance(context,
2941 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2942 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2943 			BINDING_StorageBuffer,
2944 			VK_DESCRIPTOR_TYPE_UNDEFINED,
2945 			BINDING_Undefined,
2946 			false,
2947 			performWritesInVertex(testCaseParams.descriptorType, context),
2948 			testCaseParams))
2949 {
2950 }
2951 
createAndPopulateDescriptors(IterateCommonVariables & variables)2952 void StorageBufferInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
2953 {
2954 	BindingStorageBuffer::Data	data;
2955 
2956 	bool						vertexStores = false;
2957 	{
2958 		ut::DeviceProperties dp(m_context);
2959 		vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != DE_FALSE;
2960 	}
2961 	const deUint32				alignment	= static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2962 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2963 
2964 	unsigned char*				buffer		= static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2965 	for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
2966 	{
2967 		const float				component	= m_colorScheme[infoIdx % m_schemeSize];
2968 		const tcu::Vec4			color		(component, component, component, 1.0f);
2969 		VkDescriptorBufferInfo& info		= variables.descriptorsBufferInfos[infoIdx];
2970 		data.cnew							= vertexStores ? m_clearColor : color;
2971 		data.cold							= color;
2972 
2973 		deMemcpy(buffer + info.offset, &data, sizeof(data));
2974 	}
2975 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2976 
2977 	variables.dataAlignment = deAlign64(sizeof(data), alignment);
2978 }
2979 
verifyVertexWriteResults(IterateCommonVariables & variables)2980 bool StorageBufferInstance::verifyVertexWriteResults				(IterateCommonVariables&					variables)
2981 {
2982 	const tcu::Vec4				threshold		(0.002f, 0.002f, 0.002f, 0.002f);
2983 	const std::vector<deUint32>	primes			= ut::generatePrimes(variables.availableDescriptorCount);
2984 
2985 	unsigned char*				buffer = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2986 	BindingStorageBuffer::Data	data;
2987 	for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
2988 	{
2989 		const deUint32			prime		= primes[primeIdx];
2990 		const float				component	= m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
2991 		const tcu::Vec4			referenceValue(component, component, component, 1.0f);
2992 
2993 		VkDescriptorBufferInfo& info = variables.descriptorsBufferInfos[primeIdx];
2994 		deMemcpy(&data, buffer + info.offset, sizeof(data));
2995 		const tcu::Vec4			realValue = data.cnew;
2996 
2997 		const tcu::Vec4			diff = tcu::absDiff(referenceValue, realValue);
2998 		if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
2999 			return false;
3000 	}
3001 	return true;
3002 }
3003 
3004 class UniformBufferInstance : virtual public CommonDescriptorInstance
3005 {
3006 public:
3007 								UniformBufferInstance				(Context&									context,
3008 																	 const TestCaseParams&						testCaseParams);
3009 protected:
3010 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3011 };
3012 
UniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3013 UniformBufferInstance::UniformBufferInstance						(Context&									context,
3014 																	 const TestCaseParams&						testCaseParams)
3015 	: CommonDescriptorInstance(context,
3016 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3017 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3018 			BINDING_UniformBuffer,
3019 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3020 			BINDING_Undefined,
3021 			false,
3022 			performWritesInVertex(testCaseParams.descriptorType, context),
3023 			testCaseParams))
3024 {
3025 }
3026 
createAndPopulateDescriptors(IterateCommonVariables & variables)3027 void UniformBufferInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3028 {
3029 	BindingUniformBuffer::Data data;
3030 
3031 	const deUint32				alignment	= static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3032 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3033 
3034 	unsigned char*				buffer		= static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
3035 	for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
3036 	{
3037 		const float				component	= m_colorScheme[infoIdx % m_schemeSize];
3038 		VkDescriptorBufferInfo& info		= variables.descriptorsBufferInfos[infoIdx];
3039 		data.c								= tcu::Vec4(component, component, component, 1.0f);
3040 		deMemcpy(buffer + info.offset, &data, sizeof(data));
3041 	}
3042 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3043 
3044 	variables.dataAlignment = deAlign64(sizeof(data), alignment);
3045 }
3046 
3047 class StorageTexelInstance : public CommonDescriptorInstance
3048 {
3049 public:
3050 								StorageTexelInstance				(Context&									context,
3051 																	 const TestCaseParams&						testCaseParams);
3052 private:
3053 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3054 
3055 	virtual bool				verifyVertexWriteResults			(IterateCommonVariables&					variables);
3056 };
3057 
StorageTexelInstance(Context & context,const TestCaseParams & testCaseParams)3058 StorageTexelInstance::StorageTexelInstance							(Context&									context,
3059 																	 const TestCaseParams&						testCaseParams)
3060 	: CommonDescriptorInstance(context,
3061 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3062 			VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3063 			BINDING_StorageTexelBuffer,
3064 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3065 			BINDING_Undefined,
3066 			false,
3067 			performWritesInVertex(testCaseParams.descriptorType, context),
3068 			testCaseParams))
3069 {
3070 }
3071 
createAndPopulateDescriptors(IterateCommonVariables & variables)3072 void StorageTexelInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3073 {
3074 	const VkExtent3D			imageExtent			= { 4, 4, 1 };
3075 	const deUint32				imageSize			= ut::computeImageSize(imageExtent, m_colorFormat);
3076 
3077 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3078 	createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3079 
3080 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3081 	{
3082 		const float				component			= m_colorScheme[imageIdx % m_schemeSize];
3083 		const PixelBufferAccess pa					= getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3084 
3085 		tcu::clear(pa, m_clearColor);
3086 		pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3087 	}
3088 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3089 }
3090 
verifyVertexWriteResults(IterateCommonVariables & variables)3091 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables&					variables)
3092 {
3093 	const VkExtent3D			imageExtent		= { 4, 4, 1 };
3094 	const tcu::Vec4				threshold		(0.002f, 0.002f, 0.002f, 0.002f);
3095 	const std::vector<deUint32>	primes			= ut::generatePrimes(variables.availableDescriptorCount);
3096 
3097 	for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3098 	{
3099 		const deUint32			prime		= primes[primeIdx];
3100 		const float				component	= m_colorScheme[( prime % variables.validDescriptorCount ) % m_schemeSize];
3101 		const tcu::Vec4			referenceValue(component, component, component, 1.0f);
3102 
3103 		const PixelBufferAccess pa			= getPixelAccess(primeIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3104 		const tcu::Vec4			realValue	= pa.getPixel(1, 0);
3105 
3106 		const tcu::Vec4			diff		= tcu::absDiff(referenceValue, realValue);
3107 		if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3108 			return false;
3109 	}
3110 	return true;
3111 }
3112 
3113 class UniformTexelInstance : public CommonDescriptorInstance
3114 {
3115 public:
3116 								UniformTexelInstance				(Context&									context,
3117 																	 const TestCaseParams&						testCaseParams);
3118 private:
3119 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3120 };
3121 
UniformTexelInstance(Context & context,const TestCaseParams & testCaseParams)3122 UniformTexelInstance::UniformTexelInstance							(Context&									context,
3123 																	 const TestCaseParams&						testCaseParams)
3124 	: CommonDescriptorInstance(context,
3125 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3126 			VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3127 			BINDING_UniformTexelBuffer,
3128 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3129 			BINDING_Undefined,
3130 			false,
3131 			performWritesInVertex(testCaseParams.descriptorType, context),
3132 			testCaseParams))
3133 {
3134 }
3135 
createAndPopulateDescriptors(IterateCommonVariables & variables)3136 void UniformTexelInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3137 {
3138 	const VkExtent3D			imageExtent	= { 4, 4, 1 };
3139 	const deUint32				imageSize	= ut::computeImageSize(imageExtent, m_colorFormat);
3140 
3141 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3142 	createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3143 
3144 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3145 	{
3146 		const float				component	= m_colorScheme[imageIdx % m_schemeSize];
3147 		const PixelBufferAccess	pa			= getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3148 
3149 		tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3150 	}
3151 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3152 }
3153 
3154 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
3155 {
3156 public:
DynamicBuffersInstance(Context & context,const TestParams & testParams)3157 	DynamicBuffersInstance											(Context&									context,
3158 																	 const TestParams&							testParams)
3159 		: CommonDescriptorInstance(context, testParams) {}
3160 
3161 protected:
3162 	virtual tcu::TestStatus		iterate								(void);
3163 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3164 };
3165 
updateDescriptors(IterateCommonVariables & variables)3166 void DynamicBuffersInstance::updateDescriptors						(IterateCommonVariables&					variables)
3167 {
3168 	DE_ASSERT(variables.dataAlignment);
3169 
3170 	VkDescriptorBufferInfo	bufferInfo =
3171 	{
3172 		*variables.descriptorsBuffer.get()->buffer,
3173 		0,	// always 0, it will be taken from pDynamicOffsets
3174 		variables.dataAlignment
3175 	};
3176 
3177 	VkWriteDescriptorSet updateInfo =
3178 	{
3179 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3180 		DE_NULL,										// pNext
3181 		*variables.descriptorSet,						// descriptorSet
3182 		m_testParams.descriptorBinding,					// descriptorBinding;
3183 		0,	// to be set in below loop					// dstArrayElement
3184 		1u,												// descriptorCount
3185 		m_testParams.descriptorType,					// descriptorType
3186 		DE_NULL,										// pImageInfo
3187 		&bufferInfo,									// pBufferInfo
3188 		DE_NULL											// pTexelBufferView
3189 	};
3190 
3191 	deUint32 descIdx = 0;
3192 	const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
3193 	for (deUint32 validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
3194 	{
3195 		for (; descIdx < primes[validIdx]; ++descIdx)
3196 		{
3197 			updateInfo.dstArrayElement			= descIdx;
3198 			m_vki.updateDescriptorSets	(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3199 		}
3200 
3201 		updateInfo.dstArrayElement				= primes[validIdx];
3202 		m_vki.updateDescriptorSets		(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3203 
3204 		++descIdx;
3205 	}
3206 	for (; descIdx < variables.availableDescriptorCount; ++descIdx)
3207 	{
3208 		updateInfo.dstArrayElement = descIdx;
3209 		m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3210 	}
3211 }
3212 
iterate(void)3213 tcu::TestStatus	DynamicBuffersInstance::iterate						(void)
3214 {
3215 	IterateCommonVariables	v;
3216 	iterateCommandSetup		(v);
3217 
3218 	ut::UpdatablePixelBufferAccessPtr	programResult;
3219 	ut::UpdatablePixelBufferAccessPtr	referenceResult;
3220 	bool firstPass = true;
3221 
3222 	DE_ASSERT(v.dataAlignment);
3223 
3224 	std::vector<deUint32> dynamicOffsets;
3225 
3226 	deUint32 descIdx = 0;
3227 	const std::vector<deUint32> primes = ut::generatePrimes(v.availableDescriptorCount);
3228 	for (deUint32 validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
3229 	{
3230 		for (; descIdx < primes[validIdx]; ++descIdx)
3231 		{
3232 			dynamicOffsets.push_back(0);
3233 		}
3234 
3235 		dynamicOffsets.push_back(static_cast<deUint32>(validIdx * v.dataAlignment));
3236 
3237 		++descIdx;
3238 	}
3239 	for (; descIdx < v.availableDescriptorCount; ++descIdx)
3240 	{
3241 		dynamicOffsets.push_back(0);
3242 	}
3243 
3244 	// Unfortunatelly not lees and not more, only exactly
3245 	DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
3246 
3247 	const VkDescriptorSet	descriptorSets[] = { *v.descriptorSet };
3248 
3249 	v.renderArea.extent.width	= m_testParams.frameResolution.width/4;
3250 	v.renderArea.extent.height	= m_testParams.frameResolution.height/4;
3251 
3252 	for (int x = 0; x < 4; x++)
3253 		for (int y= 0; y < 4; y++)
3254 		{
3255 
3256 			v.renderArea.offset.x		= x * m_testParams.frameResolution.width/4;
3257 			v.renderArea.offset.y		= y * m_testParams.frameResolution.height/4;
3258 
3259 			iterateCommandBegin		(v, firstPass);
3260 			firstPass = false;
3261 
3262 	m_vki.cmdBindDescriptorSets(
3263 		*v.commandBuffer,						// commandBuffer
3264 		VK_PIPELINE_BIND_POINT_GRAPHICS,		// pipelineBindPoint
3265 		*v.pipelineLayout,						// layout
3266 		0u,										// firstSet
3267 		DE_LENGTH_OF_ARRAY(descriptorSets),		// descriptorSetCount
3268 		descriptorSets,							// pDescriptorSets
3269 		v.availableDescriptorCount,				// dynamicOffsetCount
3270 		dynamicOffsets.data());					// pDynamicOffsets
3271 
3272 			vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
3273 	m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
3274 
3275 	vk::beginRenderPass	(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
3276 			m_vki.cmdDraw			(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
3277 	vk::endRenderPass	(m_vki, *v.commandBuffer);
3278 
3279 			iterateCommandEnd(v, programResult, referenceResult);
3280 			programResult->invalidate();
3281 		}
3282 
3283 	return (iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
3284 }
3285 
3286 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
3287 {
3288 public:
3289 	DynamicStorageBufferInstance									(Context&					context,
3290 																	 const TestCaseParams&		testCaseParams);
3291 	tcu::TestStatus		iterate										(void);
3292 	void				createAndPopulateDescriptors				(IterateCommonVariables&	variables);
3293 	void				updateDescriptors							(IterateCommonVariables&	variables);
3294 	bool				verifyVertexWriteResults					(IterateCommonVariables&	variables);
3295 };
3296 
DynamicStorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)3297 DynamicStorageBufferInstance::DynamicStorageBufferInstance			(Context&					context,
3298 																	 const TestCaseParams&		testCaseParams)
3299 	: CommonDescriptorInstance(context,
3300 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3301 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3302 			BINDING_StorageBufferDynamic,
3303 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3304 			BINDING_Undefined,
3305 			false,
3306 			performWritesInVertex(testCaseParams.descriptorType, context),
3307 			testCaseParams)),
3308 			DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
3309 {
3310 }
3311 
iterate(void)3312 tcu::TestStatus	DynamicStorageBufferInstance::iterate(void)
3313 {
3314 	return DynamicBuffersInstance::iterate();
3315 }
3316 
createAndPopulateDescriptors(IterateCommonVariables & variables)3317 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&			variables)
3318 {
3319 	StorageBufferInstance::createAndPopulateDescriptors(variables);
3320 }
3321 
updateDescriptors(IterateCommonVariables & variables)3322 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables&					variables)
3323 {
3324 	DynamicBuffersInstance::updateDescriptors(variables);
3325 }
3326 
verifyVertexWriteResults(IterateCommonVariables & variables)3327 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables&				variables)
3328 {
3329 	return StorageBufferInstance::verifyVertexWriteResults(variables);
3330 }
3331 
3332 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
3333 {
3334 public:
3335 	DynamicUniformBufferInstance									(Context&					context,
3336 																	 const TestCaseParams&		testCaseParams);
3337 	tcu::TestStatus		iterate(void);
3338 	void				createAndPopulateDescriptors(IterateCommonVariables&					variables);
3339 	void				updateDescriptors(IterateCommonVariables&								variables);
3340 };
3341 
DynamicUniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3342 DynamicUniformBufferInstance::DynamicUniformBufferInstance			(Context&					context,
3343 																	 const TestCaseParams&		testCaseParams)
3344 	: CommonDescriptorInstance(context,
3345 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3346 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3347 			BINDING_UniformBufferDynamic,
3348 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3349 			BINDING_Undefined,
3350 			false,
3351 			performWritesInVertex(testCaseParams.descriptorType, context),
3352 			testCaseParams)),
3353 			DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
3354 {
3355 }
3356 
iterate(void)3357 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
3358 {
3359 	return DynamicBuffersInstance::iterate();
3360 }
3361 
createAndPopulateDescriptors(IterateCommonVariables & variables)3362 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&			variables)
3363 {
3364 	UniformBufferInstance::createAndPopulateDescriptors(variables);
3365 }
3366 
updateDescriptors(IterateCommonVariables & variables)3367 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables&					variables)
3368 {
3369 	DynamicBuffersInstance::updateDescriptors(variables);
3370 }
3371 
3372 class InputAttachmentInstance : public CommonDescriptorInstance
3373 {
3374 public:
3375 								InputAttachmentInstance				(Context&									context,
3376 																	const TestCaseParams&						testCaseParams);
3377 private:
3378 	virtual Move<VkRenderPass>	createRenderPass					(const IterateCommonVariables&				variables);
3379 	virtual void				createFramebuffer					(ut::FrameBufferSp&							frameBuffer,
3380 																	 VkRenderPass								renderPass,
3381 																	 const IterateCommonVariables&				variables);
3382 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3383 };
3384 
InputAttachmentInstance(Context & context,const TestCaseParams & testCaseParams)3385 InputAttachmentInstance::InputAttachmentInstance					(Context&									context,
3386 																	 const TestCaseParams&						testCaseParams)
3387 	: CommonDescriptorInstance(context,
3388 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3389 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3390 			BINDING_InputAttachment,
3391 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3392 			BINDING_Undefined,
3393 			true,
3394 			performWritesInVertex(testCaseParams.descriptorType, context),
3395 			testCaseParams))
3396 {
3397 }
3398 
createAndPopulateDescriptors(IterateCommonVariables & variables)3399 void InputAttachmentInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3400 {
3401 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3402 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3403 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3404 
3405 	for (deUint32 descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
3406 	{
3407 		const float						component	= m_colorScheme[descriptorIdx % m_schemeSize];
3408 		const tcu::PixelBufferAccess	pa			= getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3409 		tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3410 	}
3411 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3412 }
3413 
createRenderPass(const IterateCommonVariables & variables)3414 Move<VkRenderPass> InputAttachmentInstance::createRenderPass		(const IterateCommonVariables&				variables)
3415 {
3416 	std::vector<VkAttachmentDescription>	attachmentDescriptions;
3417 	std::vector<VkAttachmentReference>		inputAttachmentRefs;
3418 
3419 	const VkAttachmentDescription	colorAttachmentDescription =
3420 	{
3421 		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags;
3422 		m_colorFormat,								// VkFormat							format;
3423 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples;
3424 		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
3425 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
3426 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
3427 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
3428 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
3429 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout;
3430 	};
3431 	const VkAttachmentReference		colorAttachmentRef =
3432 	{
3433 		0u,												// deUint32							attachment;
3434 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout					layout;
3435 	};
3436 	attachmentDescriptions.push_back(colorAttachmentDescription);
3437 
3438 	// build input atachments
3439 	{
3440 		const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3441 		const deUint32 inputCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3442 		for (deUint32 inputIdx = 0; inputIdx < inputCount; ++inputIdx)
3443 		{
3444 			// primes holds the indices of input attachments for shader binding 10 which has input_attachment_index=1
3445 			deUint32 nextInputAttachmentIndex = primes[inputIdx] + 1;
3446 
3447 			// Fill up the subpass description's input attachments with unused attachments forming gaps to the next referenced attachment
3448 			for (deUint32 unusedIdx = static_cast<deUint32>(inputAttachmentRefs.size()); unusedIdx < nextInputAttachmentIndex; ++unusedIdx)
3449 			{
3450 				const VkAttachmentReference		inputAttachmentRef =
3451 				{
3452 					VK_ATTACHMENT_UNUSED,						// deUint32							attachment;
3453 					VK_IMAGE_LAYOUT_GENERAL						// VkImageLayout					layout;
3454 				};
3455 
3456 				inputAttachmentRefs.push_back(inputAttachmentRef);
3457 			}
3458 
3459 			const VkAttachmentDescription	inputAttachmentDescription =
3460 			{
3461 				VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,		// VkAttachmentDescriptionFlags		flags;
3462 				variables.descriptorsImages[inputIdx]->format,	// VkFormat							format;
3463 				VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits			samples;
3464 				VK_ATTACHMENT_LOAD_OP_LOAD,						// VkAttachmentLoadOp				loadOp;
3465 				VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp				storeOp;
3466 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp				stencilLoadOp;
3467 				VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp				stencilStoreOp;
3468 				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout					initialLayout;
3469 				VK_IMAGE_LAYOUT_GENERAL							// VkImageLayout					finalLayout;
3470 			};
3471 
3472 			const VkAttachmentReference		inputAttachmentRef =
3473 			{
3474 				inputIdx + 1,								// deUint32							attachment;
3475 				VK_IMAGE_LAYOUT_GENERAL						// VkImageLayout					layout;
3476 			};
3477 
3478 			inputAttachmentRefs.push_back(inputAttachmentRef);
3479 			attachmentDescriptions.push_back(inputAttachmentDescription);
3480 		}
3481 	}
3482 
3483 	const VkSubpassDescription		subpassDescription =
3484 	{
3485 		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
3486 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
3487 		static_cast<deUint32>(inputAttachmentRefs.size()),	// deUint32							inputAttachmentCount;
3488 		inputAttachmentRefs.data(),							// const VkAttachmentReference*		pInputAttachments;
3489 		1u,													// deUint32							colorAttachmentCount;
3490 		&colorAttachmentRef,								// const VkAttachmentReference*		pColorAttachments;
3491 		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
3492 		DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
3493 		0u,													// deUint32							preserveAttachmentCount;
3494 		DE_NULL												// const deUint32*					pPreserveAttachments;
3495 	};
3496 
3497 	const VkRenderPassCreateInfo	renderPassInfo =
3498 	{
3499 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
3500 		DE_NULL,												// const void*						pNext;
3501 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
3502 		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
3503 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments;
3504 		1u,														// deUint32							subpassCount;
3505 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses;
3506 		0u,														// deUint32							dependencyCount;
3507 		DE_NULL													// const VkSubpassDependency*		pDependencies;
3508 	};
3509 
3510 	return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
3511 }
3512 
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)3513 void InputAttachmentInstance::createFramebuffer						(ut::FrameBufferSp&							frameBuffer,
3514 																	 VkRenderPass								renderPass,
3515 																	 const IterateCommonVariables&				variables)
3516 {
3517 	std::vector<VkImageView>			inputAttachments;
3518 	const deUint32 viewCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3519 	inputAttachments.resize(viewCount);
3520 	for (deUint32 viewIdx = 0; viewIdx < viewCount; ++viewIdx)
3521 	{
3522 		inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
3523 	}
3524 	ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount, inputAttachments.data());
3525 }
3526 
3527 class SamplerInstance : public CommonDescriptorInstance
3528 {
3529 public:
3530 								SamplerInstance						(Context&									context,
3531 																	 const TestCaseParams&						testCaseParams);
3532 private:
3533 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3534 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3535 };
3536 
SamplerInstance(Context & context,const TestCaseParams & testCaseParams)3537 SamplerInstance::SamplerInstance									(Context&									context,
3538 																	 const TestCaseParams&						testCaseParams)
3539 	: CommonDescriptorInstance(context,
3540 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3541 			VK_DESCRIPTOR_TYPE_SAMPLER,
3542 			BINDING_Sampler,
3543 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3544 			BINDING_SampledImage,
3545 			true,
3546 			performWritesInVertex(testCaseParams.descriptorType, context),
3547 			testCaseParams))
3548 {
3549 }
3550 
updateDescriptors(IterateCommonVariables & variables)3551 void SamplerInstance::updateDescriptors								(IterateCommonVariables&					variables)
3552 {
3553 	DE_ASSERT(variables.descriptorsImages.size()		== 1);
3554 	DE_ASSERT(variables.descriptorImageViews.size()		== 1);
3555 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 1);
3556 	DE_ASSERT(m_testParams.additionalDescriptorType		== VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
3557 	DE_ASSERT(variables.descriptorSamplers.size()		== variables.validDescriptorCount);
3558 
3559 	// update an image
3560 	{
3561 		const VkDescriptorImageInfo imageInfo =
3562 		{
3563 			static_cast<VkSampler>(0),
3564 			**variables.descriptorImageViews[0],
3565 			VK_IMAGE_LAYOUT_GENERAL
3566 		};
3567 
3568 		const VkWriteDescriptorSet writeInfo =
3569 		{
3570 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3571 			DE_NULL,										// pNext
3572 			*variables.descriptorSet,						// descriptorSet
3573 			BINDING_SampledImage,							// descriptorBinding;
3574 			0,												// elementIndex
3575 			1u,												// descriptorCount
3576 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				// descriptorType
3577 			&imageInfo,										// pImageInfo
3578 			DE_NULL,										// pBufferInfo
3579 			DE_NULL											// pTexelBufferView
3580 		};
3581 
3582 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3583 	}
3584 
3585 	// update samplers
3586 	CommonDescriptorInstance::updateDescriptors(variables);
3587 }
3588 
createAndPopulateDescriptors(IterateCommonVariables & variables)3589 void SamplerInstance::createAndPopulateDescriptors					(IterateCommonVariables&					variables)
3590 {
3591 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3592 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3593 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3594 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3595 
3596 	// create and populate an image
3597 	{
3598 		VkExtent3D imageExtent = m_testParams.frameResolution;
3599 		if (m_testParams.usesMipMaps)
3600 		{
3601 			imageExtent.width *= 2;
3602 			imageExtent.height *= 2;
3603 		};
3604 
3605 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3606 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3607 		createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3608 
3609 		PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
3610 
3611 		for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
3612 		{
3613 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
3614 			{
3615 				const float		component	= m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
3616 				pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
3617 			}
3618 		}
3619 
3620 		vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3621 	}
3622 
3623 	const tcu::Sampler sampler(
3624 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapS
3625 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapT
3626 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapR
3627 		m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3628 		m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3629 		0.0f,																					// lodTreshold
3630 		true);																					// normalizeCoords
3631 	const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3632 	variables.descriptorSamplers.resize(variables.validDescriptorCount);
3633 
3634 	for (deUint32 samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
3635 	{
3636 		variables.descriptorSamplers[samplerIdx] = ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3637 	}
3638 }
3639 
3640 class SampledImageInstance : public CommonDescriptorInstance
3641 {
3642 public:
3643 								SampledImageInstance				(Context&									context,
3644 																	 const TestCaseParams&						testCaseParams);
3645 private:
3646 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3647 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3648 };
3649 
SampledImageInstance(Context & context,const TestCaseParams & testCaseParams)3650 SampledImageInstance::SampledImageInstance							(Context&									context,
3651 																	 const TestCaseParams&						testCaseParams)
3652 	: CommonDescriptorInstance(context,
3653 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3654 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3655 			BINDING_SampledImage,
3656 			VK_DESCRIPTOR_TYPE_SAMPLER,
3657 			BINDING_Sampler,
3658 			true,
3659 			performWritesInVertex(testCaseParams.descriptorType, context),
3660 			testCaseParams))
3661 {
3662 }
3663 
updateDescriptors(IterateCommonVariables & variables)3664 void SampledImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3665 {
3666 	DE_ASSERT(variables.descriptorSamplers.size()		== 1);
3667 	DE_ASSERT(variables.descriptorsImages.size()		== variables.validDescriptorCount);
3668 	DE_ASSERT(variables.descriptorImageViews.size()		== variables.validDescriptorCount);
3669 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== variables.validDescriptorCount);
3670 
3671 	// update a sampler
3672 	{
3673 		const VkDescriptorImageInfo samplerInfo =
3674 		{
3675 			**variables.descriptorSamplers[0],
3676 			static_cast<VkImageView>(0),
3677 			static_cast<VkImageLayout>(0)
3678 		};
3679 
3680 		const VkWriteDescriptorSet writeInfo =
3681 		{
3682 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3683 			DE_NULL,										// pNext
3684 			*variables.descriptorSet,						// descriptorSet
3685 			BINDING_Sampler,								// descriptorBinding;
3686 			0,												// elementIndex
3687 			1u,												// descriptorCount
3688 			VK_DESCRIPTOR_TYPE_SAMPLER,						// descriptorType
3689 			&samplerInfo,									// pImageInfo
3690 			DE_NULL,										// pBufferInfo
3691 			DE_NULL											// pTexelBufferView
3692 		};
3693 
3694 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3695 	}
3696 
3697 	// update images
3698 	CommonDescriptorInstance::updateDescriptors(variables);
3699 }
3700 
createAndPopulateDescriptors(IterateCommonVariables & variables)3701 void SampledImageInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3702 {
3703 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3704 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3705 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3706 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3707 
3708 	// create an only one sampler for all images
3709 	{
3710 		const tcu::Sampler sampler(
3711 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapS
3712 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapT
3713 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapR
3714 			m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3715 			m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3716 			0.0f,																						// lodTreshold
3717 			true);																						// normalizeCoords
3718 		const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3719 		variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3720 	}
3721 
3722 	const VkExtent3D&			imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3723 
3724 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3725 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3726 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3727 
3728 	PixelBufferAccess			pixelAccess;
3729 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3730 	{
3731 		const float				component	= m_colorScheme[imageIdx % m_schemeSize];
3732 
3733 		if (m_testParams.usesMipMaps)
3734 		{
3735 			const deUint32 mipCount = ut::computeMipMapCount(imageExtent);
3736 			DE_ASSERT(mipCount >= 2);
3737 			for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3738 			{
3739 				pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3740 				tcu::clear(pixelAccess, m_clearColor);
3741 			}
3742 
3743 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3744 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3745 		}
3746 		else
3747 		{
3748 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3749 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3750 		}
3751 	}
3752 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3753 }
3754 
3755 class CombinedImageInstance : public CommonDescriptorInstance
3756 {
3757 public:
3758 								CombinedImageInstance				(Context&									context,
3759 																	 const TestCaseParams&						testCaseParams);
3760 private:
3761 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3762 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3763 };
3764 
CombinedImageInstance(Context & context,const TestCaseParams & testCaseParams)3765 CombinedImageInstance::CombinedImageInstance						(Context&									context,
3766 																	 const TestCaseParams&						testCaseParams)
3767 	: CommonDescriptorInstance(context,
3768 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3769 			testCaseParams.descriptorType,
3770 			BINDING_CombinedImageSampler,
3771 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3772 			BINDING_Undefined,
3773 			true,
3774 			performWritesInVertex(testCaseParams.descriptorType),
3775 			testCaseParams))
3776 {
3777 }
3778 
updateDescriptors(IterateCommonVariables & variables)3779 void CombinedImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3780 {
3781 	const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3782 	const deUint32				primeCount = static_cast<deUint32>(primes.size());
3783 
3784 	DE_ASSERT(variables.descriptorSamplers.size()		== 1);
3785 	DE_ASSERT(variables.descriptorsImages.size()		== primeCount);
3786 	DE_ASSERT(variables.descriptorImageViews.size()		== primeCount);
3787 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== primeCount);
3788 
3789 	for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
3790 	{
3791 		const VkDescriptorImageInfo imageInfo =
3792 		{
3793 			**variables.descriptorSamplers[0],
3794 			**variables.descriptorImageViews[primeIdx],
3795 			VK_IMAGE_LAYOUT_GENERAL
3796 		};
3797 
3798 		const VkWriteDescriptorSet writeInfo =
3799 		{
3800 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3801 			DE_NULL,										// pNext
3802 			*variables.descriptorSet,						// descriptorSet
3803 			BINDING_CombinedImageSampler,					// descriptorBinding;
3804 			primes[primeIdx],								// elementIndex
3805 			1u,												// descriptorCount
3806 			m_testParams.descriptorType,					// descriptorType
3807 			&imageInfo,										// pImageInfo
3808 			DE_NULL,										// pBufferInfo
3809 			DE_NULL											// pTexelBufferView
3810 		};
3811 
3812 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3813 	}
3814 }
3815 
createAndPopulateDescriptors(IterateCommonVariables & variables)3816 void CombinedImageInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3817 {
3818 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3819 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3820 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3821 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3822 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3823 
3824 	const tcu::Sampler sampler(
3825 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapS
3826 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapT
3827 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapR
3828 		m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3829 		m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3830 		0.0f,																						// lodTreshold
3831 		true);																						// normalizeCoords
3832 	const VkSamplerCreateInfo	createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3833 	variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3834 
3835 	const VkExtent3D&			imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3836 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
3837 		imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3838 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3839 
3840 	PixelBufferAccess			pixelAccess;
3841 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3842 	{
3843 		const float				component = m_colorScheme[imageIdx % m_schemeSize];
3844 
3845 		if (m_testParams.usesMipMaps)
3846 		{
3847 			const deUint32	mipCount = ut::computeMipMapCount(imageExtent);
3848 			DE_ASSERT(mipCount >= 2);
3849 			for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3850 			{
3851 				pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3852 				tcu::clear(pixelAccess, m_clearColor);
3853 			}
3854 
3855 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3856 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3857 		}
3858 		else
3859 		{
3860 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3861 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3862 		}
3863 	}
3864 
3865 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3866 }
3867 
3868 class StorageImageInstance : public CommonDescriptorInstance
3869 {
3870 public:
3871 								StorageImageInstance				(Context&									context,
3872 																	 const TestCaseParams&						testCaseParams);
3873 private:
3874 	virtual tcu::TestStatus		iterate								(void);
3875 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3876 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3877 	virtual void				iterateCollectResults				(ut::UpdatablePixelBufferAccessPtr&			result,
3878 																	 const IterateCommonVariables&				variables,
3879 																	 bool										fromTest);
3880 	ut::BufferHandleAllocSp		m_buffer;
3881 	const deUint32				m_fillColor;
3882 	typedef deUint32			m_imageFormat_t;
3883 };
3884 
StorageImageInstance(Context & context,const TestCaseParams & testCaseParams)3885 StorageImageInstance::StorageImageInstance							(Context&									context,
3886 																	 const TestCaseParams&						testCaseParams)
3887 	: CommonDescriptorInstance(context,
3888 		TestParams	(VK_SHADER_STAGE_COMPUTE_BIT,
3889 					VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3890 					BINDING_StorageImage,
3891 					VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3892 					(BINDING_StorageImage + 1),
3893 					true,
3894 					performWritesInVertex(testCaseParams.descriptorType, context),
3895 					testCaseParams))
3896 	, m_buffer		()
3897 	, m_fillColor	(10)
3898 {
3899 }
3900 
updateDescriptors(IterateCommonVariables & variables)3901 void StorageImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3902 {
3903 	// update image at last index
3904 	{
3905 		VkDescriptorImageInfo		imageInfo =
3906 		{
3907 			static_cast<VkSampler>(0),
3908 			**variables.descriptorImageViews[variables.validDescriptorCount],
3909 			VK_IMAGE_LAYOUT_GENERAL
3910 		};
3911 
3912 		const VkWriteDescriptorSet writeInfo =
3913 		{
3914 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// sType
3915 			DE_NULL,									// pNext
3916 			*variables.descriptorSet,					// descriptorSet
3917 			m_testParams.additionalDescriptorBinding,	// descriptorBinding;
3918 			0,											// elementIndex
3919 			1u,											// descriptorCount
3920 			m_testParams.additionalDescriptorType,		// descriptorType
3921 			&imageInfo,									// pImageInfo
3922 			DE_NULL,									// pBufferInfo
3923 			DE_NULL										// pTexelBufferView
3924 		};
3925 
3926 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3927 	}
3928 
3929 	// update rest images
3930 	CommonDescriptorInstance::updateDescriptors(variables);
3931 }
3932 
createAndPopulateDescriptors(IterateCommonVariables & variables)3933 void StorageImageInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3934 {
3935 	const VkFormat				imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
3936 	const VkBufferUsageFlags	bufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3937 
3938 	// create descriptor buffer, images and views
3939 	{
3940 		const VkExtent3D			imageExtent = { 4, 4, 1 };
3941 
3942 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3943 			bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3944 
3945 		for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3946 		{
3947 			const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3948 			tcu::clear(pa, tcu::UVec4(m_fillColor));
3949 		}
3950 		vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3951 	}
3952 
3953 	// create additional image that will be used as index container
3954 	{
3955 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer,
3956 			bufferUsage, m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
3957 
3958 		// populate buffer
3959 		const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3960 		const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution, imageFormat, variables.descriptorsBufferInfos, m_buffer);
3961 		for (deUint32 y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
3962 		{
3963 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
3964 			{
3965 				const deUint32 component = primes[pixel % variables.validDescriptorCount];
3966 				pa.setPixel(tcu::UVec4(component), x, y);
3967 			}
3968 		}
3969 
3970 		// save changes
3971 		vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
3972 	}
3973 
3974 	// create views for all previously created images
3975 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
3976 }
3977 
iterate(void)3978 tcu::TestStatus StorageImageInstance::iterate						(void)
3979 {
3980 	IterateCommonVariables	v;
3981 	iterateCommandSetup		(v);
3982 	iterateCommandBegin		(v);
3983 
3984 	ut::UpdatablePixelBufferAccessPtr	programResult;
3985 	ut::UpdatablePixelBufferAccessPtr	referenceResult;
3986 
3987 	if (m_testParams.updateAfterBind)
3988 	{
3989 		updateDescriptors	(v);
3990 	}
3991 
3992 	copyBuffersToImages		(v);
3993 
3994 	m_vki.cmdDispatch		(*v.commandBuffer,
3995 							m_testParams.calculateInLoop ? 1 : v.renderArea.extent.width,
3996 							m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height,
3997 							1);
3998 
3999 	copyImagesToBuffers		(v);
4000 
4001 	iterateCommandEnd(v, programResult, referenceResult, false);
4002 
4003 	return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
4004 }
4005 
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)4006 void StorageImageInstance::iterateCollectResults					(ut::UpdatablePixelBufferAccessPtr&			result,
4007 																	 const IterateCommonVariables&				variables,
4008 																	 bool										fromTest)
4009 {
4010 	result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
4011 		vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
4012 	const PixelBufferAccess& dst = *result.get();
4013 
4014 	if (fromTest)
4015 	{
4016 		vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4017 		for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
4018 		{
4019 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
4020 			{
4021 				const deUint32 imageIdx = pixelNum % variables.validDescriptorCount;
4022 				const PixelBufferAccess src = getPixelAccess(imageIdx,
4023 					variables.descriptorsImages[imageIdx]->extent, variables.descriptorsImages[imageIdx]->format,
4024 					variables.descriptorsBufferInfos, variables.descriptorsBuffer);
4025 				dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
4026 			}
4027 		}
4028 	}
4029 	else
4030 	{
4031 		std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
4032 
4033 		for (deUint32 invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
4034 		{
4035 			++inc[invIdx % variables.validDescriptorCount];
4036 		}
4037 
4038 		for (deUint32 invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
4039 		{
4040 			const deUint32 row = invIdx / m_testParams.frameResolution.width;
4041 			const deUint32 col = invIdx % m_testParams.frameResolution.width;
4042 			const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
4043 			dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
4044 		}
4045 	}
4046 }
4047 
4048 class DescriptorIndexingTestCase : public TestCase
4049 {
4050 	const TestCaseParams m_testCaseParams;
4051 public:
DescriptorIndexingTestCase(tcu::TestContext & context,const char * name,const char * description,const TestCaseParams & testCaseParams)4052 	DescriptorIndexingTestCase (tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
4053 		: TestCase(context, name, description)
4054 		, m_testCaseParams(testCaseParams)
4055 	{
4056 	}
4057 
createInstance(vkt::Context & context) const4058 	vkt::TestInstance* createInstance (vkt::Context& context) const // override
4059 	{
4060 		switch (m_testCaseParams.descriptorType)
4061 		{
4062 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4063 			return new StorageBufferInstance		(context, m_testCaseParams);
4064 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4065 			return new UniformBufferInstance		(context, m_testCaseParams);
4066 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4067 			return new StorageTexelInstance			(context, m_testCaseParams);
4068 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4069 			return new UniformTexelInstance			(context, m_testCaseParams);
4070 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4071 			return new DynamicStorageBufferInstance	(context, m_testCaseParams);
4072 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4073 			return new DynamicUniformBufferInstance	(context, m_testCaseParams);
4074 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4075 			return new InputAttachmentInstance		(context, m_testCaseParams);
4076 		case VK_DESCRIPTOR_TYPE_SAMPLER:
4077 			return new SamplerInstance				(context, m_testCaseParams);
4078 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4079 			return new SampledImageInstance			(context, m_testCaseParams);
4080 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4081 			return new CombinedImageInstance		(context, m_testCaseParams);
4082 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4083 			return new StorageImageInstance			(context, m_testCaseParams);
4084 		default:
4085 			TCU_THROW(InternalError, "Unknown Descriptor Type");
4086 		}
4087 		return DE_NULL;
4088 	}
4089 
checkSupport(vkt::Context & context) const4090 	virtual void checkSupport (vkt::Context& context) const
4091 	{
4092 		context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
4093 
4094 		const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& feats = context.getDescriptorIndexingFeatures();
4095 
4096 		switch (m_testCaseParams.descriptorType)
4097 		{
4098 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4099 			if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4100 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
4101 
4102 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
4103 				TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
4104 			break;
4105 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4106 			if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4107 				TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
4108 
4109 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
4110 				TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
4111 			break;
4112 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4113 			if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
4114 				TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
4115 
4116 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
4117 				TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
4118 			break;
4119 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4120 			if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
4121 				TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
4122 
4123 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
4124 				TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
4125 			break;
4126 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4127 			if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4128 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
4129 
4130 			if (m_testCaseParams.updateAfterBind)
4131 				TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
4132 			break;
4133 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4134 			if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4135 				TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
4136 
4137 			if (m_testCaseParams.updateAfterBind)
4138 				TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
4139 			break;
4140 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4141 			if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
4142 				TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
4143 
4144 			if (m_testCaseParams.updateAfterBind)
4145 				TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
4146 			break;
4147 		case VK_DESCRIPTOR_TYPE_SAMPLER:
4148 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4149 				TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
4150 
4151 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4152 				TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
4153 			break;
4154 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4155 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4156 				TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
4157 
4158 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4159 				TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
4160 			break;
4161 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4162 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4163 				TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
4164 
4165 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4166 				TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
4167 			break;
4168 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4169 			if (!(feats.shaderStorageImageArrayNonUniformIndexing))
4170 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
4171 
4172 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
4173 				TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
4174 			break;
4175 		default:
4176 			DE_FATAL("Unknown Descriptor Type");
4177 			break;
4178 		}
4179 	}
4180 
initAsmPrograms(SourceCollections & programCollection) const4181 	void initAsmPrograms(SourceCollections&	programCollection) const
4182 	{
4183 
4184 		std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderAsm;
4185 
4186 		deUint32 vulkan_version = VK_MAKE_VERSION(1, 2, 0);
4187 		vk::SpirvVersion spirv_version = vk::SPIRV_VERSION_1_4;
4188 		vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
4189 
4190 		if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4191 		{
4192 			programCollection.spirvAsmSources.add(
4193 				ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4194 				<< (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false);
4195 
4196 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4197 			{
4198 				programCollection.spirvAsmSources.add(
4199 					ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4200 					<< (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true);
4201 			}
4202 		}
4203 		if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4204 		{
4205 			programCollection.spirvAsmSources.add(
4206 				ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4207 				<< (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false);
4208 
4209 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4210 			{
4211 				programCollection.spirvAsmSources.add(
4212 					ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4213 					<< (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true);
4214 			}
4215 		}
4216 		if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4217 		{
4218 			programCollection.spirvAsmSources.add(
4219 				ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4220 				<< (*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false);
4221 		}
4222 	}
4223 
initPrograms(SourceCollections & programCollection) const4224 	virtual void initPrograms (SourceCollections& programCollection) const
4225 	{
4226 		if (m_testCaseParams.minNonUniform) {
4227 			initAsmPrograms(programCollection);
4228 			return;
4229 		}
4230 
4231 		std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
4232 
4233 		if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4234 		{
4235 			programCollection.glslSources.add(
4236 				ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4237 				<< glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
4238 
4239 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4240 			{
4241 				programCollection.glslSources.add(
4242 					ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4243 					<< glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
4244 			}
4245 		}
4246 		if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4247 		{
4248 			programCollection.glslSources.add(
4249 				ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4250 				<< glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
4251 
4252 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4253 			{
4254 				programCollection.glslSources.add(
4255 					ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4256 					<< glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
4257 			}
4258 		}
4259 		if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4260 		{
4261 			programCollection.glslSources.add(
4262 				ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4263 				<< glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
4264 		}
4265 	}
4266 };
4267 
4268 } // - unnamed namespace
4269 
descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup * group)4270 void descriptorIndexingDescriptorSetsCreateTests (tcu::TestCaseGroup* group)
4271 {
4272 	struct TestCaseInfo
4273 	{
4274 		const char*		name;
4275 		const char*		description;
4276 		TestCaseParams	params;
4277 	};
4278 
4279 	tcu::TestContext&				context(group->getTestContext());
4280 
4281 	TestCaseInfo casesAfterBindAndLoop[] =
4282 	{
4283 		{
4284 			"storage_buffer", "Regular Storage Buffer Descriptors",
4285 			{
4286 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4287 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4288 				RESOLUTION,
4289 				false,	// updateAfterBind
4290 				false,	// calculateInLoop
4291 				false,	// useMipMaps
4292 				false,	// minNonUniform
4293 				FUZZY_COMPARE, CMP_THRESHOLD
4294 			}
4295 		},
4296 		{
4297 			"storage_texel_buffer", "Storage Texel Buffer Descriptors",
4298 			{
4299 				VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4300 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4301 				RESOLUTION,
4302 				false,	// updateAfterBind
4303 				false,	// calculateInLoop
4304 				false,	// useMipMaps
4305 				false,	// minNonUniform
4306 				FUZZY_COMPARE, CMP_THRESHOLD
4307 			}
4308 		},
4309 		{
4310 			"uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4311 			{
4312 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4313 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4314 				RESOLUTION,
4315 				false,	// updateAfterBind,
4316 				false,	// calculateInLoop
4317 				false,	// usesMipMaps
4318 				false,	// minNonUniform
4319 				FUZZY_COMPARE, CMP_THRESHOLD
4320 			}
4321 		},
4322 		{
4323 			"storage_image", "Storage Image Descriptors",
4324 			{
4325 				VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4326 				VK_SHADER_STAGE_COMPUTE_BIT,
4327 				RESOLUTION,
4328 				false,	// updateAfterBind
4329 				false,	// calculateInLoop
4330 				false,	// useMipMaps
4331 				false,	// minNonUniform
4332 				FUZZY_COMPARE, CMP_THRESHOLD
4333 			}
4334 		},
4335 	};
4336 
4337 	for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4338 	{
4339 		for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4340 		{
4341 			for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
4342 			{
4343 				TestCaseInfo&	info			(casesAfterBindAndLoop[caseIdx]);
4344 				std::string		caseName		(info.name);
4345 				std::string		caseDescription	(info.description);
4346 				TestCaseParams	params			(info.params);
4347 
4348 				caseName				+= (updateAfterBind	? "_after_bind"	: "");
4349 				caseName				+= (calculateInLoop	? "_in_loop"	: "");
4350 
4351 				caseDescription			+= (updateAfterBind	? " After Bind"	: "");
4352 				caseDescription			+= (calculateInLoop ? " In Loop"	: "");
4353 
4354 				params.updateAfterBind	= updateAfterBind	? true			: false;
4355 				params.calculateInLoop	= calculateInLoop	? true			: false;
4356 
4357 				group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4358 			}
4359 		}
4360 	}
4361 
4362 	TestCaseInfo casesAfterBindAndLoopAndLOD[] =
4363 	{
4364 		{
4365 			"sampler", "Sampler Descriptors",
4366 			{
4367 				VK_DESCRIPTOR_TYPE_SAMPLER,
4368 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4369 				RESOLUTION,
4370 				false,	// updateAfterBind
4371 				false,	// calculateInLoop
4372 				false,	// usesMipMaps
4373 				false,	// minNonUniform
4374 				FUZZY_COMPARE, CMP_THRESHOLD
4375 			}
4376 		},
4377 		{
4378 			"sampled_image", "Sampled Image Descriptors",
4379 			{
4380 				VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
4381 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4382 				RESOLUTION,
4383 				false,	// updateAfterBind
4384 				false,	// calculateInLoop
4385 				false,	// usesMipMaps
4386 				false,	// minNonUniform
4387 				FUZZY_COMPARE, CMP_THRESHOLD
4388 			}
4389 		},
4390 		{
4391 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4392 			{
4393 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4394 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4395 				RESOLUTION,
4396 				false,	// updateAfterBind
4397 				false,	// calculateInLoop
4398 				false,	// usesMipMaps
4399 				false,	// minNonUniform
4400 				FUZZY_COMPARE, CMP_THRESHOLD
4401 			}
4402 		},
4403 	};
4404 
4405 	for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4406 	{
4407 		for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4408 		{
4409 			for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4410 			{
4411 				for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoopAndLOD); ++caseIdx)
4412 				{
4413 					TestCaseInfo&	info			(casesAfterBindAndLoopAndLOD[caseIdx]);
4414 					std::string		caseName		(info.name);
4415 					std::string		caseDescription	(info.description);
4416 					TestCaseParams	params			(info.params);
4417 
4418 					caseName				+= (updateAfterBind	? "_after_bind"	: "");
4419 					caseName				+= (calculateInLoop ? "_in_loop"	: "");
4420 					caseName				+= (usesMipMaps		? "_with_lod"	: "");
4421 
4422 					caseDescription			+= (updateAfterBind	? " After Bind"	: "");
4423 					caseDescription			+= (calculateInLoop	? " In Loop"	: "");
4424 					caseDescription			+= (usesMipMaps		? " Use LOD"	: "");
4425 
4426 					params.updateAfterBind	= updateAfterBind	? true			: false;
4427 					params.calculateInLoop	= calculateInLoop	? true			: false;
4428 					params.usesMipMaps		= usesMipMaps		? true			: false;
4429 
4430 					group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4431 				}
4432 			}
4433 		}
4434 	}
4435 
4436 	TestCaseInfo casesNonAfterBindAndLoop[] =
4437 	{
4438 		{
4439 			"uniform_buffer", "Regular Uniform Buffer Descriptors",
4440 			{
4441 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4442 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4443 				RESOLUTION,
4444 				false,	// updateAfterBind
4445 				false,	// calculateInLoop
4446 				false,	// usesMipMaps
4447 				false,	// minNonUniform
4448 				FUZZY_COMPARE, CMP_THRESHOLD
4449 			}
4450 		},
4451 		{
4452 			"storage_buffer_dynamic", "Dynamic Storage Buffer Descriptors",
4453 			{
4454 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
4455 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4456 				RESOLUTION,
4457 				false,	// updateAfterBind
4458 				false,	// calculateInLoop
4459 				false,	// useMipMaps
4460 				false,	// minNonUniform
4461 				FUZZY_COMPARE, CMP_THRESHOLD
4462 			}
4463 		},
4464 		{
4465 			"uniform_buffer_dynamic", "Dynamic Uniform Buffer Descriptors",
4466 			{
4467 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
4468 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4469 				RESOLUTION,
4470 				false,	// updateAfterBind
4471 				false,	// calculateInLoop
4472 				false,	// useMipMaps
4473 				false,	// minNonUniform
4474 				FUZZY_COMPARE, CMP_THRESHOLD
4475 			}
4476 		},
4477 		{
4478 			"input_attachment", "Input Attachment Descriptors",
4479 			{
4480 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
4481 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4482 				RESOLUTION,
4483 				false,	// updateAfterBind
4484 				false,	// calculateInLoop
4485 				false,	// useMipMaps
4486 				false,	// minNonUniform
4487 				FUZZY_COMPARE, CMP_THRESHOLD
4488 			}
4489 		},
4490 	};
4491 
4492 	for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4493 	{
4494 		for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesNonAfterBindAndLoop); ++caseIdx)
4495 		{
4496 			TestCaseInfo&	info(casesNonAfterBindAndLoop[caseIdx]);
4497 			std::string		caseName(info.name);
4498 			std::string		caseDescription(info.description);
4499 			TestCaseParams	params(info.params);
4500 
4501 			caseName				+= (calculateInLoop	? "_in_loop"	: "");
4502 
4503 			caseDescription			+= (calculateInLoop ? " In Loop"	: "");
4504 
4505 			params.calculateInLoop	= calculateInLoop	? true			: false;
4506 
4507 			group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4508 		}
4509 	}
4510 
4511 	// SPIR-V Asm Tests
4512 	// Tests that have the minimum necessary NonUniform decorations.
4513 	// sampler and sampled_image GLSL already have minimum NonUniform decorations.
4514 
4515 	TestCaseInfo casesMinNonUniform[] =
4516 	{
4517 		{
4518 			"storage_buffer", "Regular Storage Buffer Descriptors",
4519 			{
4520 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4521 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4522 				RESOLUTION,
4523 				false,	// updateAfterBind
4524 				false,	// calculateInLoop
4525 				false,	// useMipMaps
4526 				true,	// minNonUniform
4527 				FUZZY_COMPARE, CMP_THRESHOLD
4528 			}
4529 		},
4530 		{
4531 			"storage_texel_buffer", "Storage Texel Buffer Descriptors",
4532 			{
4533 				VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4534 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4535 				RESOLUTION,
4536 				false,	// updateAfterBind
4537 				false,	// calculateInLoop
4538 				false,	// useMipMaps
4539 				true,	// minNonUniform
4540 				FUZZY_COMPARE, CMP_THRESHOLD
4541 			}
4542 		},
4543 		{
4544 			"uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4545 			{
4546 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4547 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4548 				RESOLUTION,
4549 				false,	// updateAfterBind,
4550 				false,	// calculateInLoop
4551 				false,	// usesMipMaps
4552 				true,	// minNonUniform
4553 				FUZZY_COMPARE, CMP_THRESHOLD
4554 			}
4555 		},
4556 		{
4557 			"uniform_buffer", "Regular Uniform Buffer Descriptors",
4558 			{
4559 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4560 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4561 				RESOLUTION,
4562 				false,	// updateAfterBind
4563 				false,	// calculateInLoop
4564 				false,	// usesMipMaps
4565 				true,	// minNonUniform
4566 				FUZZY_COMPARE, CMP_THRESHOLD
4567 			}
4568 		},
4569 		{
4570 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4571 			{
4572 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4573 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4574 				RESOLUTION,
4575 				false,	// updateAfterBind
4576 				false,	// calculateInLoop
4577 				false,	// usesMipMaps
4578 				true,	// minNonUniform
4579 				FUZZY_COMPARE, CMP_THRESHOLD
4580 			}
4581 		},
4582 		{
4583 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4584 			{
4585 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4586 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4587 				RESOLUTION,
4588 				false,	// updateAfterBind
4589 				false,	// calculateInLoop
4590 				true,	// usesMipMaps
4591 				true,	// minNonUniform
4592 				FUZZY_COMPARE, CMP_THRESHOLD
4593 			}
4594 		},
4595 		{
4596 			"storage_image", "Storage Image Descriptors",
4597 			{
4598 				VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4599 				VK_SHADER_STAGE_COMPUTE_BIT,
4600 				RESOLUTION,
4601 				false,	// updateAfterBind
4602 				false,	// calculateInLoop
4603 				false,	// useMipMaps
4604 				true,	// minNonUniform
4605 				FUZZY_COMPARE, CMP_THRESHOLD
4606 			}
4607 		},
4608 	};
4609 
4610 	for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesMinNonUniform); ++caseIdx)
4611 	{
4612 		TestCaseInfo&	info(casesMinNonUniform[caseIdx]);
4613 		std::string		caseName(info.name);
4614 		std::string		caseDescription(info.description);
4615 		TestCaseParams	params(info.params);
4616 
4617 		if (params.usesMipMaps) {
4618 			caseName += "_with_lod";
4619 		}
4620 		caseName += "_minNonUniform";
4621 
4622 		caseDescription += " With Minimum NonUniform Decorations";
4623 
4624 		TestCase* tc = new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params);
4625 		group->addChild(tc);
4626 		// group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4627 	}
4628 }
4629 
4630 } // - DescriptorIndexing
4631 } // - vkt
4632