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