• 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::__anon5df221fd0111::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::__anon5df221fd0111::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 			}
2221 			break;
2222 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2223 			switch (testCaseParams.descriptorType)
2224 			{
2225 				case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2226 					s << "               OpCapability Shader\n";
2227 					if (testCaseParams.usesMipMaps)
2228 					{
2229 						s << "               OpCapability ImageQuery\n";
2230 					}
2231 					s << "               OpCapability ShaderNonUniform\n";
2232 					s << "               OpCapability RuntimeDescriptorArray\n";
2233 					s << "               OpCapability SampledImageArrayNonUniformIndexing\n";
2234 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2235 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2236 					s << "               OpMemoryModel Logical GLSL450\n";
2237 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2238 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2239 					s << "               OpSource GLSL 450\n";
2240 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2241 					s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2242 					s << "               OpName %main \"main\"\n";
2243 					s << "               OpName %FragColor \"FragColor\"\n";
2244 					s << "               OpName %data \"data\"\n";
2245 					s << "               OpName %rIndex \"rIndex\"\n";
2246 					s << "               OpName %position \"position\"\n";
2247 					s << "               OpName %normalpos \"normalpos\"\n";
2248 					s << "               OpName %vIndex \"vIndex\"\n";
2249 					s << "               OpName %gIndex \"gIndex\"\n";
2250 					s << "               OpName %bIndex \"bIndex\"\n";
2251 					s << "               OpName %aIndex \"aIndex\"\n";
2252 					s << "               OpDecorate %FragColor Location 0\n";
2253 					s << "               OpDecorate %data DescriptorSet 0\n";
2254 					s << "               OpDecorate %data Binding 7\n";
2255 					s << "               OpDecorate %rIndex Flat\n";
2256 					s << "               OpDecorate %rIndex Location 3\n";
2257 					// s << "               OpDecorate %19 NonUniform\n";
2258 					// s << "               OpDecorate %21 NonUniform\n";
2259 					s << "               OpDecorate %22 NonUniform\n";
2260 					if (testCaseParams.usesMipMaps)
2261 					{
2262 						// s << "               OpDecorate %27 NonUniform\n";
2263 						// s << "               OpDecorate %28 NonUniform\n";
2264 						// s << "               OpDecorate %29 NonUniform\n";
2265 						s << "               OpDecorate %30 NonUniform\n";
2266 					}
2267 					s << "               OpDecorate %position Flat\n";
2268 					s << "               OpDecorate %position Location 0\n";
2269 					s << "               OpDecorate %normalpos Flat\n";
2270 					s << "               OpDecorate %normalpos Location 1\n";
2271 					s << "               OpDecorate %vIndex Flat\n";
2272 					s << "               OpDecorate %vIndex Location 2\n";
2273 					s << "               OpDecorate %gIndex Flat\n";
2274 					s << "               OpDecorate %gIndex Location 4\n";
2275 					s << "               OpDecorate %bIndex Flat\n";
2276 					s << "               OpDecorate %bIndex Location 5\n";
2277 					s << "               OpDecorate %aIndex Flat\n";
2278 					s << "               OpDecorate %aIndex Location 6\n";
2279 					s << "       %void = OpTypeVoid\n";
2280 					s << "          %3 = OpTypeFunction %void\n";
2281 					s << "      %float = OpTypeFloat 32\n";
2282 					s << "    %v4float = OpTypeVector %float 4\n";
2283 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2284 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2285 					s << "         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
2286 					s << "         %11 = OpTypeSampledImage %10\n";
2287 					s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2288 					s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2289 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2290 					s << "        %int = OpTypeInt 32 1\n";
2291 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2292 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2293 					s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2294 					s << "    %v2float = OpTypeVector %float 2\n";
2295 					s << "    %float_0 = OpConstant %float 0\n";
2296 					s << "      %int_1 = OpConstant %int 1\n";
2297 					s << "         %25 = OpConstantComposite %v2float %float_0 %float_0\n";
2298 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2299 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2300 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2301 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2302 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2303 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2304 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2305 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2306 					s << "       %main = OpFunction %void None %3\n";
2307 					s << "          %5 = OpLabel\n";
2308 					s << "         %18 = OpLoad %int %rIndex\n";
2309 					s << "         %19 = OpCopyObject %int %18\n";
2310 					s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2311 					s << "         %22 = OpLoad %11 %21\n";
2312 					if (testCaseParams.usesMipMaps)
2313 					{
2314 						s << "          %26 = OpLoad %int %rIndex\n";
2315 						s << "          %27 = OpCopyObject %int %26\n";
2316 						s << "          %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
2317 						s << "          %29 = OpLoad %11 %28\n";
2318 						s << "          %30 = OpImage %10 %29\n";
2319 						s << "          %31 = OpImageQueryLevels %int %30\n";
2320 						s << "          %33 = OpISub %int %31 %int_1\n";
2321 						s << "          %34 = OpConvertSToF %float %33\n";
2322 						s << "          %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
2323 						s << "                OpStore %FragColor %35\n";
2324 					}
2325 					else
2326 					{
2327 						s << "         %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
2328 						s << "               OpStore %FragColor %26\n";
2329 					}
2330 					s << "               OpReturn\n";
2331 					s << "               OpFunctionEnd\n";
2332 					break;
2333 				case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2334 					s << "               OpCapability Shader\n";
2335 					s << "               OpCapability SampledBuffer\n";
2336 					s << "               OpCapability ShaderNonUniform\n";
2337 					s << "               OpCapability RuntimeDescriptorArray\n";
2338 					s << "               OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
2339 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2340 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2341 					s << "               OpMemoryModel Logical GLSL450\n";
2342 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2343 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2344 					s << "               OpSource GLSL 450\n";
2345 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2346 					s << "               OpSourceExtension \"GL_EXT_texture_buffer\"\n";
2347 					s << "               OpName %main \"main\"\n";
2348 					s << "               OpName %FragColor \"FragColor\"\n";
2349 					s << "               OpName %data \"data\"\n";
2350 					s << "               OpName %rIndex \"rIndex\"\n";
2351 					s << "               OpName %position \"position\"\n";
2352 					s << "               OpName %normalpos \"normalpos\"\n";
2353 					s << "               OpName %vIndex \"vIndex\"\n";
2354 					s << "               OpName %gIndex \"gIndex\"\n";
2355 					s << "               OpName %bIndex \"bIndex\"\n";
2356 					s << "               OpName %aIndex \"aIndex\"\n";
2357 					s << "               OpDecorate %FragColor Location 0\n";
2358 					s << "               OpDecorate %data DescriptorSet 0\n";
2359 					s << "               OpDecorate %data Binding 3\n";
2360 					s << "               OpDecorate %rIndex Flat\n";
2361 					s << "               OpDecorate %rIndex Location 3\n";
2362 					// s << "               OpDecorate %19 NonUniform\n";
2363 					// s << "               OpDecorate %21 NonUniform\n";
2364 					// s << "               OpDecorate %22 NonUniform\n";
2365 					s << "               OpDecorate %24 NonUniform\n";
2366 					s << "               OpDecorate %position Flat\n";
2367 					s << "               OpDecorate %position Location 0\n";
2368 					s << "               OpDecorate %normalpos Flat\n";
2369 					s << "               OpDecorate %normalpos Location 1\n";
2370 					s << "               OpDecorate %vIndex Flat\n";
2371 					s << "               OpDecorate %vIndex Location 2\n";
2372 					s << "               OpDecorate %gIndex Flat\n";
2373 					s << "               OpDecorate %gIndex Location 4\n";
2374 					s << "               OpDecorate %bIndex Flat\n";
2375 					s << "               OpDecorate %bIndex Location 5\n";
2376 					s << "               OpDecorate %aIndex Flat\n";
2377 					s << "               OpDecorate %aIndex Location 6\n";
2378 					s << "       %void = OpTypeVoid\n";
2379 					s << "          %3 = OpTypeFunction %void\n";
2380 					s << "      %float = OpTypeFloat 32\n";
2381 					s << "    %v4float = OpTypeVector %float 4\n";
2382 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2383 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2384 					s << "         %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
2385 					s << "         %11 = OpTypeSampledImage %10\n";
2386 					s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
2387 					s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
2388 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
2389 					s << "        %int = OpTypeInt 32 1\n";
2390 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2391 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2392 					s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
2393 					s << "      %int_0 = OpConstant %int 0\n";
2394 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2395 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2396 					s << "    %v2float = OpTypeVector %float 2\n";
2397 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2398 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2399 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2400 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2401 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2402 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2403 					s << "       %main = OpFunction %void None %3\n";
2404 					s << "          %5 = OpLabel\n";
2405 					s << "         %18 = OpLoad %int %rIndex\n";
2406 					s << "         %19 = OpCopyObject %int %18\n";
2407 					s << "         %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
2408 					s << "         %22 = OpLoad %11 %21\n";
2409 					s << "         %24 = OpImage %10 %22\n";
2410 					s << "         %25 = OpImageFetch %v4float %24 %int_0\n";
2411 					s << "               OpStore %FragColor %25\n";
2412 					s << "               OpReturn\n";
2413 					s << "               OpFunctionEnd\n";
2414 					break;
2415 				case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2416 					s << "               OpCapability Shader\n";
2417 					s << "               OpCapability ImageBuffer\n";
2418 					s << "               OpCapability ShaderNonUniform\n";
2419 					s << "               OpCapability RuntimeDescriptorArray\n";
2420 					s << "               OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
2421 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2422 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2423 					s << "               OpMemoryModel Logical GLSL450\n";
2424 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2425 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2426 					s << "               OpSource GLSL 450\n";
2427 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2428 					s << "               OpName %main \"main\"\n";
2429 					s << "               OpName %FragColor \"FragColor\"\n";
2430 					s << "               OpName %data \"data\"\n";
2431 					s << "               OpName %rIndex \"rIndex\"\n";
2432 					s << "               OpName %position \"position\"\n";
2433 					s << "               OpName %normalpos \"normalpos\"\n";
2434 					s << "               OpName %vIndex \"vIndex\"\n";
2435 					s << "               OpName %gIndex \"gIndex\"\n";
2436 					s << "               OpName %bIndex \"bIndex\"\n";
2437 					s << "               OpName %aIndex \"aIndex\"\n";
2438 					s << "               OpDecorate %FragColor Location 0\n";
2439 					s << "               OpDecorate %data DescriptorSet 0\n";
2440 					s << "               OpDecorate %data Binding 4\n";
2441 					s << "               OpDecorate %rIndex Flat\n";
2442 					s << "               OpDecorate %rIndex Location 3\n";
2443 					// s << "               OpDecorate %18 NonUniform\n";
2444 					// s << "               OpDecorate %20 NonUniform\n";
2445 					s << "               OpDecorate %21 NonUniform\n";
2446 					s << "               OpDecorate %position Flat\n";
2447 					s << "               OpDecorate %position Location 0\n";
2448 					s << "               OpDecorate %normalpos Flat\n";
2449 					s << "               OpDecorate %normalpos Location 1\n";
2450 					s << "               OpDecorate %vIndex Flat\n";
2451 					s << "               OpDecorate %vIndex Location 2\n";
2452 					s << "               OpDecorate %gIndex Flat\n";
2453 					s << "               OpDecorate %gIndex Location 4\n";
2454 					s << "               OpDecorate %bIndex Flat\n";
2455 					s << "               OpDecorate %bIndex Location 5\n";
2456 					s << "               OpDecorate %aIndex Flat\n";
2457 					s << "               OpDecorate %aIndex Location 6\n";
2458 					s << "       %void = OpTypeVoid\n";
2459 					s << "          %3 = OpTypeFunction %void\n";
2460 					s << "      %float = OpTypeFloat 32\n";
2461 					s << "    %v4float = OpTypeVector %float 4\n";
2462 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2463 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2464 					s << "         %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
2465 					s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2466 					s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2467 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2468 					s << "        %int = OpTypeInt 32 1\n";
2469 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2470 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2471 					s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2472 					s << "      %int_0 = OpConstant %int 0\n";
2473 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2474 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2475 					s << "    %v2float = OpTypeVector %float 2\n";
2476 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2477 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2478 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2479 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2480 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2481 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2482 					s << "       %main = OpFunction %void None %3\n";
2483 					s << "          %5 = OpLabel\n";
2484 					s << "         %17 = OpLoad %int %rIndex\n";
2485 					s << "         %18 = OpCopyObject %int %17\n";
2486 					s << "         %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
2487 					s << "         %21 = OpLoad %10 %20\n";
2488 					s << "         %23 = OpImageRead %v4float %21 %int_0\n";
2489 					s << "               OpStore %FragColor %23\n";
2490 					s << "               OpReturn\n";
2491 					s << "               OpFunctionEnd\n";
2492 					break;
2493 				case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2494 					s << "               OpCapability Shader\n";
2495 					s << "               OpCapability ShaderNonUniform\n";
2496 					s << "               OpCapability RuntimeDescriptorArray\n";
2497 					s << "               OpCapability StorageBufferArrayNonUniformIndexing\n";
2498 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2499 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2500 					s << "               OpMemoryModel Logical GLSL450\n";
2501 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2502 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2503 					s << "               OpSource GLSL 450\n";
2504 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2505 					s << "               OpName %main \"main\"\n";
2506 					s << "               OpName %FragColor \"FragColor\"\n";
2507 					s << "               OpName %Data \"Data\"\n";
2508 					s << "               OpMemberName %Data 0 \"cnew\"\n";
2509 					s << "               OpMemberName %Data 1 \"cold\"\n";
2510 					s << "               OpName %data \"data\"\n";
2511 					s << "               OpName %rIndex \"rIndex\"\n";
2512 					s << "               OpName %position \"position\"\n";
2513 					s << "               OpName %normalpos \"normalpos\"\n";
2514 					s << "               OpName %vIndex \"vIndex\"\n";
2515 					s << "               OpName %gIndex \"gIndex\"\n";
2516 					s << "               OpName %bIndex \"bIndex\"\n";
2517 					s << "               OpName %aIndex \"aIndex\"\n";
2518 					s << "               OpDecorate %FragColor Location 0\n";
2519 					s << "               OpMemberDecorate %Data 0 Offset 0\n";
2520 					s << "               OpMemberDecorate %Data 1 Offset 16\n";
2521 					s << "               OpDecorate %Data Block\n";
2522 					s << "               OpDecorate %data DescriptorSet 0\n";
2523 					s << "               OpDecorate %data Binding 2\n";
2524 					s << "               OpDecorate %rIndex Flat\n";
2525 					s << "               OpDecorate %rIndex Location 3\n";
2526 					// s << "               OpDecorate %18 NonUniform\n";
2527 					s << "               OpDecorate %21 NonUniform\n";
2528 					// s << "               OpDecorate %22 NonUniform\n";
2529 					s << "               OpDecorate %position Flat\n";
2530 					s << "               OpDecorate %position Location 0\n";
2531 					s << "               OpDecorate %normalpos Flat               OpDecorate %normalpos Location 1\n";
2532 					s << "               OpDecorate %vIndex Flat\n";
2533 					s << "               OpDecorate %vIndex Location 2\n";
2534 					s << "               OpDecorate %gIndex Flat\n";
2535 					s << "               OpDecorate %gIndex Location 4\n";
2536 					s << "               OpDecorate %bIndex Flat\n";
2537 					s << "               OpDecorate %bIndex Location 5\n";
2538 					s << "               OpDecorate %aIndex Flat\n";
2539 					s << "               OpDecorate %aIndex Location 6\n";
2540 					s << "       %void = OpTypeVoid\n";
2541 					s << "          %3 = OpTypeFunction %void\n";
2542 					s << "      %float = OpTypeFloat 32\n";
2543 					s << "    %v4float = OpTypeVector %float 4\n";
2544 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2545 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2546 					s << "       %Data = OpTypeStruct %v4float %v4float\n";
2547 					s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2548 					s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
2549 					s << "       %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
2550 					s << "        %int = OpTypeInt 32 1\n";
2551 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2552 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2553 					s << "      %int_1 = OpConstant %int 1\n";
2554 					s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
2555 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2556 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2557 					s << "    %v2float = OpTypeVector %float 2\n";
2558 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2559 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2560 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2561 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2562 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2563 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2564 					s << "       %main = OpFunction %void None %3\n";
2565 					s << "          %5 = OpLabel\n";
2566 					s << "         %17 = OpLoad %int %rIndex\n";
2567 					s << "         %18 = OpCopyObject %int %17\n";
2568 					s << "         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
2569 					s << "         %22 = OpLoad %v4float %21\n";
2570 					s << "               OpStore %FragColor %22\n";
2571 					s << "               OpReturn\n";
2572 					s << "               OpFunctionEnd\n";
2573 					break;
2574 				case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2575 					s << "               OpCapability Shader\n";
2576 					s << "               OpCapability ShaderNonUniform\n";
2577 					s << "               OpCapability RuntimeDescriptorArray\n";
2578 					s << "               OpCapability UniformBufferArrayNonUniformIndexing\n";
2579 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2580 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2581 					s << "               OpMemoryModel Logical GLSL450\n";
2582 					s << "               OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
2583 					s << "               OpExecutionMode %main OriginUpperLeft\n";
2584 					s << "               OpSource GLSL 450\n";
2585 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2586 					s << "               OpName %main \"main\"\n";
2587 					s << "               OpName %FragColor \"FragColor\"\n";
2588 					s << "               OpName %Data \"Data\"\n";
2589 					s << "               OpMemberName %Data 0 \"c\"\n";
2590 					s << "               OpName %data \"data\"\n";
2591 					s << "               OpName %rIndex \"rIndex\"\n";
2592 					s << "               OpName %position \"position\"\n";
2593 					s << "               OpName %normalpos \"normalpos\"\n";
2594 					s << "               OpName %vIndex \"vIndex\"\n";
2595 					s << "               OpName %gIndex \"gIndex\"\n";
2596 					s << "               OpName %bIndex \"bIndex\"\n";
2597 					s << "               OpName %aIndex \"aIndex\"\n";
2598 					s << "               OpDecorate %FragColor Location 0\n";
2599 					s << "               OpMemberDecorate %Data 0 Offset 0\n";
2600 					s << "               OpDecorate %Data Block\n";
2601 					s << "               OpDecorate %data DescriptorSet 0\n";
2602 					s << "               OpDecorate %data Binding 1\n";
2603 					s << "               OpDecorate %rIndex Flat\n";
2604 					s << "               OpDecorate %rIndex Location 3\n";
2605 					// s << "               OpDecorate %18 NonUniform\n";
2606 					s << "               OpDecorate %21 NonUniform\n";
2607 					// s << "               OpDecorate %22 NonUniform\n";
2608 					s << "               OpDecorate %position Flat\n";
2609 					s << "               OpDecorate %position Location 0\n";
2610 					s << "               OpDecorate %normalpos Flat\n";
2611 					s << "               OpDecorate %normalpos Location 1\n";
2612 					s << "               OpDecorate %vIndex Flat\n";
2613 					s << "               OpDecorate %vIndex Location 2\n";
2614 					s << "               OpDecorate %gIndex Flat\n";
2615 					s << "               OpDecorate %gIndex Location 4\n";
2616 					s << "               OpDecorate %bIndex Flat\n";
2617 					s << "               OpDecorate %bIndex Location 5\n";
2618 					s << "               OpDecorate %aIndex Flat\n";
2619 					s << "               OpDecorate %aIndex Location 6\n";
2620 					s << "       %void = OpTypeVoid\n";
2621 					s << "          %3 = OpTypeFunction %void\n";
2622 					s << "      %float = OpTypeFloat 32\n";
2623 					s << "    %v4float = OpTypeVector %float 4\n";
2624 					s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
2625 					s << "  %FragColor = OpVariable %_ptr_Output_v4float Output\n";
2626 					s << "       %Data = OpTypeStruct %v4float\n";
2627 					s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
2628 					s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
2629 					s << "       %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
2630 					s << "        %int = OpTypeInt 32 1\n";
2631 					s << "%_ptr_Input_int = OpTypePointer Input %int\n";
2632 					s << "     %rIndex = OpVariable %_ptr_Input_int Input\n";
2633 					s << "      %int_0 = OpConstant %int 0\n";
2634 					s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
2635 					s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
2636 					s << "   %position = OpVariable %_ptr_Input_v4float Input\n";
2637 					s << "    %v2float = OpTypeVector %float 2\n";
2638 					s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
2639 					s << "  %normalpos = OpVariable %_ptr_Input_v2float Input\n";
2640 					s << "     %vIndex = OpVariable %_ptr_Input_int Input\n";
2641 					s << "     %gIndex = OpVariable %_ptr_Input_int Input\n";
2642 					s << "     %bIndex = OpVariable %_ptr_Input_int Input\n";
2643 					s << "     %aIndex = OpVariable %_ptr_Input_int Input\n";
2644 					s << "       %main = OpFunction %void None %3\n";
2645 					s << "          %5 = OpLabel\n";
2646 					s << "         %17 = OpLoad %int %rIndex\n";
2647 					s << "         %18 = OpCopyObject %int %17\n";
2648 					s << "         %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
2649 					s << "         %22 = OpLoad %v4float %21\n";
2650 					s << "               OpStore %FragColor %22\n";
2651 					s << "               OpReturn\n";
2652 					s << "               OpFunctionEnd\n";
2653 					break;
2654 				default:
2655 					TCU_THROW(InternalError, "Unexpected descriptor type");
2656 			}
2657 		    break;
2658 		case VK_SHADER_STAGE_COMPUTE_BIT:
2659 			switch (testCaseParams.descriptorType)
2660 			{
2661 				case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2662 					s << "               OpCapability Shader\n";
2663 					s << "               OpCapability ShaderNonUniform\n";
2664 					s << "               OpCapability RuntimeDescriptorArray\n";
2665 					s << "               OpCapability StorageImageArrayNonUniformIndexing\n";
2666 					s << "               OpExtension \"SPV_EXT_descriptor_indexing\"\n";
2667 					s << "          %1 = OpExtInstImport \"GLSL.std.450\"\n";
2668 					s << "               OpMemoryModel Logical GLSL450\n";
2669 					s << "               OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
2670 					s << "               OpExecutionMode %main LocalSize 1 1 1\n";
2671 					s << "               OpSource GLSL 450\n";
2672 					s << "               OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
2673 					s << "               OpName %main \"main\"\n";
2674 					s << "               OpName %c \"c\"\n";
2675 					s << "               OpName %idxs \"idxs\"\n";
2676 					s << "               OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
2677 					s << "               OpName %data \"data\"\n";
2678 					s << "               OpDecorate %idxs DescriptorSet 0\n";
2679 					s << "               OpDecorate %idxs Binding 12\n";
2680 					s << "               OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
2681 					s << "               OpDecorate %data DescriptorSet 0\n";
2682 					s << "               OpDecorate %data Binding 11\n";
2683 					// s << "               OpDecorate %36 NonUniform\n";
2684 					// s << "               OpDecorate %37 NonUniform\n";
2685 					s << "               OpDecorate %41 NonUniform\n";
2686 					s << "               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
2687 					s << "       %void = OpTypeVoid\n";
2688 					s << "          %3 = OpTypeFunction %void\n";
2689 					s << "       %uint = OpTypeInt 32 0\n";
2690 					s << "     %v4uint = OpTypeVector %uint 4\n";
2691 					s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
2692 					s << "         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
2693 					s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
2694 					s << "       %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
2695 					s << "     %v3uint = OpTypeVector %uint 3\n";
2696 					s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
2697 					s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
2698 					s << "     %uint_0 = OpConstant %uint 0\n";
2699 					s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
2700 					s << "        %int = OpTypeInt 32 1\n";
2701 					s << "     %uint_1 = OpConstant %uint 1\n";
2702 					s << "      %v2int = OpTypeVector %int 2\n";
2703 					s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
2704 					s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
2705 					s << "       %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
2706 					s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
2707 					s << "      %int_0 = OpConstant %int 0\n";
2708 					s << "         %39 = OpConstantComposite %v2int %int_0 %int_0\n";
2709 					s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
2710 					s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
2711 					s << "       %main = OpFunction %void None %3\n";
2712 					s << "          %5 = OpLabel\n";
2713 					s << "          %c = OpVariable %_ptr_Function_v4uint Function\n";
2714 					s << "         %13 = OpLoad %10 %idxs\n";
2715 					s << "         %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
2716 					s << "         %20 = OpLoad %uint %19\n";
2717 					s << "         %22 = OpBitcast %int %20\n";
2718 					s << "         %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
2719 					s << "         %25 = OpLoad %uint %24\n";
2720 					s << "         %26 = OpBitcast %int %25\n";
2721 					s << "         %28 = OpCompositeConstruct %v2int %22 %26\n";
2722 					s << "         %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
2723 					s << "               OpStore %c %29\n";
2724 					s << "         %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
2725 					s << "         %35 = OpLoad %uint %34\n";
2726 					s << "         %36 = OpCopyObject %uint %35\n";
2727 					s << "         %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
2728 					s << "         %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
2729 					s << "         %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
2730 					s << "               OpReturn\n";
2731 					s << "               OpFunctionEnd\n";
2732 					break;
2733 				default:
2734 					TCU_THROW(InternalError, "Unexpected descriptor type");
2735 			}
2736 			break;
2737 		default:
2738 			TCU_THROW(InternalError, "Unexpected stage");
2739 	}
2740 
2741 	return s.str();
2742 }
2743 
getShaderSource(VkShaderStageFlagBits shaderType,const TestCaseParams & testCaseParams,bool allowVertexStoring)2744 std::string CommonDescriptorInstance::getShaderSource				(VkShaderStageFlagBits						shaderType,
2745 																	 const TestCaseParams&						testCaseParams,
2746 																	 bool										allowVertexStoring)
2747 {
2748 	std::stringstream	s;
2749 
2750 	s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
2751 	s << "#extension GL_EXT_nonuniform_qualifier : require	\n";
2752 
2753 	if (testCaseParams.calculateInLoop)
2754 	{
2755 		s << "layout(push_constant)     uniform Block { int lowerBound, upperBound; } pc;\n";
2756 		s << substBinding(BINDING_DescriptorEnumerator,
2757 			"layout(set=1,binding=${?}) uniform isamplerBuffer iter;	\n");
2758 	}
2759 
2760 	switch (testCaseParams.descriptorType)
2761 	{
2762 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2763 			s << substBinding(BINDING_StorageBuffer,
2764 				"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2765 			break;
2766 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2767 			s << substBinding(BINDING_StorageBufferDynamic,
2768 				"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
2769 			break;
2770 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2771 			s << substBinding(BINDING_UniformBuffer,
2772 				"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2773 			break;
2774 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2775 			s << substBinding(BINDING_UniformBufferDynamic,
2776 				"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
2777 			break;
2778 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2779 			s << substBinding(BINDING_StorageTexelBuffer,
2780 				"layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
2781 			break;
2782 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2783 			s << "#extension GL_EXT_texture_buffer : require	\n";
2784 			s << substBinding(BINDING_UniformTexelBuffer,
2785 				"layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
2786 			break;
2787 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2788 			// Left for the consistent of code.
2789 			// Header is set one swicth below
2790 			break;
2791 		case VK_DESCRIPTOR_TYPE_SAMPLER:
2792 			s << "#extension GL_EXT_texture_buffer : require	\n";
2793 			s << substBinding(BINDING_SampledImage,
2794 				"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
2795 			s << substBinding(BINDING_Sampler,
2796 				"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
2797 			break;
2798 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2799 			s << "#extension GL_EXT_texture_buffer : require	\n";
2800 			s << substBinding(BINDING_Sampler,
2801 				"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
2802 			s << substBinding(BINDING_SampledImage,
2803 				"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
2804 			break;
2805 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2806 			s << "#extension GL_EXT_texture_buffer : require	\n";
2807 			s << substBinding(BINDING_CombinedImageSampler,
2808 				"layout(set=0,binding=${?}) uniform sampler2D data[];\n");
2809 			break;
2810 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2811 			s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in;	\n";
2812 			s << substBinding(BINDING_StorageImage + 1,
2813 				"layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs;	\n");
2814 			s << substBinding(BINDING_StorageImage,
2815 				"layout(r32ui,set=0,binding=${?}) uniform uimage2D data[];	\n");
2816 			break;
2817 		default:
2818 			TCU_THROW(InternalError, "Not implemented descriptor type");
2819 	}
2820 
2821 	switch (shaderType)
2822 	{
2823 		case VK_SHADER_STAGE_VERTEX_BIT:	s << getVertexShaderProlog();	break;
2824 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2825 			{
2826 				if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
2827 				{
2828 					s << substBinding(BINDING_InputAttachment,
2829 						"layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[];	\n");
2830 				}
2831 				s << getFragmentShaderProlog();
2832 			}
2833 			break;
2834 		case VK_SHADER_STAGE_COMPUTE_BIT:
2835 			break;
2836 		default:
2837 			TCU_THROW(InternalError, "Not implemented shader stage");
2838 	}
2839 
2840 	switch (shaderType)
2841 	{
2842 		case VK_SHADER_STAGE_VERTEX_BIT:
2843 		{
2844 			switch (testCaseParams.descriptorType)
2845 			{
2846 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2847 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2848 				if (allowVertexStoring)
2849 					s << "  if (gIndex != 0) data[nonuniformEXT(gIndex)].cnew = data[nonuniformEXT(rIndex)].cold;	\n";
2850 				break;
2851 			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2852 				if (allowVertexStoring)
2853 					s << "  if (gIndex != 0) imageStore(data[nonuniformEXT(gIndex)], 1, imageLoad(data[nonuniformEXT(rIndex)], 0));	\n";
2854 				break;
2855 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2856 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2857 			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2858 			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2859 			case VK_DESCRIPTOR_TYPE_SAMPLER:
2860 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2861 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2862 				break;
2863 
2864 			default:
2865 				TCU_THROW(InternalError, "Not implemented descriptor type");
2866 			}
2867 		}
2868 		break;
2869 
2870 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2871 		{
2872 			switch (testCaseParams.descriptorType)
2873 			{
2874 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2875 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2876 			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2877 				{
2878 					if (testCaseParams.calculateInLoop)
2879 						s << getFragmentLoopSource(
2880 							getColorAccess(testCaseParams.descriptorType, "rIndex", false),
2881 							getColorAccess(testCaseParams.descriptorType, "loopIdx", false));
2882 					else
2883 						s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", false));
2884 				}
2885 				break;
2886 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2887 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2888 			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2889 			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2890 			case VK_DESCRIPTOR_TYPE_SAMPLER:
2891 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2892 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2893 				if (testCaseParams.calculateInLoop)
2894 					s << getFragmentLoopSource(
2895 						getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps),
2896 						getColorAccess(testCaseParams.descriptorType, "loopIdx", testCaseParams.usesMipMaps));
2897 				else
2898 					s << getFragmentReturnSource(getColorAccess(testCaseParams.descriptorType, "rIndex", testCaseParams.usesMipMaps));
2899 				break;
2900 			default:	TCU_THROW(InternalError, "Not implemented descriptor type");
2901 			}
2902 		}
2903 		break;
2904 
2905 		case VK_SHADER_STAGE_COMPUTE_BIT: // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
2906 			s << "void main(void)\n{\n";
2907 			if (testCaseParams.calculateInLoop)
2908 				s << "  for (int i = pc.lowerBound; i < pc.upperBound; ++i)	\n"
2909 					"    imageAtomicAdd(data[nonuniformEXT(texelFetch(iter, i).x)], ivec2(0, 0), 1);			\n";
2910 			else
2911 				s << "  uvec4 c = imageLoad(idxs, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y));	\n"
2912 					"  imageAtomicAdd( data[nonuniformEXT(c.r)], ivec2(0, 0), 1);								\n";
2913 			break;
2914 
2915 		default:	TCU_THROW(InternalError, "Not implemented shader stage");
2916 	}
2917 
2918 	s << getShaderEpilog();
2919 
2920 	return s.str();
2921 }
2922 
2923 class StorageBufferInstance : virtual public CommonDescriptorInstance
2924 {
2925 public:
2926 								StorageBufferInstance				(Context&									context,
2927 																	 const TestCaseParams&						testCaseParams);
2928 protected:
2929 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
2930 
2931 	virtual bool				verifyVertexWriteResults			(IterateCommonVariables&					variables);
2932 };
2933 
StorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)2934 StorageBufferInstance::StorageBufferInstance						(Context&									context,
2935 																	 const TestCaseParams&						testCaseParams)
2936 	: CommonDescriptorInstance(context,
2937 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
2938 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2939 			BINDING_StorageBuffer,
2940 			VK_DESCRIPTOR_TYPE_UNDEFINED,
2941 			BINDING_Undefined,
2942 			false,
2943 			performWritesInVertex(testCaseParams.descriptorType, context),
2944 			testCaseParams))
2945 {
2946 }
2947 
createAndPopulateDescriptors(IterateCommonVariables & variables)2948 void StorageBufferInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
2949 {
2950 	BindingStorageBuffer::Data	data;
2951 
2952 	bool						vertexStores = false;
2953 	{
2954 		ut::DeviceProperties dp(m_context);
2955 		vertexStores = dp.physicalDeviceFeatures().vertexPipelineStoresAndAtomics != DE_FALSE;
2956 	}
2957 	const deUint32				alignment	= static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minStorageBufferOffsetAlignment);
2958 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2959 
2960 	unsigned char*				buffer		= static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2961 	for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
2962 	{
2963 		const float				component	= m_colorScheme[infoIdx % m_schemeSize];
2964 		const tcu::Vec4			color		(component, component, component, 1.0f);
2965 		VkDescriptorBufferInfo& info		= variables.descriptorsBufferInfos[infoIdx];
2966 		data.cnew							= vertexStores ? m_clearColor : color;
2967 		data.cold							= color;
2968 
2969 		deMemcpy(buffer + info.offset, &data, sizeof(data));
2970 	}
2971 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
2972 
2973 	variables.dataAlignment = deAlign64(sizeof(data), alignment);
2974 }
2975 
verifyVertexWriteResults(IterateCommonVariables & variables)2976 bool StorageBufferInstance::verifyVertexWriteResults				(IterateCommonVariables&					variables)
2977 {
2978 	const tcu::Vec4				threshold		(0.002f, 0.002f, 0.002f, 0.002f);
2979 	const std::vector<deUint32>	primes			= ut::generatePrimes(variables.availableDescriptorCount);
2980 
2981 	unsigned char*				buffer = static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
2982 	BindingStorageBuffer::Data	data;
2983 	for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
2984 	{
2985 		const deUint32			prime		= primes[primeIdx];
2986 		const float				component	= m_colorScheme[(prime % variables.validDescriptorCount) % m_schemeSize];
2987 		const tcu::Vec4			referenceValue(component, component, component, 1.0f);
2988 
2989 		VkDescriptorBufferInfo& info = variables.descriptorsBufferInfos[primeIdx];
2990 		deMemcpy(&data, buffer + info.offset, sizeof(data));
2991 		const tcu::Vec4			realValue = data.cnew;
2992 
2993 		const tcu::Vec4			diff = tcu::absDiff(referenceValue, realValue);
2994 		if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
2995 			return false;
2996 	}
2997 	return true;
2998 }
2999 
3000 class UniformBufferInstance : virtual public CommonDescriptorInstance
3001 {
3002 public:
3003 								UniformBufferInstance				(Context&									context,
3004 																	 const TestCaseParams&						testCaseParams);
3005 protected:
3006 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3007 };
3008 
UniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3009 UniformBufferInstance::UniformBufferInstance						(Context&									context,
3010 																	 const TestCaseParams&						testCaseParams)
3011 	: CommonDescriptorInstance(context,
3012 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3013 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3014 			BINDING_UniformBuffer,
3015 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3016 			BINDING_Undefined,
3017 			false,
3018 			performWritesInVertex(testCaseParams.descriptorType, context),
3019 			testCaseParams))
3020 {
3021 }
3022 
createAndPopulateDescriptors(IterateCommonVariables & variables)3023 void UniformBufferInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3024 {
3025 	BindingUniformBuffer::Data data;
3026 
3027 	const deUint32				alignment	= static_cast<deUint32>(ut::DeviceProperties(m_context).physicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
3028 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, sizeof(data), alignment, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
3029 
3030 	unsigned char*				buffer		= static_cast<unsigned char*>(variables.descriptorsBuffer->alloc->getHostPtr());
3031 	for (deUint32 infoIdx = 0; infoIdx < variables.validDescriptorCount; ++infoIdx)
3032 	{
3033 		const float				component	= m_colorScheme[infoIdx % m_schemeSize];
3034 		VkDescriptorBufferInfo& info		= variables.descriptorsBufferInfos[infoIdx];
3035 		data.c								= tcu::Vec4(component, component, component, 1.0f);
3036 		deMemcpy(buffer + info.offset, &data, sizeof(data));
3037 	}
3038 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3039 
3040 	variables.dataAlignment = deAlign64(sizeof(data), alignment);
3041 }
3042 
3043 class StorageTexelInstance : public CommonDescriptorInstance
3044 {
3045 public:
3046 								StorageTexelInstance				(Context&									context,
3047 																	 const TestCaseParams&						testCaseParams);
3048 private:
3049 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3050 
3051 	virtual bool				verifyVertexWriteResults			(IterateCommonVariables&					variables);
3052 };
3053 
StorageTexelInstance(Context & context,const TestCaseParams & testCaseParams)3054 StorageTexelInstance::StorageTexelInstance							(Context&									context,
3055 																	 const TestCaseParams&						testCaseParams)
3056 	: CommonDescriptorInstance(context,
3057 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3058 			VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
3059 			BINDING_StorageTexelBuffer,
3060 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3061 			BINDING_Undefined,
3062 			false,
3063 			performWritesInVertex(testCaseParams.descriptorType, context),
3064 			testCaseParams))
3065 {
3066 }
3067 
createAndPopulateDescriptors(IterateCommonVariables & variables)3068 void StorageTexelInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3069 {
3070 	const VkExtent3D			imageExtent			= { 4, 4, 1 };
3071 	const deUint32				imageSize			= ut::computeImageSize(imageExtent, m_colorFormat);
3072 
3073 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
3074 	createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3075 
3076 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3077 	{
3078 		const float				component			= m_colorScheme[imageIdx % m_schemeSize];
3079 		const PixelBufferAccess pa					= getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3080 
3081 		tcu::clear(pa, m_clearColor);
3082 		pa.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3083 	}
3084 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3085 }
3086 
verifyVertexWriteResults(IterateCommonVariables & variables)3087 bool StorageTexelInstance::verifyVertexWriteResults(IterateCommonVariables&					variables)
3088 {
3089 	const VkExtent3D			imageExtent		= { 4, 4, 1 };
3090 	const tcu::Vec4				threshold		(0.002f, 0.002f, 0.002f, 0.002f);
3091 	const std::vector<deUint32>	primes			= ut::generatePrimes(variables.availableDescriptorCount);
3092 
3093 	for (deUint32 primeIdx = 0; primeIdx < variables.validDescriptorCount; ++primeIdx)
3094 	{
3095 		const deUint32			prime		= primes[primeIdx];
3096 		const float				component	= m_colorScheme[( prime % variables.validDescriptorCount ) % m_schemeSize];
3097 		const tcu::Vec4			referenceValue(component, component, component, 1.0f);
3098 
3099 		const PixelBufferAccess pa			= getPixelAccess(primeIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3100 		const tcu::Vec4			realValue	= pa.getPixel(1, 0);
3101 
3102 		const tcu::Vec4			diff		= tcu::absDiff(referenceValue, realValue);
3103 		if (!tcu::boolAll(tcu::lessThanEqual(diff, threshold)))
3104 			return false;
3105 	}
3106 	return true;
3107 }
3108 
3109 class UniformTexelInstance : public CommonDescriptorInstance
3110 {
3111 public:
3112 								UniformTexelInstance				(Context&									context,
3113 																	 const TestCaseParams&						testCaseParams);
3114 private:
3115 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3116 };
3117 
UniformTexelInstance(Context & context,const TestCaseParams & testCaseParams)3118 UniformTexelInstance::UniformTexelInstance							(Context&									context,
3119 																	 const TestCaseParams&						testCaseParams)
3120 	: CommonDescriptorInstance(context,
3121 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3122 			VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
3123 			BINDING_UniformTexelBuffer,
3124 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3125 			BINDING_Undefined,
3126 			false,
3127 			performWritesInVertex(testCaseParams.descriptorType, context),
3128 			testCaseParams))
3129 {
3130 }
3131 
createAndPopulateDescriptors(IterateCommonVariables & variables)3132 void UniformTexelInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3133 {
3134 	const VkExtent3D			imageExtent	= { 4, 4, 1 };
3135 	const deUint32				imageSize	= ut::computeImageSize(imageExtent, m_colorFormat);
3136 
3137 	createBuffers(variables.descriptorsBufferInfos, variables.descriptorsBuffer, variables.validDescriptorCount, imageSize, sizeof(tcu::Vec4), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
3138 	createBuffersViews(variables.descriptorsBufferViews, variables.descriptorsBufferInfos, m_colorFormat);
3139 
3140 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3141 	{
3142 		const float				component	= m_colorScheme[imageIdx % m_schemeSize];
3143 		const PixelBufferAccess	pa			= getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3144 
3145 		tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3146 	}
3147 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3148 }
3149 
3150 class DynamicBuffersInstance : virtual public CommonDescriptorInstance
3151 {
3152 public:
DynamicBuffersInstance(Context & context,const TestParams & testParams)3153 	DynamicBuffersInstance											(Context&									context,
3154 																	 const TestParams&							testParams)
3155 		: CommonDescriptorInstance(context, testParams) {}
3156 
3157 protected:
3158 	virtual tcu::TestStatus		iterate								(void);
3159 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3160 };
3161 
updateDescriptors(IterateCommonVariables & variables)3162 void DynamicBuffersInstance::updateDescriptors						(IterateCommonVariables&					variables)
3163 {
3164 	DE_ASSERT(variables.dataAlignment);
3165 
3166 	VkDescriptorBufferInfo	bufferInfo =
3167 	{
3168 		*variables.descriptorsBuffer.get()->buffer,
3169 		0,	// always 0, it will be taken from pDynamicOffsets
3170 		variables.dataAlignment
3171 	};
3172 
3173 	VkWriteDescriptorSet updateInfo =
3174 	{
3175 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3176 		DE_NULL,										// pNext
3177 		*variables.descriptorSet,						// descriptorSet
3178 		m_testParams.descriptorBinding,					// descriptorBinding;
3179 		0,	// to be set in below loop					// dstArrayElement
3180 		1u,												// descriptorCount
3181 		m_testParams.descriptorType,					// descriptorType
3182 		DE_NULL,										// pImageInfo
3183 		&bufferInfo,									// pBufferInfo
3184 		DE_NULL											// pTexelBufferView
3185 	};
3186 
3187 	deUint32 descIdx = 0;
3188 	const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
3189 	for (deUint32 validIdx = 0; validIdx < variables.validDescriptorCount; ++validIdx)
3190 	{
3191 		for (; descIdx < primes[validIdx]; ++descIdx)
3192 		{
3193 			updateInfo.dstArrayElement			= descIdx;
3194 			m_vki.updateDescriptorSets	(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3195 		}
3196 
3197 		updateInfo.dstArrayElement				= primes[validIdx];
3198 		m_vki.updateDescriptorSets		(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3199 
3200 		++descIdx;
3201 	}
3202 	for (; descIdx < variables.availableDescriptorCount; ++descIdx)
3203 	{
3204 		updateInfo.dstArrayElement = descIdx;
3205 		m_vki.updateDescriptorSets(m_vkd, 1u, &updateInfo, 0u, DE_NULL);
3206 	}
3207 }
3208 
iterate(void)3209 tcu::TestStatus	DynamicBuffersInstance::iterate						(void)
3210 {
3211 	IterateCommonVariables	v;
3212 	iterateCommandSetup		(v);
3213 
3214 	ut::UpdatablePixelBufferAccessPtr	programResult;
3215 	ut::UpdatablePixelBufferAccessPtr	referenceResult;
3216 	bool firstPass = true;
3217 
3218 	DE_ASSERT(v.dataAlignment);
3219 
3220 	std::vector<deUint32> dynamicOffsets;
3221 
3222 	deUint32 descIdx = 0;
3223 	const std::vector<deUint32> primes = ut::generatePrimes(v.availableDescriptorCount);
3224 	for (deUint32 validIdx = 0; validIdx < v.validDescriptorCount; ++validIdx)
3225 	{
3226 		for (; descIdx < primes[validIdx]; ++descIdx)
3227 		{
3228 			dynamicOffsets.push_back(0);
3229 		}
3230 
3231 		dynamicOffsets.push_back(static_cast<deUint32>(validIdx * v.dataAlignment));
3232 
3233 		++descIdx;
3234 	}
3235 	for (; descIdx < v.availableDescriptorCount; ++descIdx)
3236 	{
3237 		dynamicOffsets.push_back(0);
3238 	}
3239 
3240 	// Unfortunatelly not lees and not more, only exactly
3241 	DE_ASSERT(dynamicOffsets.size() == v.availableDescriptorCount);
3242 
3243 	const VkDescriptorSet	descriptorSets[] = { *v.descriptorSet };
3244 
3245 	v.renderArea.extent.width	= m_testParams.frameResolution.width/4;
3246 	v.renderArea.extent.height	= m_testParams.frameResolution.height/4;
3247 
3248 	for (int x = 0; x < 4; x++)
3249 		for (int y= 0; y < 4; y++)
3250 		{
3251 
3252 			v.renderArea.offset.x		= x * m_testParams.frameResolution.width/4;
3253 			v.renderArea.offset.y		= y * m_testParams.frameResolution.height/4;
3254 
3255 			iterateCommandBegin		(v, firstPass);
3256 			firstPass = false;
3257 
3258 	m_vki.cmdBindDescriptorSets(
3259 		*v.commandBuffer,						// commandBuffer
3260 		VK_PIPELINE_BIND_POINT_GRAPHICS,		// pipelineBindPoint
3261 		*v.pipelineLayout,						// layout
3262 		0u,										// firstSet
3263 		DE_LENGTH_OF_ARRAY(descriptorSets),		// descriptorSetCount
3264 		descriptorSets,							// pDescriptorSets
3265 		v.availableDescriptorCount,				// dynamicOffsetCount
3266 		dynamicOffsets.data());					// pDynamicOffsets
3267 
3268 			vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
3269 	m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
3270 
3271 	vk::beginRenderPass	(m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
3272 			m_vki.cmdDraw			(*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
3273 	vk::endRenderPass	(m_vki, *v.commandBuffer);
3274 
3275 			iterateCommandEnd(v, programResult, referenceResult);
3276 			programResult->invalidate();
3277 		}
3278 
3279 	return (iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
3280 }
3281 
3282 class DynamicStorageBufferInstance : public DynamicBuffersInstance, public StorageBufferInstance
3283 {
3284 public:
3285 	DynamicStorageBufferInstance									(Context&					context,
3286 																	 const TestCaseParams&		testCaseParams);
3287 	tcu::TestStatus		iterate										(void);
3288 	void				createAndPopulateDescriptors				(IterateCommonVariables&	variables);
3289 	void				updateDescriptors							(IterateCommonVariables&	variables);
3290 	bool				verifyVertexWriteResults					(IterateCommonVariables&	variables);
3291 };
3292 
DynamicStorageBufferInstance(Context & context,const TestCaseParams & testCaseParams)3293 DynamicStorageBufferInstance::DynamicStorageBufferInstance			(Context&					context,
3294 																	 const TestCaseParams&		testCaseParams)
3295 	: CommonDescriptorInstance(context,
3296 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3297 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
3298 			BINDING_StorageBufferDynamic,
3299 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3300 			BINDING_Undefined,
3301 			false,
3302 			performWritesInVertex(testCaseParams.descriptorType, context),
3303 			testCaseParams)),
3304 			DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
3305 {
3306 }
3307 
iterate(void)3308 tcu::TestStatus	DynamicStorageBufferInstance::iterate(void)
3309 {
3310 	return DynamicBuffersInstance::iterate();
3311 }
3312 
createAndPopulateDescriptors(IterateCommonVariables & variables)3313 void DynamicStorageBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&			variables)
3314 {
3315 	StorageBufferInstance::createAndPopulateDescriptors(variables);
3316 }
3317 
updateDescriptors(IterateCommonVariables & variables)3318 void DynamicStorageBufferInstance::updateDescriptors(IterateCommonVariables&					variables)
3319 {
3320 	DynamicBuffersInstance::updateDescriptors(variables);
3321 }
3322 
verifyVertexWriteResults(IterateCommonVariables & variables)3323 bool DynamicStorageBufferInstance::verifyVertexWriteResults(IterateCommonVariables&				variables)
3324 {
3325 	return StorageBufferInstance::verifyVertexWriteResults(variables);
3326 }
3327 
3328 class DynamicUniformBufferInstance : public DynamicBuffersInstance, public UniformBufferInstance
3329 {
3330 public:
3331 	DynamicUniformBufferInstance									(Context&					context,
3332 																	 const TestCaseParams&		testCaseParams);
3333 	tcu::TestStatus		iterate(void);
3334 	void				createAndPopulateDescriptors(IterateCommonVariables&					variables);
3335 	void				updateDescriptors(IterateCommonVariables&								variables);
3336 };
3337 
DynamicUniformBufferInstance(Context & context,const TestCaseParams & testCaseParams)3338 DynamicUniformBufferInstance::DynamicUniformBufferInstance			(Context&					context,
3339 																	 const TestCaseParams&		testCaseParams)
3340 	: CommonDescriptorInstance(context,
3341 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3342 			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
3343 			BINDING_UniformBufferDynamic,
3344 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3345 			BINDING_Undefined,
3346 			false,
3347 			performWritesInVertex(testCaseParams.descriptorType, context),
3348 			testCaseParams)),
3349 			DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
3350 {
3351 }
3352 
iterate(void)3353 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
3354 {
3355 	return DynamicBuffersInstance::iterate();
3356 }
3357 
createAndPopulateDescriptors(IterateCommonVariables & variables)3358 void DynamicUniformBufferInstance::createAndPopulateDescriptors(IterateCommonVariables&			variables)
3359 {
3360 	UniformBufferInstance::createAndPopulateDescriptors(variables);
3361 }
3362 
updateDescriptors(IterateCommonVariables & variables)3363 void DynamicUniformBufferInstance::updateDescriptors(IterateCommonVariables&					variables)
3364 {
3365 	DynamicBuffersInstance::updateDescriptors(variables);
3366 }
3367 
3368 class InputAttachmentInstance : public CommonDescriptorInstance
3369 {
3370 public:
3371 								InputAttachmentInstance				(Context&									context,
3372 																	const TestCaseParams&						testCaseParams);
3373 private:
3374 	virtual Move<VkRenderPass>	createRenderPass					(const IterateCommonVariables&				variables);
3375 	virtual void				createFramebuffer					(ut::FrameBufferSp&							frameBuffer,
3376 																	 VkRenderPass								renderPass,
3377 																	 const IterateCommonVariables&				variables);
3378 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3379 };
3380 
InputAttachmentInstance(Context & context,const TestCaseParams & testCaseParams)3381 InputAttachmentInstance::InputAttachmentInstance					(Context&									context,
3382 																	 const TestCaseParams&						testCaseParams)
3383 	: CommonDescriptorInstance(context,
3384 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3385 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
3386 			BINDING_InputAttachment,
3387 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3388 			BINDING_Undefined,
3389 			true,
3390 			performWritesInVertex(testCaseParams.descriptorType, context),
3391 			testCaseParams))
3392 {
3393 }
3394 
createAndPopulateDescriptors(IterateCommonVariables & variables)3395 void InputAttachmentInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3396 {
3397 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3398 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT, m_testParams.frameResolution, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3399 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3400 
3401 	for (deUint32 descriptorIdx = 0; descriptorIdx < variables.validDescriptorCount; ++descriptorIdx)
3402 	{
3403 		const float						component	= m_colorScheme[descriptorIdx % m_schemeSize];
3404 		const tcu::PixelBufferAccess	pa			= getPixelAccess(descriptorIdx, m_testParams.frameResolution, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3405 		tcu::clear(pa, tcu::Vec4(component, component, component, 1.0f));
3406 	}
3407 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3408 }
3409 
createRenderPass(const IterateCommonVariables & variables)3410 Move<VkRenderPass> InputAttachmentInstance::createRenderPass		(const IterateCommonVariables&				variables)
3411 {
3412 	std::vector<VkAttachmentDescription>	attachmentDescriptions;
3413 	std::vector<VkAttachmentReference>		inputAttachmentRefs;
3414 
3415 	const VkAttachmentDescription	colorAttachmentDescription =
3416 	{
3417 		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags;
3418 		m_colorFormat,								// VkFormat							format;
3419 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples;
3420 		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
3421 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
3422 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
3423 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
3424 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
3425 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout;
3426 	};
3427 	const VkAttachmentReference		colorAttachmentRef =
3428 	{
3429 		0u,												// deUint32							attachment;
3430 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout					layout;
3431 	};
3432 	attachmentDescriptions.push_back(colorAttachmentDescription);
3433 
3434 	// build input atachments
3435 	{
3436 		const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3437 		const deUint32 inputCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3438 		for (deUint32 inputIdx = 0; inputIdx < inputCount; ++inputIdx)
3439 		{
3440 			// primes holds the indices of input attachments for shader binding 10 which has input_attachment_index=1
3441 			deUint32 nextInputAttachmentIndex = primes[inputIdx] + 1;
3442 
3443 			// Fill up the subpass description's input attachments with unused attachments forming gaps to the next referenced attachment
3444 			for (deUint32 unusedIdx = static_cast<deUint32>(inputAttachmentRefs.size()); unusedIdx < nextInputAttachmentIndex; ++unusedIdx)
3445 			{
3446 				const VkAttachmentReference		inputAttachmentRef =
3447 				{
3448 					VK_ATTACHMENT_UNUSED,						// deUint32							attachment;
3449 					VK_IMAGE_LAYOUT_GENERAL						// VkImageLayout					layout;
3450 				};
3451 
3452 				inputAttachmentRefs.push_back(inputAttachmentRef);
3453 			}
3454 
3455 			const VkAttachmentDescription	inputAttachmentDescription =
3456 			{
3457 				VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,		// VkAttachmentDescriptionFlags		flags;
3458 				variables.descriptorsImages[inputIdx]->format,	// VkFormat							format;
3459 				VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits			samples;
3460 				VK_ATTACHMENT_LOAD_OP_LOAD,						// VkAttachmentLoadOp				loadOp;
3461 				VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp				storeOp;
3462 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp				stencilLoadOp;
3463 				VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp				stencilStoreOp;
3464 				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout					initialLayout;
3465 				VK_IMAGE_LAYOUT_GENERAL							// VkImageLayout					finalLayout;
3466 			};
3467 
3468 			const VkAttachmentReference		inputAttachmentRef =
3469 			{
3470 				inputIdx + 1,								// deUint32							attachment;
3471 				VK_IMAGE_LAYOUT_GENERAL						// VkImageLayout					layout;
3472 			};
3473 
3474 			inputAttachmentRefs.push_back(inputAttachmentRef);
3475 			attachmentDescriptions.push_back(inputAttachmentDescription);
3476 		}
3477 	}
3478 
3479 	const VkSubpassDescription		subpassDescription =
3480 	{
3481 		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
3482 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
3483 		static_cast<deUint32>(inputAttachmentRefs.size()),	// deUint32							inputAttachmentCount;
3484 		inputAttachmentRefs.data(),							// const VkAttachmentReference*		pInputAttachments;
3485 		1u,													// deUint32							colorAttachmentCount;
3486 		&colorAttachmentRef,								// const VkAttachmentReference*		pColorAttachments;
3487 		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
3488 		DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
3489 		0u,													// deUint32							preserveAttachmentCount;
3490 		DE_NULL												// const deUint32*					pPreserveAttachments;
3491 	};
3492 
3493 	const VkRenderPassCreateInfo	renderPassInfo =
3494 	{
3495 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
3496 		DE_NULL,												// const void*						pNext;
3497 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags;
3498 		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
3499 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments;
3500 		1u,														// deUint32							subpassCount;
3501 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses;
3502 		0u,														// deUint32							dependencyCount;
3503 		DE_NULL													// const VkSubpassDependency*		pDependencies;
3504 	};
3505 
3506 	return vk::createRenderPass(m_vki, m_vkd, &renderPassInfo);
3507 }
3508 
createFramebuffer(ut::FrameBufferSp & frameBuffer,VkRenderPass renderPass,const IterateCommonVariables & variables)3509 void InputAttachmentInstance::createFramebuffer						(ut::FrameBufferSp&							frameBuffer,
3510 																	 VkRenderPass								renderPass,
3511 																	 const IterateCommonVariables&				variables)
3512 {
3513 	std::vector<VkImageView>			inputAttachments;
3514 	const deUint32 viewCount = static_cast<deUint32>(variables.descriptorImageViews.size());
3515 	inputAttachments.resize(viewCount);
3516 	for (deUint32 viewIdx = 0; viewIdx < viewCount; ++viewIdx)
3517 	{
3518 		inputAttachments[viewIdx] = **variables.descriptorImageViews[viewIdx];
3519 	}
3520 	ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass, viewCount, inputAttachments.data());
3521 }
3522 
3523 class SamplerInstance : public CommonDescriptorInstance
3524 {
3525 public:
3526 								SamplerInstance						(Context&									context,
3527 																	 const TestCaseParams&						testCaseParams);
3528 private:
3529 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3530 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3531 };
3532 
SamplerInstance(Context & context,const TestCaseParams & testCaseParams)3533 SamplerInstance::SamplerInstance									(Context&									context,
3534 																	 const TestCaseParams&						testCaseParams)
3535 	: CommonDescriptorInstance(context,
3536 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3537 			VK_DESCRIPTOR_TYPE_SAMPLER,
3538 			BINDING_Sampler,
3539 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3540 			BINDING_SampledImage,
3541 			true,
3542 			performWritesInVertex(testCaseParams.descriptorType, context),
3543 			testCaseParams))
3544 {
3545 }
3546 
updateDescriptors(IterateCommonVariables & variables)3547 void SamplerInstance::updateDescriptors								(IterateCommonVariables&					variables)
3548 {
3549 	DE_ASSERT(variables.descriptorsImages.size()		== 1);
3550 	DE_ASSERT(variables.descriptorImageViews.size()		== 1);
3551 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 1);
3552 	DE_ASSERT(m_testParams.additionalDescriptorType		== VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
3553 	DE_ASSERT(variables.descriptorSamplers.size()		== variables.validDescriptorCount);
3554 
3555 	// update an image
3556 	{
3557 		const VkDescriptorImageInfo imageInfo =
3558 		{
3559 			static_cast<VkSampler>(0),
3560 			**variables.descriptorImageViews[0],
3561 			VK_IMAGE_LAYOUT_GENERAL
3562 		};
3563 
3564 		const VkWriteDescriptorSet writeInfo =
3565 		{
3566 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3567 			DE_NULL,										// pNext
3568 			*variables.descriptorSet,						// descriptorSet
3569 			BINDING_SampledImage,							// descriptorBinding;
3570 			0,												// elementIndex
3571 			1u,												// descriptorCount
3572 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				// descriptorType
3573 			&imageInfo,										// pImageInfo
3574 			DE_NULL,										// pBufferInfo
3575 			DE_NULL											// pTexelBufferView
3576 		};
3577 
3578 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3579 	}
3580 
3581 	// update samplers
3582 	CommonDescriptorInstance::updateDescriptors(variables);
3583 }
3584 
createAndPopulateDescriptors(IterateCommonVariables & variables)3585 void SamplerInstance::createAndPopulateDescriptors					(IterateCommonVariables&					variables)
3586 {
3587 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3588 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3589 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3590 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3591 
3592 	// create and populate an image
3593 	{
3594 		VkExtent3D imageExtent = m_testParams.frameResolution;
3595 		if (m_testParams.usesMipMaps)
3596 		{
3597 			imageExtent.width *= 2;
3598 			imageExtent.height *= 2;
3599 		}
3600 
3601 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3602 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1, m_testParams.usesMipMaps);
3603 		createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3604 
3605 		PixelBufferAccess pa = getPixelAccess(0, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, m_testParams.usesMipMaps ? 1 : 0);
3606 
3607 		for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
3608 		{
3609 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
3610 			{
3611 				const float		component	= m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
3612 				pa.setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
3613 			}
3614 		}
3615 
3616 		vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3617 	}
3618 
3619 	const tcu::Sampler sampler(
3620 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapS
3621 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapT
3622 		tcu::Sampler::CLAMP_TO_BORDER,															// wrapR
3623 		m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3624 		m_testParams.usesMipMaps ? tcu::Sampler::LINEAR_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3625 		0.0f,																					// lodTreshold
3626 		true);																					// normalizeCoords
3627 	const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3628 	variables.descriptorSamplers.resize(variables.validDescriptorCount);
3629 
3630 	for (deUint32 samplerIdx = 0; samplerIdx < variables.validDescriptorCount; ++samplerIdx)
3631 	{
3632 		variables.descriptorSamplers[samplerIdx] = ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo)));
3633 	}
3634 }
3635 
3636 class SampledImageInstance : public CommonDescriptorInstance
3637 {
3638 public:
3639 								SampledImageInstance				(Context&									context,
3640 																	 const TestCaseParams&						testCaseParams);
3641 private:
3642 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3643 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3644 };
3645 
SampledImageInstance(Context & context,const TestCaseParams & testCaseParams)3646 SampledImageInstance::SampledImageInstance							(Context&									context,
3647 																	 const TestCaseParams&						testCaseParams)
3648 	: CommonDescriptorInstance(context,
3649 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3650 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
3651 			BINDING_SampledImage,
3652 			VK_DESCRIPTOR_TYPE_SAMPLER,
3653 			BINDING_Sampler,
3654 			true,
3655 			performWritesInVertex(testCaseParams.descriptorType, context),
3656 			testCaseParams))
3657 {
3658 }
3659 
updateDescriptors(IterateCommonVariables & variables)3660 void SampledImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3661 {
3662 	DE_ASSERT(variables.descriptorSamplers.size()		== 1);
3663 	DE_ASSERT(variables.descriptorsImages.size()		== variables.validDescriptorCount);
3664 	DE_ASSERT(variables.descriptorImageViews.size()		== variables.validDescriptorCount);
3665 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== variables.validDescriptorCount);
3666 
3667 	// update a sampler
3668 	{
3669 		const VkDescriptorImageInfo samplerInfo =
3670 		{
3671 			**variables.descriptorSamplers[0],
3672 			static_cast<VkImageView>(0),
3673 			static_cast<VkImageLayout>(0)
3674 		};
3675 
3676 		const VkWriteDescriptorSet writeInfo =
3677 		{
3678 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3679 			DE_NULL,										// pNext
3680 			*variables.descriptorSet,						// descriptorSet
3681 			BINDING_Sampler,								// descriptorBinding;
3682 			0,												// elementIndex
3683 			1u,												// descriptorCount
3684 			VK_DESCRIPTOR_TYPE_SAMPLER,						// descriptorType
3685 			&samplerInfo,									// pImageInfo
3686 			DE_NULL,										// pBufferInfo
3687 			DE_NULL											// pTexelBufferView
3688 		};
3689 
3690 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3691 	}
3692 
3693 	// update images
3694 	CommonDescriptorInstance::updateDescriptors(variables);
3695 }
3696 
createAndPopulateDescriptors(IterateCommonVariables & variables)3697 void SampledImageInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3698 {
3699 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3700 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3701 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3702 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3703 
3704 	// create an only one sampler for all images
3705 	{
3706 		const tcu::Sampler sampler(
3707 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapS
3708 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapT
3709 			tcu::Sampler::CLAMP_TO_BORDER,																// wrapR
3710 			m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3711 			m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3712 			0.0f,																						// lodTreshold
3713 			true);																						// normalizeCoords
3714 		const VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3715 		variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3716 	}
3717 
3718 	const VkExtent3D&			imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3719 
3720 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3721 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT, imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3722 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3723 
3724 	PixelBufferAccess			pixelAccess;
3725 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3726 	{
3727 		const float				component	= m_colorScheme[imageIdx % m_schemeSize];
3728 
3729 		if (m_testParams.usesMipMaps)
3730 		{
3731 			const deUint32 mipCount = ut::computeMipMapCount(imageExtent);
3732 			DE_ASSERT(mipCount >= 2);
3733 			for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3734 			{
3735 				pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3736 				tcu::clear(pixelAccess, m_clearColor);
3737 			}
3738 
3739 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3740 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3741 		}
3742 		else
3743 		{
3744 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3745 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3746 		}
3747 	}
3748 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3749 }
3750 
3751 class CombinedImageInstance : public CommonDescriptorInstance
3752 {
3753 public:
3754 								CombinedImageInstance				(Context&									context,
3755 																	 const TestCaseParams&						testCaseParams);
3756 private:
3757 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3758 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3759 };
3760 
CombinedImageInstance(Context & context,const TestCaseParams & testCaseParams)3761 CombinedImageInstance::CombinedImageInstance						(Context&									context,
3762 																	 const TestCaseParams&						testCaseParams)
3763 	: CommonDescriptorInstance(context,
3764 		TestParams(VK_SHADER_STAGE_ALL_GRAPHICS,
3765 			testCaseParams.descriptorType,
3766 			BINDING_CombinedImageSampler,
3767 			VK_DESCRIPTOR_TYPE_UNDEFINED,
3768 			BINDING_Undefined,
3769 			true,
3770 			performWritesInVertex(testCaseParams.descriptorType),
3771 			testCaseParams))
3772 {
3773 }
3774 
updateDescriptors(IterateCommonVariables & variables)3775 void CombinedImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3776 {
3777 	const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3778 	const deUint32				primeCount = static_cast<deUint32>(primes.size());
3779 
3780 	DE_ASSERT(variables.descriptorSamplers.size()		== 1);
3781 	DE_ASSERT(variables.descriptorsImages.size()		== primeCount);
3782 	DE_ASSERT(variables.descriptorImageViews.size()		== primeCount);
3783 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== primeCount);
3784 
3785 	for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
3786 	{
3787 		const VkDescriptorImageInfo imageInfo =
3788 		{
3789 			**variables.descriptorSamplers[0],
3790 			**variables.descriptorImageViews[primeIdx],
3791 			VK_IMAGE_LAYOUT_GENERAL
3792 		};
3793 
3794 		const VkWriteDescriptorSet writeInfo =
3795 		{
3796 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// sType
3797 			DE_NULL,										// pNext
3798 			*variables.descriptorSet,						// descriptorSet
3799 			BINDING_CombinedImageSampler,					// descriptorBinding;
3800 			primes[primeIdx],								// elementIndex
3801 			1u,												// descriptorCount
3802 			m_testParams.descriptorType,					// descriptorType
3803 			&imageInfo,										// pImageInfo
3804 			DE_NULL,										// pBufferInfo
3805 			DE_NULL											// pTexelBufferView
3806 		};
3807 
3808 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3809 	}
3810 }
3811 
createAndPopulateDescriptors(IterateCommonVariables & variables)3812 void CombinedImageInstance::createAndPopulateDescriptors			(IterateCommonVariables&					variables)
3813 {
3814 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3815 	DE_ASSERT(variables.descriptorsImages.size()		== 0);
3816 	DE_ASSERT(variables.descriptorImageViews.size()		== 0);
3817 	DE_ASSERT(variables.descriptorsBufferInfos.size()	== 0);
3818 	DE_ASSERT(variables.descriptorSamplers.size()		== 0);
3819 
3820 	const tcu::Sampler sampler(
3821 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapS
3822 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapT
3823 		tcu::Sampler::CLAMP_TO_BORDER,																// wrapR
3824 		m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// minFilter
3825 		m_testParams.usesMipMaps ? tcu::Sampler::NEAREST_MIPMAP_NEAREST : tcu::Sampler::NEAREST,	// magFilter
3826 		0.0f,																						// lodTreshold
3827 		true);																						// normalizeCoords
3828 	const VkSamplerCreateInfo	createInfo = vk::mapSampler(sampler, vk::mapVkFormat(m_colorFormat));
3829 	variables.descriptorSamplers.push_back(ut::SamplerSp(new Move<VkSampler>(vk::createSampler(m_vki, m_vkd, &createInfo))));
3830 
3831 	const VkExtent3D&			imageExtent = m_testParams.usesMipMaps ? bigImageExtent : smallImageExtent;
3832 	createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
3833 		imageExtent, m_colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount, m_testParams.usesMipMaps);
3834 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, m_colorFormat);
3835 
3836 	PixelBufferAccess			pixelAccess;
3837 	for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3838 	{
3839 		const float				component = m_colorScheme[imageIdx % m_schemeSize];
3840 
3841 		if (m_testParams.usesMipMaps)
3842 		{
3843 			const deUint32	mipCount = ut::computeMipMapCount(imageExtent);
3844 			DE_ASSERT(mipCount >= 2);
3845 			for (deUint32 mipIdx = 0; mipIdx < mipCount; ++mipIdx)
3846 			{
3847 				pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipIdx);
3848 				tcu::clear(pixelAccess, m_clearColor);
3849 			}
3850 
3851 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, mipCount-1);
3852 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3853 		}
3854 		else
3855 		{
3856 			pixelAccess = getPixelAccess(imageIdx, imageExtent, m_colorFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer, 0);
3857 			pixelAccess.setPixel(tcu::Vec4(component, component, component, 1.0f), 0, 0);
3858 		}
3859 	}
3860 
3861 	vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3862 }
3863 
3864 class StorageImageInstance : public CommonDescriptorInstance
3865 {
3866 public:
3867 								StorageImageInstance				(Context&									context,
3868 																	 const TestCaseParams&						testCaseParams);
3869 private:
3870 	virtual tcu::TestStatus		iterate								(void);
3871 	virtual void				createAndPopulateDescriptors		(IterateCommonVariables&					variables);
3872 	virtual void				updateDescriptors					(IterateCommonVariables&					variables);
3873 	virtual void				iterateCollectResults				(ut::UpdatablePixelBufferAccessPtr&			result,
3874 																	 const IterateCommonVariables&				variables,
3875 																	 bool										fromTest);
3876 	ut::BufferHandleAllocSp		m_buffer;
3877 	const deUint32				m_fillColor;
3878 	typedef deUint32			m_imageFormat_t;
3879 };
3880 
StorageImageInstance(Context & context,const TestCaseParams & testCaseParams)3881 StorageImageInstance::StorageImageInstance							(Context&									context,
3882 																	 const TestCaseParams&						testCaseParams)
3883 	: CommonDescriptorInstance(context,
3884 		TestParams	(VK_SHADER_STAGE_COMPUTE_BIT,
3885 					VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3886 					BINDING_StorageImage,
3887 					VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
3888 					(BINDING_StorageImage + 1),
3889 					true,
3890 					performWritesInVertex(testCaseParams.descriptorType, context),
3891 					testCaseParams))
3892 	, m_buffer		()
3893 	, m_fillColor	(10)
3894 {
3895 }
3896 
updateDescriptors(IterateCommonVariables & variables)3897 void StorageImageInstance::updateDescriptors						(IterateCommonVariables&					variables)
3898 {
3899 	// update image at last index
3900 	{
3901 		VkDescriptorImageInfo		imageInfo =
3902 		{
3903 			static_cast<VkSampler>(0),
3904 			**variables.descriptorImageViews[variables.validDescriptorCount],
3905 			VK_IMAGE_LAYOUT_GENERAL
3906 		};
3907 
3908 		const VkWriteDescriptorSet writeInfo =
3909 		{
3910 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// sType
3911 			DE_NULL,									// pNext
3912 			*variables.descriptorSet,					// descriptorSet
3913 			m_testParams.additionalDescriptorBinding,	// descriptorBinding;
3914 			0,											// elementIndex
3915 			1u,											// descriptorCount
3916 			m_testParams.additionalDescriptorType,		// descriptorType
3917 			&imageInfo,									// pImageInfo
3918 			DE_NULL,									// pBufferInfo
3919 			DE_NULL										// pTexelBufferView
3920 		};
3921 
3922 		m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
3923 	}
3924 
3925 	// update rest images
3926 	CommonDescriptorInstance::updateDescriptors(variables);
3927 }
3928 
createAndPopulateDescriptors(IterateCommonVariables & variables)3929 void StorageImageInstance::createAndPopulateDescriptors				(IterateCommonVariables&					variables)
3930 {
3931 	const VkFormat				imageFormat = ut::mapType2vkFormat<m_imageFormat_t>::value;
3932 	const VkBufferUsageFlags	bufferUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3933 
3934 	// create descriptor buffer, images and views
3935 	{
3936 		const VkExtent3D			imageExtent = { 4, 4, 1 };
3937 
3938 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, variables.descriptorsBuffer,
3939 			bufferUsage, imageExtent, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, variables.validDescriptorCount);
3940 
3941 		for (deUint32 imageIdx = 0; imageIdx < variables.validDescriptorCount; ++imageIdx)
3942 		{
3943 			const PixelBufferAccess pa = getPixelAccess(imageIdx, imageExtent, imageFormat, variables.descriptorsBufferInfos, variables.descriptorsBuffer);
3944 			tcu::clear(pa, tcu::UVec4(m_fillColor));
3945 		}
3946 		vk::flushAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
3947 	}
3948 
3949 	// create additional image that will be used as index container
3950 	{
3951 		createImages(variables.descriptorsImages, variables.descriptorsBufferInfos, m_buffer,
3952 			bufferUsage, m_testParams.frameResolution, imageFormat, VK_IMAGE_LAYOUT_UNDEFINED, 1);
3953 
3954 		// populate buffer
3955 		const std::vector<deUint32>	primes = ut::generatePrimes(variables.availableDescriptorCount);
3956 		const PixelBufferAccess pa = getPixelAccess(variables.validDescriptorCount, m_testParams.frameResolution, imageFormat, variables.descriptorsBufferInfos, m_buffer);
3957 		for (deUint32 y = 0, pixel = 0; y < m_testParams.frameResolution.height; ++y)
3958 		{
3959 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixel)
3960 			{
3961 				const deUint32 component = primes[pixel % variables.validDescriptorCount];
3962 				pa.setPixel(tcu::UVec4(component), x, y);
3963 			}
3964 		}
3965 
3966 		// save changes
3967 		vk::flushAlloc(m_vki, m_vkd, *m_buffer->alloc);
3968 	}
3969 
3970 	// create views for all previously created images
3971 	createImagesViews(variables.descriptorImageViews, variables.descriptorsImages, imageFormat);
3972 }
3973 
iterate(void)3974 tcu::TestStatus StorageImageInstance::iterate						(void)
3975 {
3976 	IterateCommonVariables	v;
3977 	iterateCommandSetup		(v);
3978 	iterateCommandBegin		(v);
3979 
3980 	ut::UpdatablePixelBufferAccessPtr	programResult;
3981 	ut::UpdatablePixelBufferAccessPtr	referenceResult;
3982 
3983 	if (m_testParams.updateAfterBind)
3984 	{
3985 		updateDescriptors	(v);
3986 	}
3987 
3988 	copyBuffersToImages		(v);
3989 
3990 	m_vki.cmdDispatch		(*v.commandBuffer,
3991 							m_testParams.calculateInLoop ? 1 : v.renderArea.extent.width,
3992 							m_testParams.calculateInLoop ? 1 : v.renderArea.extent.height,
3993 							1);
3994 
3995 	copyImagesToBuffers		(v);
3996 
3997 	iterateCommandEnd(v, programResult, referenceResult, false);
3998 
3999 	return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
4000 }
4001 
iterateCollectResults(ut::UpdatablePixelBufferAccessPtr & result,const IterateCommonVariables & variables,bool fromTest)4002 void StorageImageInstance::iterateCollectResults					(ut::UpdatablePixelBufferAccessPtr&			result,
4003 																	 const IterateCommonVariables&				variables,
4004 																	 bool										fromTest)
4005 {
4006 	result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(
4007 		vk::mapVkFormat(ut::mapType2vkFormat<m_imageFormat_t>::value), m_testParams.frameResolution));
4008 	const PixelBufferAccess& dst = *result.get();
4009 
4010 	if (fromTest)
4011 	{
4012 		vk::invalidateAlloc(m_vki, m_vkd, *variables.descriptorsBuffer->alloc);
4013 		for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
4014 		{
4015 			for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
4016 			{
4017 				const deUint32 imageIdx = pixelNum % variables.validDescriptorCount;
4018 				const PixelBufferAccess src = getPixelAccess(imageIdx,
4019 					variables.descriptorsImages[imageIdx]->extent, variables.descriptorsImages[imageIdx]->format,
4020 					variables.descriptorsBufferInfos, variables.descriptorsBuffer);
4021 				dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(src.getPixelT<m_imageFormat_t>(0, 0).x()), x, y);
4022 			}
4023 		}
4024 	}
4025 	else
4026 	{
4027 		std::vector<m_imageFormat_t> inc(variables.validDescriptorCount, m_fillColor);
4028 
4029 		for (deUint32 invIdx = variables.lowerBound; invIdx < variables.upperBound; ++invIdx)
4030 		{
4031 			++inc[invIdx % variables.validDescriptorCount];
4032 		}
4033 
4034 		for (deUint32 invIdx = 0; invIdx < variables.vertexCount; ++invIdx)
4035 		{
4036 			const deUint32 row = invIdx / m_testParams.frameResolution.width;
4037 			const deUint32 col = invIdx % m_testParams.frameResolution.width;
4038 			const m_imageFormat_t color = inc[invIdx % variables.validDescriptorCount];
4039 			dst.setPixel(tcu::Vector<m_imageFormat_t, 4>(color), col, row);
4040 		}
4041 	}
4042 }
4043 
4044 class DescriptorIndexingTestCase : public TestCase
4045 {
4046 	const TestCaseParams m_testCaseParams;
4047 public:
DescriptorIndexingTestCase(tcu::TestContext & context,const char * name,const char * description,const TestCaseParams & testCaseParams)4048 	DescriptorIndexingTestCase (tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
4049 		: TestCase(context, name, description)
4050 		, m_testCaseParams(testCaseParams)
4051 	{
4052 	}
4053 
createInstance(vkt::Context & context) const4054 	vkt::TestInstance* createInstance (vkt::Context& context) const // override
4055 	{
4056 		switch (m_testCaseParams.descriptorType)
4057 		{
4058 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4059 			return new StorageBufferInstance		(context, m_testCaseParams);
4060 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4061 			return new UniformBufferInstance		(context, m_testCaseParams);
4062 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4063 			return new StorageTexelInstance			(context, m_testCaseParams);
4064 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4065 			return new UniformTexelInstance			(context, m_testCaseParams);
4066 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4067 			return new DynamicStorageBufferInstance	(context, m_testCaseParams);
4068 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4069 			return new DynamicUniformBufferInstance	(context, m_testCaseParams);
4070 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4071 			return new InputAttachmentInstance		(context, m_testCaseParams);
4072 		case VK_DESCRIPTOR_TYPE_SAMPLER:
4073 			return new SamplerInstance				(context, m_testCaseParams);
4074 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4075 			return new SampledImageInstance			(context, m_testCaseParams);
4076 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4077 			return new CombinedImageInstance		(context, m_testCaseParams);
4078 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4079 			return new StorageImageInstance			(context, m_testCaseParams);
4080 		default:
4081 			TCU_THROW(InternalError, "Unknown Descriptor Type");
4082 		}
4083 		return DE_NULL;
4084 	}
4085 
checkSupport(vkt::Context & context) const4086 	virtual void checkSupport (vkt::Context& context) const
4087 	{
4088 		context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
4089 
4090 		const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& feats = context.getDescriptorIndexingFeatures();
4091 
4092 		switch (m_testCaseParams.descriptorType)
4093 		{
4094 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4095 			if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4096 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
4097 
4098 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
4099 				TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
4100 			break;
4101 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4102 			if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4103 				TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
4104 
4105 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
4106 				TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
4107 			break;
4108 		case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4109 			if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
4110 				TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
4111 
4112 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
4113 				TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
4114 			break;
4115 		case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4116 			if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
4117 				TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
4118 
4119 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
4120 				TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
4121 			break;
4122 		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
4123 			if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
4124 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
4125 
4126 			if (m_testCaseParams.updateAfterBind)
4127 				TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
4128 			break;
4129 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4130 			if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
4131 				TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
4132 
4133 			if (m_testCaseParams.updateAfterBind)
4134 				TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
4135 			break;
4136 		case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4137 			if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
4138 				TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
4139 
4140 			if (m_testCaseParams.updateAfterBind)
4141 				TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
4142 			break;
4143 		case VK_DESCRIPTOR_TYPE_SAMPLER:
4144 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4145 				TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
4146 
4147 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4148 				TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
4149 			break;
4150 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4151 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4152 				TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
4153 
4154 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4155 				TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
4156 			break;
4157 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4158 			if (!(feats.shaderSampledImageArrayNonUniformIndexing))
4159 				TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
4160 
4161 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
4162 				TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
4163 			break;
4164 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4165 			if (!(feats.shaderStorageImageArrayNonUniformIndexing))
4166 				TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
4167 
4168 			if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
4169 				TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
4170 			break;
4171 		default:
4172 			DE_FATAL("Unknown Descriptor Type");
4173 			break;
4174 		}
4175 	}
4176 
initAsmPrograms(SourceCollections & programCollection) const4177 	void initAsmPrograms(SourceCollections&	programCollection) const
4178 	{
4179 
4180 		std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderAsm;
4181 
4182 		deUint32 vulkan_version = VK_MAKE_VERSION(1, 2, 0);
4183 		vk::SpirvVersion spirv_version = vk::SPIRV_VERSION_1_4;
4184 		vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
4185 
4186 		if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4187 		{
4188 			programCollection.spirvAsmSources.add(
4189 				ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4190 				<< (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false);
4191 
4192 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4193 			{
4194 				programCollection.spirvAsmSources.add(
4195 					ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4196 					<< (*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true);
4197 			}
4198 		}
4199 		if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4200 		{
4201 			programCollection.spirvAsmSources.add(
4202 				ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4203 				<< (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false);
4204 
4205 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4206 			{
4207 				programCollection.spirvAsmSources.add(
4208 					ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true), &asm_options)
4209 					<< (*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true);
4210 			}
4211 		}
4212 		if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4213 		{
4214 			programCollection.spirvAsmSources.add(
4215 				ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false), &asm_options)
4216 				<< (*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false);
4217 		}
4218 	}
4219 
initPrograms(SourceCollections & programCollection) const4220 	virtual void initPrograms (SourceCollections& programCollection) const
4221 	{
4222 		if (m_testCaseParams.minNonUniform) {
4223 			initAsmPrograms(programCollection);
4224 			return;
4225 		}
4226 
4227 		std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
4228 
4229 		if (VK_SHADER_STAGE_VERTEX_BIT & m_testCaseParams.stageFlags)
4230 		{
4231 			programCollection.glslSources.add(
4232 				ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4233 				<< glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, false));
4234 
4235 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4236 			{
4237 				programCollection.glslSources.add(
4238 					ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4239 					<< glu::VertexSource((*genShaderSource)(VK_SHADER_STAGE_VERTEX_BIT, m_testCaseParams, true));
4240 			}
4241 		}
4242 		if (VK_SHADER_STAGE_FRAGMENT_BIT & m_testCaseParams.stageFlags)
4243 		{
4244 			programCollection.glslSources.add(
4245 				ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4246 				<< glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, false));
4247 
4248 			if (CommonDescriptorInstance::performWritesInVertex(m_testCaseParams.descriptorType))
4249 			{
4250 				programCollection.glslSources.add(
4251 					ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, true))
4252 					<< glu::FragmentSource((*genShaderSource)(VK_SHADER_STAGE_FRAGMENT_BIT, m_testCaseParams, true));
4253 			}
4254 		}
4255 		if (VK_SHADER_STAGE_COMPUTE_BIT & m_testCaseParams.stageFlags)
4256 		{
4257 			programCollection.glslSources.add(
4258 				ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams.descriptorType, m_testCaseParams.updateAfterBind, m_testCaseParams.calculateInLoop, m_testCaseParams.minNonUniform, false))
4259 				<< glu::ComputeSource((*genShaderSource)(VK_SHADER_STAGE_COMPUTE_BIT, m_testCaseParams, false));
4260 		}
4261 	}
4262 };
4263 
4264 } // - unnamed namespace
4265 
descriptorIndexingDescriptorSetsCreateTests(tcu::TestCaseGroup * group)4266 void descriptorIndexingDescriptorSetsCreateTests (tcu::TestCaseGroup* group)
4267 {
4268 	struct TestCaseInfo
4269 	{
4270 		const char*		name;
4271 		const char*		description;
4272 		TestCaseParams	params;
4273 	};
4274 
4275 	tcu::TestContext&				context(group->getTestContext());
4276 
4277 	TestCaseInfo casesAfterBindAndLoop[] =
4278 	{
4279 		{
4280 			"storage_buffer", "Regular Storage Buffer Descriptors",
4281 			{
4282 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4283 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4284 				RESOLUTION,
4285 				false,	// updateAfterBind
4286 				false,	// calculateInLoop
4287 				false,	// useMipMaps
4288 				false,	// minNonUniform
4289 				FUZZY_COMPARE, CMP_THRESHOLD
4290 			}
4291 		},
4292 		{
4293 			"storage_texel_buffer", "Storage Texel Buffer Descriptors",
4294 			{
4295 				VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4296 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4297 				RESOLUTION,
4298 				false,	// updateAfterBind
4299 				false,	// calculateInLoop
4300 				false,	// useMipMaps
4301 				false,	// minNonUniform
4302 				FUZZY_COMPARE, CMP_THRESHOLD
4303 			}
4304 		},
4305 		{
4306 			"uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4307 			{
4308 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4309 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4310 				RESOLUTION,
4311 				false,	// updateAfterBind,
4312 				false,	// calculateInLoop
4313 				false,	// usesMipMaps
4314 				false,	// minNonUniform
4315 				FUZZY_COMPARE, CMP_THRESHOLD
4316 			}
4317 		},
4318 		{
4319 			"storage_image", "Storage Image Descriptors",
4320 			{
4321 				VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4322 				VK_SHADER_STAGE_COMPUTE_BIT,
4323 				RESOLUTION,
4324 				false,	// updateAfterBind
4325 				false,	// calculateInLoop
4326 				false,	// useMipMaps
4327 				false,	// minNonUniform
4328 				FUZZY_COMPARE, CMP_THRESHOLD
4329 			}
4330 		},
4331 	};
4332 
4333 	for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4334 	{
4335 		for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4336 		{
4337 			for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoop); ++caseIdx)
4338 			{
4339 				TestCaseInfo&	info			(casesAfterBindAndLoop[caseIdx]);
4340 				std::string		caseName		(info.name);
4341 				std::string		caseDescription	(info.description);
4342 				TestCaseParams	params			(info.params);
4343 
4344 				caseName				+= (updateAfterBind	? "_after_bind"	: "");
4345 				caseName				+= (calculateInLoop	? "_in_loop"	: "");
4346 
4347 				caseDescription			+= (updateAfterBind	? " After Bind"	: "");
4348 				caseDescription			+= (calculateInLoop ? " In Loop"	: "");
4349 
4350 				params.updateAfterBind	= updateAfterBind	? true			: false;
4351 				params.calculateInLoop	= calculateInLoop	? true			: false;
4352 
4353 				group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4354 			}
4355 		}
4356 	}
4357 
4358 	TestCaseInfo casesAfterBindAndLoopAndLOD[] =
4359 	{
4360 		{
4361 			"sampler", "Sampler Descriptors",
4362 			{
4363 				VK_DESCRIPTOR_TYPE_SAMPLER,
4364 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4365 				RESOLUTION,
4366 				false,	// updateAfterBind
4367 				false,	// calculateInLoop
4368 				false,	// usesMipMaps
4369 				false,	// minNonUniform
4370 				FUZZY_COMPARE, CMP_THRESHOLD
4371 			}
4372 		},
4373 		{
4374 			"sampled_image", "Sampled Image Descriptors",
4375 			{
4376 				VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
4377 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4378 				RESOLUTION,
4379 				false,	// updateAfterBind
4380 				false,	// calculateInLoop
4381 				false,	// usesMipMaps
4382 				false,	// minNonUniform
4383 				FUZZY_COMPARE, CMP_THRESHOLD
4384 			}
4385 		},
4386 		{
4387 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4388 			{
4389 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4390 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4391 				RESOLUTION,
4392 				false,	// updateAfterBind
4393 				false,	// calculateInLoop
4394 				false,	// usesMipMaps
4395 				false,	// minNonUniform
4396 				FUZZY_COMPARE, CMP_THRESHOLD
4397 			}
4398 		},
4399 	};
4400 
4401 	for (int updateAfterBind = 0; updateAfterBind < 2; ++updateAfterBind)
4402 	{
4403 		for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4404 		{
4405 			for (int usesMipMaps = 0; usesMipMaps < 2; ++usesMipMaps)
4406 			{
4407 				for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesAfterBindAndLoopAndLOD); ++caseIdx)
4408 				{
4409 					TestCaseInfo&	info			(casesAfterBindAndLoopAndLOD[caseIdx]);
4410 					std::string		caseName		(info.name);
4411 					std::string		caseDescription	(info.description);
4412 					TestCaseParams	params			(info.params);
4413 
4414 					caseName				+= (updateAfterBind	? "_after_bind"	: "");
4415 					caseName				+= (calculateInLoop ? "_in_loop"	: "");
4416 					caseName				+= (usesMipMaps		? "_with_lod"	: "");
4417 
4418 					caseDescription			+= (updateAfterBind	? " After Bind"	: "");
4419 					caseDescription			+= (calculateInLoop	? " In Loop"	: "");
4420 					caseDescription			+= (usesMipMaps		? " Use LOD"	: "");
4421 
4422 					params.updateAfterBind	= updateAfterBind	? true			: false;
4423 					params.calculateInLoop	= calculateInLoop	? true			: false;
4424 					params.usesMipMaps		= usesMipMaps		? true			: false;
4425 
4426 					group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4427 				}
4428 			}
4429 		}
4430 	}
4431 
4432 	TestCaseInfo casesNonAfterBindAndLoop[] =
4433 	{
4434 		{
4435 			"uniform_buffer", "Regular Uniform Buffer Descriptors",
4436 			{
4437 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4438 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4439 				RESOLUTION,
4440 				false,	// updateAfterBind
4441 				false,	// calculateInLoop
4442 				false,	// usesMipMaps
4443 				false,	// minNonUniform
4444 				FUZZY_COMPARE, CMP_THRESHOLD
4445 			}
4446 		},
4447 		{
4448 			"storage_buffer_dynamic", "Dynamic Storage Buffer Descriptors",
4449 			{
4450 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
4451 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4452 				RESOLUTION,
4453 				false,	// updateAfterBind
4454 				false,	// calculateInLoop
4455 				false,	// useMipMaps
4456 				false,	// minNonUniform
4457 				FUZZY_COMPARE, CMP_THRESHOLD
4458 			}
4459 		},
4460 		{
4461 			"uniform_buffer_dynamic", "Dynamic Uniform Buffer Descriptors",
4462 			{
4463 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
4464 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4465 				RESOLUTION,
4466 				false,	// updateAfterBind
4467 				false,	// calculateInLoop
4468 				false,	// useMipMaps
4469 				false,	// minNonUniform
4470 				FUZZY_COMPARE, CMP_THRESHOLD
4471 			}
4472 		},
4473 		{
4474 			"input_attachment", "Input Attachment Descriptors",
4475 			{
4476 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
4477 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4478 				RESOLUTION,
4479 				false,	// updateAfterBind
4480 				false,	// calculateInLoop
4481 				false,	// useMipMaps
4482 				false,	// minNonUniform
4483 				FUZZY_COMPARE, CMP_THRESHOLD
4484 			}
4485 		},
4486 	};
4487 
4488 	for (int calculateInLoop = 0; calculateInLoop < 2; ++calculateInLoop)
4489 	{
4490 		for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesNonAfterBindAndLoop); ++caseIdx)
4491 		{
4492 			TestCaseInfo&	info(casesNonAfterBindAndLoop[caseIdx]);
4493 			std::string		caseName(info.name);
4494 			std::string		caseDescription(info.description);
4495 			TestCaseParams	params(info.params);
4496 
4497 			caseName				+= (calculateInLoop	? "_in_loop"	: "");
4498 
4499 			caseDescription			+= (calculateInLoop ? " In Loop"	: "");
4500 
4501 			params.calculateInLoop	= calculateInLoop	? true			: false;
4502 
4503 			group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4504 		}
4505 	}
4506 
4507 	// SPIR-V Asm Tests
4508 	// Tests that have the minimum necessary NonUniform decorations.
4509 	// sampler and sampled_image GLSL already have minimum NonUniform decorations.
4510 
4511 	TestCaseInfo casesMinNonUniform[] =
4512 	{
4513 		{
4514 			"storage_buffer", "Regular Storage Buffer Descriptors",
4515 			{
4516 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
4517 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4518 				RESOLUTION,
4519 				false,	// updateAfterBind
4520 				false,	// calculateInLoop
4521 				false,	// useMipMaps
4522 				true,	// minNonUniform
4523 				FUZZY_COMPARE, CMP_THRESHOLD
4524 			}
4525 		},
4526 		{
4527 			"storage_texel_buffer", "Storage Texel Buffer Descriptors",
4528 			{
4529 				VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
4530 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4531 				RESOLUTION,
4532 				false,	// updateAfterBind
4533 				false,	// calculateInLoop
4534 				false,	// useMipMaps
4535 				true,	// minNonUniform
4536 				FUZZY_COMPARE, CMP_THRESHOLD
4537 			}
4538 		},
4539 		{
4540 			"uniform_texel_buffer", "Uniform Texel Buffer Descriptors",
4541 			{
4542 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
4543 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4544 				RESOLUTION,
4545 				false,	// updateAfterBind,
4546 				false,	// calculateInLoop
4547 				false,	// usesMipMaps
4548 				true,	// minNonUniform
4549 				FUZZY_COMPARE, CMP_THRESHOLD
4550 			}
4551 		},
4552 		{
4553 			"uniform_buffer", "Regular Uniform Buffer Descriptors",
4554 			{
4555 				VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
4556 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4557 				RESOLUTION,
4558 				false,	// updateAfterBind
4559 				false,	// calculateInLoop
4560 				false,	// usesMipMaps
4561 				true,	// minNonUniform
4562 				FUZZY_COMPARE, CMP_THRESHOLD
4563 			}
4564 		},
4565 		{
4566 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4567 			{
4568 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4569 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4570 				RESOLUTION,
4571 				false,	// updateAfterBind
4572 				false,	// calculateInLoop
4573 				false,	// usesMipMaps
4574 				true,	// minNonUniform
4575 				FUZZY_COMPARE, CMP_THRESHOLD
4576 			}
4577 		},
4578 		{
4579 			"combined_image_sampler", "Combined Image Sampler Descriptors",
4580 			{
4581 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
4582 				(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT),
4583 				RESOLUTION,
4584 				false,	// updateAfterBind
4585 				false,	// calculateInLoop
4586 				true,	// usesMipMaps
4587 				true,	// minNonUniform
4588 				FUZZY_COMPARE, CMP_THRESHOLD
4589 			}
4590 		},
4591 		{
4592 			"storage_image", "Storage Image Descriptors",
4593 			{
4594 				VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
4595 				VK_SHADER_STAGE_COMPUTE_BIT,
4596 				RESOLUTION,
4597 				false,	// updateAfterBind
4598 				false,	// calculateInLoop
4599 				false,	// useMipMaps
4600 				true,	// minNonUniform
4601 				FUZZY_COMPARE, CMP_THRESHOLD
4602 			}
4603 		},
4604 	};
4605 
4606 	for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(casesMinNonUniform); ++caseIdx)
4607 	{
4608 		TestCaseInfo&	info(casesMinNonUniform[caseIdx]);
4609 		std::string		caseName(info.name);
4610 		std::string		caseDescription(info.description);
4611 		TestCaseParams	params(info.params);
4612 
4613 		if (params.usesMipMaps) {
4614 			caseName += "_with_lod";
4615 		}
4616 		caseName += "_minNonUniform";
4617 
4618 		caseDescription += " With Minimum NonUniform Decorations";
4619 
4620 		TestCase* tc = new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params);
4621 		group->addChild(tc);
4622 		// group->addChild(new DescriptorIndexingTestCase(context, caseName.c_str(), caseDescription.c_str(), params));
4623 	}
4624 }
4625 
4626 } // - DescriptorIndexing
4627 } // - vkt
4628