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