• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Google Inc.
7  * Copyright (c) 2018 ARM Limited.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Push Descriptor Tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktPipelinePushDescriptorTests.hpp"
27 #include "vktPipelineClearUtil.hpp"
28 #include "vktPipelineImageUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktPipelineReferenceRenderer.hpp"
31 #include "vktTestCase.hpp"
32 #include "vktCustomInstancesDevices.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 #include "vkDeviceUtil.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "deMemory.h"
45 #include "deUniquePtr.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuCommandLine.hpp"
48 #include <vector>
49 
50 namespace vkt
51 {
52 namespace pipeline
53 {
54 
55 using namespace vk;
56 using namespace std;
57 
58 namespace
59 {
60 typedef vector<VkExtensionProperties>			Extensions;
61 typedef de::SharedPtr<Unique<VkBuffer> >		VkBufferSp;
62 typedef de::SharedPtr<Unique<VkImage> >			VkImageSp;
63 typedef de::SharedPtr<Unique<VkImageView> >		VkImageViewSp;
64 typedef de::SharedPtr<Unique<VkBufferView> >	VkBufferViewSp;
65 typedef de::SharedPtr<Allocation>				AllocationSp;
66 typedef de::SharedPtr<Unique<VkRenderPass> >	VkRenderPassSp;
67 typedef de::SharedPtr<Unique<VkFramebuffer> >	VkFramebufferSp;
68 
69 constexpr VkDeviceSize kSizeofVec4 = static_cast<VkDeviceSize>(sizeof(tcu::Vec4));
70 
71 struct TestParams
72 {
73 	PipelineConstructionType	pipelineConstructionType;		// Used only by graphics pipeline tests
74 	VkDescriptorType			descriptorType;
75 	deUint32					binding;
76 	deUint32					numCalls;						// Number of draw or dispatch calls
77 };
78 
calcItemSize(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 numElements=1u)79 VkDeviceSize calcItemSize (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 numElements = 1u)
80 {
81 	const auto minAlignment	= getPhysicalDeviceProperties(vki, physicalDevice).limits.minStorageBufferOffsetAlignment;
82 	const auto lcm			= de::lcm(de::max(VkDeviceSize{1}, minAlignment), kSizeofVec4);
83 	return de::roundUp(kSizeofVec4 * numElements, lcm);
84 }
85 
checkAllSupported(const Extensions & supportedExtensions,const vector<string> & requiredExtensions)86 void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
87 {
88 	for (auto& requiredExtName : requiredExtensions)
89 	{
90 		if (!isExtensionStructSupported(supportedExtensions, RequiredExtension(requiredExtName)))
91 			TCU_THROW(NotSupportedError, (requiredExtName + " is not supported").c_str());
92 	}
93 }
94 
createInstanceWithGetPhysicalDeviceProperties2(Context & context,const Extensions & supportedExtensions)95 CustomInstance createInstanceWithGetPhysicalDeviceProperties2 (Context&				context,
96 															   const Extensions&	supportedExtensions)
97 {
98 	vector<string> requiredExtensions = { "VK_KHR_get_physical_device_properties2" };
99 	checkAllSupported(supportedExtensions, requiredExtensions);
100 
101 	return createCustomInstanceWithExtensions(context, requiredExtensions);
102 }
103 
innerCString(const string & str)104 const char *innerCString(const string &str)
105 {
106 	return str.c_str();
107 }
108 
createDeviceWithPushDescriptor(const Context & context,const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const Extensions & supportedExtensions,const deUint32 queueFamilyIndex,const TestParams & params)109 Move<VkDevice> createDeviceWithPushDescriptor (const Context&				context,
110 											   const PlatformInterface&		vkp,
111 											   VkInstance					instance,
112 											   const InstanceInterface&		vki,
113 											   VkPhysicalDevice				physicalDevice,
114 											   const Extensions&			supportedExtensions,
115 											   const deUint32				queueFamilyIndex,
116 											   const TestParams&			params)
117 {
118 
119 	const float						queuePriority			= 1.0f;
120 	const VkDeviceQueueCreateInfo	queueInfo				=
121 	{
122 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
123 		DE_NULL,
124 		(VkDeviceQueueCreateFlags)0,
125 		queueFamilyIndex,
126 		1u,
127 		&queuePriority
128 	};
129 
130 	VkPhysicalDeviceFeatures		features;
131 	deMemset(&features, 0, sizeof(features));
132 
133 	vector<string>					requiredExtensionsStr	= { "VK_KHR_push_descriptor" };
134 	VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT graphicsPipelineLibraryFeaturesEXT = initVulkanStructure();
135 	VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&graphicsPipelineLibraryFeaturesEXT);
136 	if (params.pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
137 	{
138 		requiredExtensionsStr.push_back("VK_KHR_pipeline_library");
139 		requiredExtensionsStr.push_back("VK_EXT_graphics_pipeline_library");
140 		vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
141 		if (!graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary)
142 			TCU_THROW(NotSupportedError, "graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary required");
143 	}
144 	vector<const char *>			requiredExtensions;
145 	checkAllSupported(supportedExtensions, requiredExtensionsStr);
146 	// We need the contents of requiredExtensionsStr as a vector<const char*> in VkDeviceCreateInfo.
147 	transform(begin(requiredExtensionsStr), end(requiredExtensionsStr), back_inserter(requiredExtensions), innerCString);
148 
149 	// Enable validation layers on this device if validation has been requested from the command line.
150 	const VkDeviceCreateInfo		deviceParams    =
151 	{
152 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
153 		params.pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC ? &features2 : DE_NULL,
154 		(VkDeviceCreateFlags)0,
155 		1u,
156 		&queueInfo,
157 		0u,
158 		DE_NULL,
159 		static_cast<deUint32>(requiredExtensions.size()),
160 		(requiredExtensions.empty() ? DE_NULL : requiredExtensions.data()),
161 		params.pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC ? DE_NULL : &features
162 	};
163 
164 	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceParams, DE_NULL);
165 }
166 
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)167 deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
168 {
169 	const vector<VkQueueFamilyProperties>	queueProps	= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
170 
171 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
172 	{
173 		if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
174 			return (deUint32)queueNdx;
175 	}
176 
177 	TCU_THROW(NotSupportedError, "No matching queue found");
178 }
179 
createQuads(deUint32 numQuads,float size)180 vector<Vertex4RGBA> createQuads (deUint32 numQuads, float size)
181 {
182 	vector<Vertex4RGBA>	vertices;
183 
184 	for (deUint32 quadNdx = 0; quadNdx < numQuads; quadNdx++)
185 	{
186 		const float			xOffset				= -0.5f + (float)quadNdx;
187 		const tcu::Vec4		color				(0.0f);
188 		const Vertex4RGBA	lowerLeftVertex		= {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), color};
189 		const Vertex4RGBA	lowerRightVertex	= {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), color};
190 		const Vertex4RGBA	UpperLeftVertex		= {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), color};
191 		const Vertex4RGBA	UpperRightVertex	= {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f), color};
192 
193 		vertices.push_back(lowerLeftVertex);
194 		vertices.push_back(lowerRightVertex);
195 		vertices.push_back(UpperLeftVertex);
196 		vertices.push_back(UpperLeftVertex);
197 		vertices.push_back(lowerRightVertex);
198 		vertices.push_back(UpperRightVertex);
199 	}
200 
201 	return vertices;
202 }
203 
createTexQuads(deUint32 numQuads,float size)204 vector<Vertex4Tex4> createTexQuads (deUint32 numQuads, float size)
205 {
206 	vector<Vertex4Tex4>	vertices;
207 
208 	for (deUint32 quadNdx = 0; quadNdx < numQuads; quadNdx++)
209 	{
210 		const float			xOffset				= -0.5f + (float)quadNdx;
211 		const Vertex4Tex4	lowerLeftVertex		= {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(-0.2f, -0.2f, 0.0f, 0.0f)};
212 		const Vertex4Tex4	lowerRightVertex	= {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(1.2f, -0.2f, 0.0f, 0.0f)};
213 		const Vertex4Tex4	UpperLeftVertex		= {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(-0.2f, 1.2f, 0.0f, 0.0f)};
214 		const Vertex4Tex4	UpperRightVertex	= {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(1.2f, 1.2f, 0.0f, 0.0f)};
215 
216 		vertices.push_back(lowerLeftVertex);
217 		vertices.push_back(lowerRightVertex);
218 		vertices.push_back(UpperLeftVertex);
219 		vertices.push_back(UpperLeftVertex);
220 		vertices.push_back(lowerRightVertex);
221 		vertices.push_back(UpperRightVertex);
222 	}
223 
224 	return vertices;
225 }
226 
227 static const tcu::Vec4 defaultTestColors[] =
228 
229 {
230 	tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
231 	tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)
232 };
233 
234 class PushDescriptorBufferGraphicsTestInstance : public vkt::TestInstance
235 {
236 public:
237 								PushDescriptorBufferGraphicsTestInstance	(Context& context, const TestParams& params);
238 	virtual						~PushDescriptorBufferGraphicsTestInstance	(void);
239 	void						init										(void);
240 	virtual tcu::TestStatus		iterate										(void);
241 	tcu::TestStatus				verifyImage									(void);
242 
243 private:
244 	const TestParams			m_params;
245 	const PlatformInterface&	m_vkp;
246 	const Extensions			m_instanceExtensions;
247 	const CustomInstance		m_instance;
248 	const InstanceDriver&		m_vki;
249 	const VkPhysicalDevice		m_physicalDevice;
250 	const deUint32				m_queueFamilyIndex;
251 	const Extensions			m_deviceExtensions;
252 	const Unique<VkDevice>		m_device;
253 	const DeviceDriver			m_vkd;
254 	const VkQueue				m_queue;
255 	SimpleAllocator				m_allocator;
256 	const tcu::UVec2			m_renderSize;
257 	const VkFormat				m_colorFormat;
258 	Move<VkImage>				m_colorImage;
259 	de::MovePtr<Allocation>		m_colorImageAlloc;
260 	Move<VkImageView>			m_colorAttachmentView;
261 	Move<VkRenderPass>			m_renderPass;
262 	Move<VkFramebuffer>			m_framebuffer;
263 	Move<VkShaderModule>		m_vertexShaderModule;
264 	Move<VkShaderModule>		m_fragmentShaderModule;
265 	Move<VkBuffer>				m_vertexBuffer;
266 	de::MovePtr<Allocation>		m_vertexBufferAlloc;
267 	vector<VkBufferSp>			m_buffers;
268 	vector<AllocationSp>		m_bufferAllocs;
269 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
270 	Move<VkPipelineLayout>		m_preRasterizationStatePipelineLayout;
271 	Move<VkPipelineLayout>		m_fragmentStatePipelineLayout;
272 	GraphicsPipelineWrapper		m_graphicsPipeline;
273 	Move<VkCommandPool>			m_cmdPool;
274 	Move<VkCommandBuffer>		m_cmdBuffer;
275 	vector<Vertex4RGBA>			m_vertices;
276 };
277 
PushDescriptorBufferGraphicsTestInstance(Context & context,const TestParams & params)278 PushDescriptorBufferGraphicsTestInstance::PushDescriptorBufferGraphicsTestInstance (Context& context, const TestParams& params)
279 	: vkt::TestInstance		(context)
280 	, m_params				(params)
281 	, m_vkp					(context.getPlatformInterface())
282 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
283 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
284 	, m_vki					(m_instance.getDriver())
285 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
286 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
287 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
288 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
289 	, m_vkd					(m_vkp, m_instance, *m_device)
290 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
291 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
292 	, m_renderSize			(32, 32)
293 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
294 	, m_graphicsPipeline	(m_vkd, *m_device, params.pipelineConstructionType)
295 	, m_vertices			(createQuads(params.numCalls, 0.25f))
296 {
297 }
298 
init(void)299 void PushDescriptorBufferGraphicsTestInstance::init (void)
300 {
301 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
302 
303 	// Create color image
304 	{
305 
306 		const VkImageCreateInfo		colorImageParams		=
307 		{
308 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
309 			DE_NULL,																// const void*				pNext;
310 			0u,																		// VkImageCreateFlags		flags;
311 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
312 			m_colorFormat,															// VkFormat					format;
313 			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
314 			1u,																		// deUint32					mipLevels;
315 			1u,																		// deUint32					arrayLayers;
316 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
317 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
318 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
319 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
320 			1u,																		// deUint32					queueFamilyIndexCount;
321 			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
322 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
323 		};
324 
325 		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);
326 
327 		// Allocate and bind color image memory
328 		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
329 		VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
330 	}
331 
332 	// Create color attachment view
333 	{
334 		const VkImageViewCreateInfo colorAttachmentViewParams =
335 		{
336 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
337 			DE_NULL,										// const void*				pNext;
338 			0u,												// VkImageViewCreateFlags	flags;
339 			*m_colorImage,									// VkImage					image;
340 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
341 			m_colorFormat,									// VkFormat					format;
342 			componentMappingRGBA,							// VkChannelMapping			channels;
343 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
344 		};
345 
346 		m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
347 	}
348 
349 	// Create render pass
350 	m_renderPass = makeRenderPass(m_vkd, *m_device, m_colorFormat);
351 
352 	// Create framebuffer
353 	{
354 		const VkImageView				attachmentBindInfos[]	=
355 		{
356 			*m_colorAttachmentView
357 		};
358 
359 		const VkFramebufferCreateInfo	framebufferParams		=
360 		{
361 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
362 			DE_NULL,									// const void*				pNext;
363 			0u,											// VkFramebufferCreateFlags	flags;
364 			*m_renderPass,								// VkRenderPass				renderPass;
365 			1u,											// deUint32					attachmentCount;
366 			attachmentBindInfos,						// const VkImageView*		pAttachments;
367 			(deUint32)m_renderSize.x(),					// deUint32					width;
368 			(deUint32)m_renderSize.y(),					// deUint32					height;
369 			1u											// deUint32					layers;
370 		};
371 
372 		m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
373 	}
374 
375 	// Create pipeline layout
376 	{
377 		// Create descriptor set layout
378 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
379 		{
380 			m_params.binding,					// uint32_t				binding;
381 			m_params.descriptorType,			// VkDescriptorType		descriptorType;
382 			1u,									// uint32_t				descriptorCount;
383 			VK_SHADER_STAGE_VERTEX_BIT,			// VkShaderStageFlags	stageFlags;
384 			DE_NULL								// const VkSampler*		pImmutableSamplers;
385 		};
386 
387 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
388 		{
389 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
390 			DE_NULL,													// const void*							pNext;
391 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
392 			1u,															// uint32_t								bindingCount;
393 			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
394 		};
395 
396 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
397 
398 		// Create pipeline layout
399 		VkPipelineLayoutCreateFlags	pipelineLayoutFlags = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
400 		VkPipelineLayoutCreateInfo	pipelineLayoutParams
401 		{
402 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
403 			DE_NULL,										// const void*					pNext;
404 			pipelineLayoutFlags,							// VkPipelineLayoutCreateFlags	flags;
405 			1u,												// deUint32						setLayoutCount;
406 			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
407 			0u,												// deUint32						pushConstantRangeCount;
408 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
409 		};
410 
411 		m_preRasterizationStatePipelineLayout	= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
412 		pipelineLayoutParams.setLayoutCount		= 0u;
413 		pipelineLayoutParams.pSetLayouts		= DE_NULL;
414 		m_fragmentStatePipelineLayout			= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
415 	}
416 
417 	// Create buffers. One color value in each buffer.
418 	{
419 		for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
420 		{
421 			const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
422 
423 			const VkBufferCreateInfo	bufferCreateInfo	=
424 			{
425 				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
426 				DE_NULL,								// const void*			pNext;
427 				0u,										// VkBufferCreateFlags	flags
428 				kSizeofVec4,							// VkDeviceSize			size;
429 				usageFlags,								// VkBufferUsageFlags	usage;
430 				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
431 				1u,										// deUint32				queueFamilyCount;
432 				&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
433 			};
434 
435 			m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
436 			m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
437 			VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
438 
439 			deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], static_cast<size_t>(kSizeofVec4));
440 			flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
441 		}
442 	}
443 
444 	// Create shaders
445 	{
446 		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
447 		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
448 	}
449 
450 	// Create pipeline
451 	{
452 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
453 		{
454 			0u,							// deUint32					binding;
455 			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
456 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
457 		};
458 
459 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[]	=
460 		{
461 			{
462 				0u,									// deUint32	location;
463 				0u,									// deUint32	binding;
464 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
465 				0u									// deUint32	offsetInBytes;
466 			},
467 			{
468 				1u,									// deUint32	location;
469 				0u,									// deUint32	binding;
470 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
471 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
472 			}
473 		};
474 
475 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
476 		{
477 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
478 			DE_NULL,													// const void*								pNext;
479 			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
480 			1u,															// deUint32									bindingCount;
481 			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
482 			2u,															// deUint32									attributeCount;
483 			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
484 		};
485 
486 		const VkPrimitiveTopology					topology							= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
487 
488 		const vector<VkViewport>					viewports							{ makeViewport(m_renderSize) };
489 		const vector<VkRect2D>						scissors							{ makeRect2D(m_renderSize) };
490 
491 		m_graphicsPipeline.setDefaultRasterizationState()
492 						  .setDefaultDepthStencilState()
493 						  .setDefaultMultisampleState()
494 						  .setDefaultColorBlendState()
495 						  .setDefaultTopology(topology)
496 						  .setupVertexInputState(&vertexInputStateParams)
497 						  .setupPreRasterizationShaderState(viewports,
498 															scissors,
499 															*m_preRasterizationStatePipelineLayout,
500 															*m_renderPass,
501 															0u,
502 															*m_vertexShaderModule)
503 						  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
504 						  .setupFragmentOutputState(*m_renderPass)
505 						  .setMonolithicPipelineLayout(*m_preRasterizationStatePipelineLayout)
506 						  .buildPipeline();
507 	}
508 
509 	// Create vertex buffer
510 	{
511 		const VkBufferCreateInfo vertexBufferParams =
512 		{
513 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
514 			DE_NULL,													// const void*			pNext;
515 			0u,															// VkBufferCreateFlags	flags;
516 			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
517 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
518 			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
519 			1u,															// deUint32				queueFamilyCount;
520 			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
521 		};
522 
523 		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
524 		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
525 
526 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
527 
528 		// Load vertices into vertex buffer
529 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
530 		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
531 	}
532 
533 	// Create command pool
534 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
535 
536 	// Create command buffer
537 	{
538 		const VkClearValue	attachmentClearValue	= defaultClearValue(m_colorFormat);
539 		const VkDeviceSize	vertexBufferOffset		= 0;
540 
541 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
542 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
543 		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
544 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
545 		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
546 
547 		// Draw quads. Switch input buffer which contains the quad color for each draw call.
548 		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
549 		{
550 			VkDescriptorBufferInfo descriptorBufferInfo =
551 			{
552 				**m_buffers[quadNdx],	// VkBuffer			buffer;
553 				0u,						// VkDeviceSize		offset;
554 				kSizeofVec4,			// VkDeviceSize		range;
555 			};
556 
557 			VkWriteDescriptorSet writeDescriptorSet =
558 			{
559 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
560 				DE_NULL,								// const void*						pNext;
561 				0u,										// VkDescriptorSet					dstSet;
562 				m_params.binding,						// uint32_t							dstBinding;
563 				0u,										// uint32_t							dstArrayElement;
564 				1u,										// uint32_t							descriptorCount;
565 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
566 				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
567 				&descriptorBufferInfo,					// const VkDescriptorBufferInfo*	pBufferInfo;
568 				DE_NULL									// const VkBufferView*				pTexelBufferView;
569 			};
570 
571 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_preRasterizationStatePipelineLayout, 0, 1, &writeDescriptorSet);
572 			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
573 		}
574 
575 		endRenderPass(m_vkd, *m_cmdBuffer);
576 		endCommandBuffer(m_vkd, *m_cmdBuffer);
577 	}
578 }
579 
~PushDescriptorBufferGraphicsTestInstance(void)580 PushDescriptorBufferGraphicsTestInstance::~PushDescriptorBufferGraphicsTestInstance (void)
581 {
582 }
583 
iterate(void)584 tcu::TestStatus PushDescriptorBufferGraphicsTestInstance::iterate (void)
585 {
586 	init();
587 
588 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
589 
590 	return verifyImage();
591 }
592 
verifyImage(void)593 tcu::TestStatus PushDescriptorBufferGraphicsTestInstance::verifyImage (void)
594 {
595 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
596 	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
597 	const ColorVertexShader		vertexShader;
598 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
599 	const rr::Program			program			(&vertexShader, &fragmentShader);
600 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
601 	bool						compareOk		= false;
602 
603 	// Render reference image
604 	{
605 		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
606 			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
607 				m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];
608 
609 		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
610 						 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
611 	}
612 
613 	// Compare result with reference image
614 	{
615 		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
616 
617 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
618 															  "IntImageCompare",
619 															  "Image comparison",
620 															  refRenderer.getAccess(),
621 															  result->getAccess(),
622 															  tcu::UVec4(2, 2, 2, 2),
623 															  tcu::IVec3(1, 1, 0),
624 															  true,
625 															  tcu::COMPARE_LOG_RESULT);
626 	}
627 
628 	if (compareOk)
629 		return tcu::TestStatus::pass("Result image matches reference");
630 	else
631 		return tcu::TestStatus::fail("Image mismatch");
632 }
633 
634 class PushDescriptorBufferGraphicsTest : public vkt::TestCase
635 {
636 public:
637 						PushDescriptorBufferGraphicsTest	(tcu::TestContext&	testContext,
638 															 const string&		name,
639 															 const string&		description,
640 															 const TestParams&	params);
641 						~PushDescriptorBufferGraphicsTest	(void);
642 	void				checkSupport						(Context& context) const;
643 	void				initPrograms						(SourceCollections& sourceCollections) const;
644 	TestInstance*		createInstance						(Context& context) const;
645 
646 protected:
647 	const TestParams	m_params;
648 };
649 
PushDescriptorBufferGraphicsTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)650 PushDescriptorBufferGraphicsTest::PushDescriptorBufferGraphicsTest (tcu::TestContext&	testContext,
651 																	const string&		name,
652 																	const string&		description,
653 																	const TestParams&	params)
654 	: vkt::TestCase	(testContext, name, description)
655 	, m_params		(params)
656 {
657 }
658 
~PushDescriptorBufferGraphicsTest(void)659 PushDescriptorBufferGraphicsTest::~PushDescriptorBufferGraphicsTest (void)
660 {
661 }
662 
createInstance(Context & context) const663 TestInstance* PushDescriptorBufferGraphicsTest::createInstance (Context& context) const
664 {
665 	return new PushDescriptorBufferGraphicsTestInstance(context, m_params);
666 }
667 
checkSupport(Context & context) const668 void PushDescriptorBufferGraphicsTest::checkSupport(Context& context) const
669 {
670 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
671 }
672 
initPrograms(SourceCollections & sourceCollections) const673 void PushDescriptorBufferGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
674 {
675 	const string	bufferType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "readonly buffer";
676 	const string	vertexSrc	=
677 		"#version 450\n"
678 		"layout(location = 0) in highp vec4 position;\n"
679 		"layout(location = 1) in highp vec4 color;\n"
680 		"layout(location = 0) out highp vec4 vtxColor;\n"
681 		"layout(set = 0, binding = " + de::toString(m_params.binding) + ") " + bufferType + " Block\n"
682 		"{\n"
683 		"	vec4 color;\n"
684 		"} inputData;\n"
685 		"\n"
686 		"out gl_PerVertex { vec4 gl_Position; };\n"
687 		"\n"
688 		"void main()\n"
689 		"{\n"
690 		"	gl_Position = position;\n"
691 		"	vtxColor = inputData.color;\n"
692 		"}\n";
693 
694 	const string	fragmentSrc	=
695 		"#version 450\n"
696 		"layout(location = 0) in highp vec4 vtxColor;\n"
697 		"layout(location = 0) out highp vec4 fragColor;\n"
698 		"\n"
699 		"void main (void)\n"
700 		"{\n"
701 		"	fragColor = vtxColor;\n"
702 		"}\n";
703 
704 	sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
705 	sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
706 }
707 
708 class PushDescriptorBufferComputeTestInstance : public vkt::TestInstance
709 {
710 public:
711 								PushDescriptorBufferComputeTestInstance		(Context& context, const TestParams& params);
712 	virtual						~PushDescriptorBufferComputeTestInstance	(void);
713 	void						init										(void);
714 	virtual tcu::TestStatus		iterate										(void);
715 	tcu::TestStatus				verifyOutput								(void);
716 
717 private:
718 	const TestParams			m_params;
719 	const PlatformInterface&	m_vkp;
720 	const Extensions			m_instanceExtensions;
721 	const CustomInstance		m_instance;
722 	const InstanceDriver&		m_vki;
723 	const VkPhysicalDevice		m_physicalDevice;
724 	const deUint32				m_queueFamilyIndex;
725 	const Extensions			m_deviceExtensions;
726 	const Unique<VkDevice>		m_device;
727 	const DeviceDriver			m_vkd;
728 	const VkQueue				m_queue;
729 	const VkDeviceSize			m_itemSize;
730 	SimpleAllocator				m_allocator;
731 	Move<VkShaderModule>		m_computeShaderModule;
732 	vector<VkBufferSp>			m_buffers;
733 	vector<AllocationSp>		m_bufferAllocs;
734 	Move<VkBuffer>				m_outputBuffer;
735 	de::MovePtr<Allocation>		m_outputBufferAlloc;
736 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
737 	Move<VkPipelineLayout>		m_pipelineLayout;
738 	Move<VkPipeline>			m_computePipeline;
739 	Move<VkCommandPool>			m_cmdPool;
740 	Move<VkCommandBuffer>		m_cmdBuffer;
741 	std::vector<tcu::Vec4>		m_testColors;
742 };
743 
PushDescriptorBufferComputeTestInstance(Context & context,const TestParams & params)744 PushDescriptorBufferComputeTestInstance::PushDescriptorBufferComputeTestInstance (Context& context, const TestParams& params)
745 	: vkt::TestInstance		(context)
746 	, m_params				(params)
747 	, m_vkp					(context.getPlatformInterface())
748 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
749 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
750 	, m_vki					(m_instance.getDriver())
751 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
752 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
753 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
754 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
755 	, m_vkd					(m_vkp, m_instance, *m_device)
756 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
757 	, m_itemSize			(calcItemSize(m_vki, m_physicalDevice))
758 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
759 {
760 }
761 
init(void)762 void PushDescriptorBufferComputeTestInstance::init (void)
763 {
764 	// Create pipeline layout
765 	{
766 		// Create descriptor set layout
767 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindings[]	=
768 		{
769 			{
770 				m_params.binding,				// uint32_t				binding;
771 				m_params.descriptorType,		// VkDescriptorType		descriptorType;
772 				1u,								// uint32_t				descriptorCount;
773 				VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
774 				DE_NULL							// const VkSampler*		pImmutableSamplers;
775 			},
776 			{
777 				m_params.binding + 1,				// uint32_t				binding;
778 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
779 				1u,									// uint32_t				descriptorCount;
780 				VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
781 				DE_NULL								// const VkSampler*		pImmutableSamplers;
782 			}
783 		};
784 
785 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
786 		{
787 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
788 			DE_NULL,													// const void*							pNext;
789 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
790 			2u,															// uint32_t								bindingCount;
791 			descriptorSetLayoutBindings									// const VkDescriptorSetLayoutBinding*	pBindings;
792 		};
793 
794 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
795 
796 		// Create pipeline layout
797 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams			=
798 		{
799 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
800 			DE_NULL,										// const void*					pNext;
801 			0u,												// VkPipelineLayoutCreateFlags	flags;
802 			1u,												// deUint32						descriptorSetCount;
803 			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
804 			0u,												// deUint32						pushConstantRangeCount;
805 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
806 		};
807 
808 		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
809 	}
810 
811 	// Fill the test colors table
812 	m_testColors.resize(m_params.numCalls);
813 	for (deUint32 colorIdx = 0; colorIdx < m_params.numCalls; colorIdx++)
814 	{
815 		if (colorIdx < DE_LENGTH_OF_ARRAY(defaultTestColors))
816 			m_testColors[colorIdx] = defaultTestColors[colorIdx];
817 		else
818 		{
819 			const float mix = static_cast<float>(colorIdx) / static_cast<float>(m_params.numCalls - 1);
820 
821 			// interpolate between first and last color, require these colors to be different
822 			DE_ASSERT(defaultTestColors[0] != defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1]);
823 			m_testColors[colorIdx] = defaultTestColors[0] * mix + defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1] * (1.0f - mix);
824 		}
825 	}
826 
827 	// Create buffers. One color value in each buffer.
828 	{
829 		for (deUint32 bufIdx = 0; bufIdx <  m_params.numCalls; bufIdx++)
830 		{
831 			const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
832 
833 			const VkBufferCreateInfo	bufferCreateInfo	=
834 			{
835 				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
836 				DE_NULL,								// const void*			pNext;
837 				0u,										// VkBufferCreateFlags	flags
838 				kSizeofVec4,							// VkDeviceSize			size;
839 				usageFlags,								// VkBufferUsageFlags	usage;
840 				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
841 				1u,										// deUint32				queueFamilyCount;
842 				&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
843 			};
844 
845 			m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
846 			m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
847 			VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
848 
849 			deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &m_testColors[bufIdx], static_cast<size_t>(kSizeofVec4));
850 			flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
851 		}
852 	}
853 
854 	// Create output buffer
855 	{
856 		const VkBufferCreateInfo bufferCreateInfo =
857 		{
858 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
859 			DE_NULL,								// const void*			pNext;
860 			0u,										// VkBufferCreateFlags	flags
861 			m_itemSize * m_params.numCalls,			// VkDeviceSize			size;
862 			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
863 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
864 			1u,										// deUint32				queueFamilyCount;
865 			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
866 		};
867 
868 		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
869 		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
870 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
871 	}
872 
873 	// Create shader
874 	{
875 		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
876 	}
877 
878 	// Create pipeline
879 	{
880 		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
881 		{
882 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
883 			DE_NULL,												// const void*						pNext;
884 			0u,														// VkPipelineShaderStageCreateFlags	flags;
885 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
886 			*m_computeShaderModule,									// VkShaderModule					module;
887 			"main",													// const char*						pName;
888 			DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
889 		};
890 
891 		const VkComputePipelineCreateInfo		createInfo		=
892 		{
893 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType;
894 			DE_NULL,												// const void*						pNext;
895 			0u,														// VkPipelineCreateFlags			flags;
896 			stageCreateInfo,										// VkPipelineShaderStageCreateInfo	stage;
897 			*m_pipelineLayout,										// VkPipelineLayout					layout;
898 			(VkPipeline)0,											// VkPipeline						basePipelineHandle;
899 			0u,														// int32_t							basePipelineIndex;
900 		};
901 
902 		m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
903 	}
904 
905 	// Create command pool
906 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
907 
908 	// Create command buffer
909 	{
910 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
911 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
912 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
913 
914 		// Dispatch: Each dispatch switches the input buffer.
915 		// Output buffer is exposed as a vec4 sized window.
916 		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
917 		{
918 			VkDescriptorBufferInfo descriptorBufferInfoUbo		=
919 			{
920 				**m_buffers[dispatchNdx],	// VkBuffer			buffer;
921 				0u,							// VkDeviceSize		offset;
922 				kSizeofVec4,				// VkDeviceSize		range;
923 			};
924 
925 			VkDescriptorBufferInfo descriptorBufferInfoOutput	=
926 			{
927 				*m_outputBuffer,			// VkBuffer			buffer;
928 				m_itemSize * dispatchNdx,	// VkDeviceSize		offset;
929 				kSizeofVec4,				// VkDeviceSize		range;
930 			};
931 
932 			VkWriteDescriptorSet writeDescriptorSets[] =
933 			{
934 				{
935 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
936 					DE_NULL,								// const void*						pNext;
937 					0u,										// VkDescriptorSet					dstSet;
938 					m_params.binding,						// uint32_t							dstBinding;
939 					0u,										// uint32_t							dstArrayElement;
940 					1u,										// uint32_t							descriptorCount;
941 					m_params.descriptorType,				// VkDescriptorType					descriptorType;
942 					DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
943 					&descriptorBufferInfoUbo,				// const VkDescriptorBufferInfo*	pBufferInfo;
944 					DE_NULL									// const VkBufferView*				pTexelBufferView;
945 				},
946 				{
947 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
948 					DE_NULL,								// const void*						pNext;
949 					0u,										// VkDescriptorSet					dstSet;
950 					m_params.binding + 1,					// uint32_t							dstBinding;
951 					0u,										// uint32_t							dstArrayElement;
952 					1u,										// uint32_t							descriptorCount;
953 					VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
954 					DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
955 					&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
956 					DE_NULL									// const VkBufferView*				pTexelBufferView;
957 				}
958 			};
959 
960 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 2, writeDescriptorSets);
961 			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
962 		}
963 
964 		endCommandBuffer(m_vkd, *m_cmdBuffer);
965 	}
966 }
967 
~PushDescriptorBufferComputeTestInstance(void)968 PushDescriptorBufferComputeTestInstance::~PushDescriptorBufferComputeTestInstance (void)
969 {
970 }
971 
iterate(void)972 tcu::TestStatus PushDescriptorBufferComputeTestInstance::iterate (void)
973 {
974 	init();
975 
976 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
977 
978 	return verifyOutput();
979 }
980 
verifyOutput(void)981 tcu::TestStatus PushDescriptorBufferComputeTestInstance::verifyOutput (void)
982 {
983 	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
984 
985 	// Verify result
986 	auto bufferPtr = reinterpret_cast<const char*>(m_outputBufferAlloc->getHostPtr());
987 	for (deUint32 i = 0; i < m_params.numCalls; ++i)
988 	{
989 		if (deMemCmp(&m_testColors[i], bufferPtr + (i * m_itemSize), static_cast<size_t>(kSizeofVec4)) != 0)
990 			TCU_FAIL("Output mismatch at output item " + de::toString(i));
991 	}
992 
993 	return tcu::TestStatus::pass("Output matches expected values");
994 }
995 
996 class PushDescriptorBufferComputeTest : public vkt::TestCase
997 {
998 public:
999 						PushDescriptorBufferComputeTest		(tcu::TestContext&	testContext,
1000 															 const string&		name,
1001 															 const string&		description,
1002 															 const TestParams&	params);
1003 						~PushDescriptorBufferComputeTest	(void);
1004 	void				initPrograms						(SourceCollections& sourceCollections) const;
1005 	TestInstance*		createInstance						(Context& context) const;
1006 
1007 protected:
1008 	const TestParams	m_params;
1009 };
1010 
PushDescriptorBufferComputeTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)1011 PushDescriptorBufferComputeTest::PushDescriptorBufferComputeTest (tcu::TestContext&	testContext,
1012 																  const string&		name,
1013 																  const string&		description,
1014 																  const TestParams&	params)
1015 	: vkt::TestCase	(testContext, name, description)
1016 	, m_params		(params)
1017 {
1018 }
1019 
~PushDescriptorBufferComputeTest(void)1020 PushDescriptorBufferComputeTest::~PushDescriptorBufferComputeTest (void)
1021 {
1022 }
1023 
createInstance(Context & context) const1024 TestInstance* PushDescriptorBufferComputeTest::createInstance (Context& context) const
1025 {
1026 	return new PushDescriptorBufferComputeTestInstance(context, m_params);
1027 }
1028 
initPrograms(SourceCollections & sourceCollections) const1029 void PushDescriptorBufferComputeTest::initPrograms (SourceCollections& sourceCollections) const
1030 {
1031 	const string	bufferType	= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "buffer";
1032 	const string	computeSrc	=
1033 		"#version 450\n"
1034 		"layout(set = 0, binding = " + de::toString(m_params.binding) + ") " + bufferType + " Block\n"
1035 		"{\n"
1036 		"	vec4 color;\n"
1037 		"} inputData;\n"
1038 		"\n"
1039 		"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
1040 		"{\n"
1041 		"	vec4 color;\n"
1042 		"} outData;\n"
1043 		"\n"
1044 		"void main()\n"
1045 		"{\n"
1046 		"	outData.color = inputData.color;\n"
1047 		"}\n";
1048 
1049 	sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
1050 }
1051 
1052 class PushDescriptorImageGraphicsTestInstance : public vkt::TestInstance
1053 {
1054 public:
1055 								PushDescriptorImageGraphicsTestInstance		(Context& context, const TestParams& params);
1056 	virtual						~PushDescriptorImageGraphicsTestInstance	(void);
1057 	void						init										(void);
1058 	virtual tcu::TestStatus		iterate										(void);
1059 	tcu::TestStatus				verifyImage									(void);
1060 
1061 private:
1062 	const TestParams				m_params;
1063 	const PlatformInterface&		m_vkp;
1064 	const Extensions				m_instanceExtensions;
1065 	const CustomInstance			m_instance;
1066 	const InstanceDriver&			m_vki;
1067 	const VkPhysicalDevice			m_physicalDevice;
1068 	const deUint32					m_queueFamilyIndex;
1069 	const Extensions				m_deviceExtensions;
1070 	const Unique<VkDevice>			m_device;
1071 	const DeviceDriver				m_vkd;
1072 	const VkQueue					m_queue;
1073 	SimpleAllocator					m_allocator;
1074 	const tcu::UVec2				m_renderSize;
1075 	const tcu::UVec2				m_textureSize;
1076 	const VkFormat					m_colorFormat;
1077 	Move<VkImage>					m_colorImage;
1078 	de::MovePtr<Allocation>			m_colorImageAlloc;
1079 	Move<VkImageView>				m_colorAttachmentView;
1080 	vector<VkImageSp>				m_textureImages;
1081 	vector<AllocationSp>			m_textureImageAllocs;
1082 	vector<VkImageViewSp>			m_textureViews;
1083 	Move<VkSampler>					m_whiteBorderSampler;
1084 	Move<VkSampler>					m_blackBorderSampler;
1085 	Move<VkRenderPass>				m_renderPass;
1086 	Move<VkFramebuffer>				m_framebuffer;
1087 	Move<VkShaderModule>			m_vertexShaderModule;
1088 	Move<VkShaderModule>			m_fragmentShaderModule;
1089 	Move<VkBuffer>					m_vertexBuffer;
1090 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
1091 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
1092 	Move<VkPipelineLayout>			m_preRasterizationStatePipelineLayout;
1093 	Move<VkPipelineLayout>			m_fragmentStatePipelineLayout;
1094 	GraphicsPipelineWrapper			m_graphicsPipeline;
1095 	Move<VkCommandPool>				m_cmdPool;
1096 	Move<VkCommandBuffer>			m_cmdBuffer;
1097 	vector<Vertex4Tex4>				m_vertices;
1098 };
1099 
PushDescriptorImageGraphicsTestInstance(Context & context,const TestParams & params)1100 PushDescriptorImageGraphicsTestInstance::PushDescriptorImageGraphicsTestInstance (Context& context, const TestParams& params)
1101 	: vkt::TestInstance		(context)
1102 	, m_params				(params)
1103 	, m_vkp					(context.getPlatformInterface())
1104 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
1105 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
1106 	, m_vki					(m_instance.getDriver())
1107 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
1108 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
1109 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
1110 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
1111 	, m_vkd					(m_vkp, m_instance, *m_device)
1112 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
1113 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
1114 	, m_renderSize			(32, 32)
1115 	, m_textureSize			(32, 32)
1116 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
1117 	, m_graphicsPipeline	(m_vkd, *m_device, params.pipelineConstructionType)
1118 	, m_vertices			(createTexQuads(params.numCalls, 0.25f))
1119 {
1120 }
1121 
init(void)1122 void PushDescriptorImageGraphicsTestInstance::init (void)
1123 {
1124 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
1125 
1126 	// Create color image
1127 	{
1128 
1129 		const VkImageCreateInfo		colorImageParams		=
1130 		{
1131 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
1132 			DE_NULL,																// const void*				pNext;
1133 			0u,																		// VkImageCreateFlags		flags;
1134 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
1135 			m_colorFormat,															// VkFormat					format;
1136 			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
1137 			1u,																		// deUint32					mipLevels;
1138 			1u,																		// deUint32					arrayLayers;
1139 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
1140 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
1141 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
1142 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
1143 			1u,																		// deUint32					queueFamilyIndexCount;
1144 			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
1145 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
1146 		};
1147 
1148 		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);
1149 
1150 		// Allocate and bind color image memory
1151 		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
1152 		VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1153 	}
1154 
1155 	// Create color attachment view
1156 	{
1157 		const VkImageViewCreateInfo colorAttachmentViewParams =
1158 		{
1159 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
1160 			DE_NULL,										// const void*				pNext;
1161 			0u,												// VkImageViewCreateFlags	flags;
1162 			*m_colorImage,									// VkImage					image;
1163 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
1164 			m_colorFormat,									// VkFormat					format;
1165 			componentMappingRGBA,							// VkChannelMapping			channels;
1166 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
1167 		};
1168 
1169 		m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
1170 	}
1171 
1172 	// Create texture images
1173 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
1174 	{
1175 		VkImageUsageFlags			usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1176 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1177 			usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
1178 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1179 			usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
1180 
1181 		const VkImageCreateInfo		textureImageParams	=
1182 		{
1183 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
1184 			DE_NULL,										// const void*				pNext;
1185 			0u,												// VkImageCreateFlags		flags;
1186 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
1187 			m_colorFormat,									// VkFormat					format;
1188 			{ m_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
1189 			1u,												// deUint32					mipLevels;
1190 			1u,												// deUint32					arrayLayers;
1191 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
1192 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
1193 			usageFlags,										// VkImageUsageFlags		usage;
1194 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
1195 			1u,												// deUint32					queueFamilyIndexCount;
1196 			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
1197 			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
1198 		};
1199 
1200 		m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
1201 
1202 		// Allocate and bind texture image memory
1203 		m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
1204 		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
1205 	}
1206 
1207 	// Create texture image views
1208 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
1209 	{
1210 		const VkImageViewCreateInfo textureViewParams =
1211 		{
1212 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
1213 			DE_NULL,										// const void*				pNext;
1214 			0u,												// VkImageViewCreateFlags	flags;
1215 			**m_textureImages[texIdx],						// VkImage					image;
1216 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
1217 			m_colorFormat,									// VkFormat					format;
1218 			componentMappingRGBA,							// VkChannelMapping			channels;
1219 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
1220 		};
1221 
1222 		m_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
1223 	}
1224 
1225 	VkClearValue	clearValues[2];
1226 	clearValues[0].color.float32[0] = 0.0f;
1227 	clearValues[0].color.float32[1] = 1.0f;
1228 	clearValues[0].color.float32[2] = 0.0f;
1229 	clearValues[0].color.float32[3] = 1.0f;
1230 	clearValues[1].color.float32[0] = 1.0f;
1231 	clearValues[1].color.float32[1] = 0.0f;
1232 	clearValues[1].color.float32[2] = 0.0f;
1233 	clearValues[1].color.float32[3] = 1.0f;
1234 
1235 	const VkImageLayout	textureImageLayout	= (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
1236 											  VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1237 
1238 	// Clear textures
1239 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
1240 	{
1241 		const VkImageAspectFlags	aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
1242 		Move<VkCommandPool>			cmdPool;
1243 		Move<VkCommandBuffer>		cmdBuffer;
1244 
1245 		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
1246 		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1247 
1248 		const VkImageMemoryBarrier preImageBarrier =
1249 		{
1250 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
1251 			DE_NULL,								// const void*				pNext;
1252 			0u,										// VkAccessFlags			srcAccessMask;
1253 			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
1254 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
1255 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
1256 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
1257 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
1258 			**m_textureImages[texIdx],				// VkImage					image;
1259 			{										// VkImageSubresourceRange	subresourceRange;
1260 				aspectMask,							// VkImageAspect			aspect;
1261 				0u,									// deUint32					baseMipLevel;
1262 				1u,									// deUint32					mipLevels;
1263 				0u,									// deUint32					baseArraySlice;
1264 				1u									// deUint32					arraySize;
1265 			}
1266 		};
1267 
1268 		const VkImageMemoryBarrier	postImageBarrier	=
1269 		{
1270 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1271 			DE_NULL,									// const void*				pNext;
1272 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1273 			VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
1274 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1275 			textureImageLayout,							// VkImageLayout			newLayout;
1276 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1277 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1278 			**m_textureImages[texIdx],					// VkImage					image;
1279 			{											// VkImageSubresourceRange	subresourceRange;
1280 				aspectMask,								// VkImageAspect			aspect;
1281 				0u,										// deUint32					baseMipLevel;
1282 				1u,										// deUint32					mipLevels;
1283 				0u,										// deUint32					baseArraySlice;
1284 				1u										// deUint32					arraySize;
1285 			}
1286 		};
1287 
1288 		const VkImageSubresourceRange clearRange	=
1289 		{
1290 			aspectMask,	// VkImageAspectFlags	aspectMask;
1291 			0u,			// deUint32				baseMipLevel;
1292 			1u,			// deUint32				levelCount;
1293 			0u,			// deUint32				baseArrayLayer;
1294 			1u			// deUint32				layerCount;
1295 		};
1296 
1297 		beginCommandBuffer(m_vkd, *cmdBuffer);
1298 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
1299 		m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
1300 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
1301 		endCommandBuffer(m_vkd, *cmdBuffer);
1302 
1303 		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
1304 	}
1305 
1306 	// Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
1307 	{
1308 		VkSamplerCreateInfo samplerParams =
1309 		{
1310 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType		sType;
1311 			DE_NULL,									// const void*			pNext;
1312 			0u,											// VkSamplerCreateFlags	flags;
1313 			VK_FILTER_NEAREST,							// VkFilter				magFilter;
1314 			VK_FILTER_NEAREST,							// VkFilter				minFilter;
1315 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode	mipmapMode;
1316 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeU;
1317 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeV;
1318 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeW;
1319 			0.0f,										// float				mipLodBias;
1320 			VK_FALSE,									// VkBool32				anisotropyEnable;
1321 			0.0f,										// float				maxAnisotropy;
1322 			VK_FALSE,									// VkBool32				compareEnable;
1323 			VK_COMPARE_OP_NEVER,						// VkCompareOp			compareOp;
1324 			0.0f,										// float				minLod;
1325 			0.0f,										// float				maxLod;
1326 			VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,			// VkBorderColor		borderColor;
1327 			VK_FALSE									// VkBool32				unnormalizedCoordinates;
1328 		};
1329 
1330 		m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
1331 		samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
1332 		m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
1333 	}
1334 
1335 	// Create render pass
1336 	{
1337 		const VkAttachmentDescription	attachmentDescription	=
1338 		{
1339 			(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
1340 			VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
1341 			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
1342 			VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp			loadOp
1343 			VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
1344 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
1345 			VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
1346 			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout				initialLayout
1347 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout				finalLayout
1348 		};
1349 
1350 		const VkAttachmentReference		resultAttachmentRef		=
1351 		{
1352 			0u,											// deUint32			attachment
1353 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
1354 		};
1355 
1356 		const VkSubpassDescription		subpassDescription		=
1357 		{
1358 			(VkSubpassDescriptionFlags)0,				// VkSubpassDescriptionFlags	flags
1359 			VK_PIPELINE_BIND_POINT_GRAPHICS,			// VkPipelineBindPoint			pipelineBindPoint
1360 			0u,											// deUint32						inputAttachmentCount
1361 			DE_NULL,									// const VkAttachmentReference*	pInputAttachments
1362 			1u,											// deUint32						colorAttachmentCount
1363 			&resultAttachmentRef,						// const VkAttachmentReference*	pColorAttachments
1364 			DE_NULL,									// const VkAttachmentReference*	pResolveAttachments
1365 			DE_NULL,									// const VkAttachmentReference*	pDepthStencilAttachment
1366 			0u,											// deUint32						preserveAttachmentCount
1367 			DE_NULL										// const deUint32*				pPreserveAttachments
1368 		};
1369 
1370 		const VkRenderPassCreateInfo	renderPassInfo			=
1371 		{
1372 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureTypei					sType
1373 			DE_NULL,									// const void*						pNext
1374 			(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags			flags
1375 			1u,											// deUint32							attachmentCount
1376 			&attachmentDescription,						// const VkAttachmentDescription*	pAttachments
1377 			1u,											// deUint32							subpassCount
1378 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses
1379 			0u,											// deUint32							dependencyCount
1380 			DE_NULL										// const VkSubpassDependency*		pDependencies
1381 		};
1382 
1383 		m_renderPass = createRenderPass(m_vkd, *m_device, &renderPassInfo);
1384 	}
1385 
1386 	// Create framebuffer
1387 	{
1388 		const VkImageView				attachmentBindInfos[]	=
1389 		{
1390 			*m_colorAttachmentView
1391 		};
1392 
1393 		const VkFramebufferCreateInfo	framebufferParams		=
1394 		{
1395 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
1396 			DE_NULL,									// const void*				pNext;
1397 			0u,											// VkFramebufferCreateFlags	flags;
1398 			*m_renderPass,								// VkRenderPass				renderPass;
1399 			1u,											// deUint32					attachmentCount;
1400 			attachmentBindInfos,						// const VkImageView*		pAttachments;
1401 			(deUint32)m_renderSize.x(),					// deUint32					width;
1402 			(deUint32)m_renderSize.y(),					// deUint32					height;
1403 			1u											// deUint32					layers;
1404 		};
1405 
1406 		m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
1407 	}
1408 
1409 	// Create pipeline layout
1410 	{
1411 		// Create descriptor set layout
1412 		vector<VkDescriptorSetLayoutBinding>	layoutBindings;
1413 
1414 		switch(m_params.descriptorType)
1415 		{
1416 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1417 				{
1418 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
1419 					{
1420 						m_params.binding,							// uint32_t				binding;
1421 						VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType;
1422 						1u,											// uint32_t				descriptorCount;
1423 						VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags;
1424 						DE_NULL										// const VkSampler*		pImmutableSamplers;
1425 					};
1426 					layoutBindings.push_back(descriptorSetLayoutBinding);
1427 				}
1428 				break;
1429 
1430 			case VK_DESCRIPTOR_TYPE_SAMPLER:
1431 				{
1432 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
1433 					{
1434 						m_params.binding,				// uint32_t				binding;
1435 						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
1436 						1u,								// uint32_t				descriptorCount;
1437 						VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
1438 						DE_NULL							// const VkSampler*		pImmutableSamplers;
1439 					};
1440 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
1441 					{
1442 						m_params.binding + 1,				// uint32_t				binding;
1443 						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
1444 						1u,									// uint32_t				descriptorCount;
1445 						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
1446 						DE_NULL								// const VkSampler*		pImmutableSamplers;
1447 					};
1448 					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
1449 					layoutBindings.push_back(descriptorSetLayoutBindingTex);
1450 				}
1451 				break;
1452 
1453 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1454 				{
1455 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
1456 					{
1457 						m_params.binding + 1,			// uint32_t				binding;
1458 						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
1459 						1u,								// uint32_t				descriptorCount;
1460 						VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
1461 						DE_NULL							// const VkSampler*		pImmutableSamplers;
1462 					};
1463 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
1464 					{
1465 						m_params.binding,					// uint32_t				binding;
1466 						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
1467 						1u,									// uint32_t				descriptorCount;
1468 						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
1469 						DE_NULL								// const VkSampler*		pImmutableSamplers;
1470 					};
1471 					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
1472 					layoutBindings.push_back(descriptorSetLayoutBindingTex);
1473 				}
1474 				break;
1475 
1476 			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1477 				{
1478 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
1479 					{
1480 						m_params.binding,					// uint32_t				binding;
1481 						VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType		descriptorType;
1482 						1u,									// uint32_t				descriptorCount;
1483 						VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags;
1484 						DE_NULL								// const VkSampler*		pImmutableSamplers;
1485 					};
1486 					layoutBindings.push_back(descriptorSetLayoutBinding);
1487 				}
1488 				break;
1489 
1490 			default:
1491 				DE_FATAL("unexpected descriptor type");
1492 				break;
1493 		}
1494 
1495 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
1496 		{
1497 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
1498 			DE_NULL,													// const void*							pNext;
1499 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
1500 			(deUint32)layoutBindings.size(),							// uint32_t								bindingCount;
1501 			layoutBindings.data()										// const VkDescriptorSetLayoutBinding*	pBindings;
1502 		};
1503 
1504 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
1505 
1506 		// Create pipeline layout
1507 		VkPipelineLayoutCreateFlags	pipelineLayoutFlags = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
1508 		VkPipelineLayoutCreateInfo	pipelineLayoutParams
1509 		{
1510 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
1511 			DE_NULL,										// const void*					pNext;
1512 			pipelineLayoutFlags,							// VkPipelineLayoutCreateFlags	flags;
1513 			0u,												// deUint32						setLayoutCount;
1514 			DE_NULL,										// const VkDescriptorSetLayout*	pSetLayouts;
1515 			0u,												// deUint32						pushConstantRangeCount;
1516 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
1517 		};
1518 
1519 		m_preRasterizationStatePipelineLayout	= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
1520 		pipelineLayoutParams.setLayoutCount		= 1u;
1521 		pipelineLayoutParams.pSetLayouts		= &(*m_descriptorSetLayout);
1522 		m_fragmentStatePipelineLayout			= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
1523 	}
1524 
1525 	// Create shaders
1526 	{
1527 		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
1528 		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
1529 	}
1530 
1531 	// Create pipeline
1532 	{
1533 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
1534 		{
1535 			0u,							// deUint32					binding;
1536 			sizeof(Vertex4Tex4),		// deUint32					strideInBytes;
1537 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
1538 		};
1539 
1540 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[]	=
1541 		{
1542 			{
1543 				0u,										// deUint32	location;
1544 				0u,										// deUint32	binding;
1545 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
1546 				0u										// deUint32	offsetInBytes;
1547 			},
1548 			{
1549 				1u,										// deUint32	location;
1550 				0u,										// deUint32	binding;
1551 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
1552 				DE_OFFSET_OF(Vertex4Tex4, texCoord),	// deUint32	offset;
1553 			}
1554 		};
1555 
1556 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
1557 		{
1558 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
1559 			DE_NULL,													// const void*								pNext;
1560 			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
1561 			1u,															// deUint32									bindingCount;
1562 			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
1563 			2u,															// deUint32									attributeCount;
1564 			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
1565 		};
1566 
1567 		const vector<VkViewport>					viewports		{ makeViewport(m_renderSize) };
1568 		const vector<VkRect2D>						scissors		{ makeRect2D(m_renderSize) };
1569 
1570 		m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
1571 						  .setDefaultRasterizationState()
1572 						  .setDefaultDepthStencilState()
1573 						  .setDefaultMultisampleState()
1574 						  .setDefaultColorBlendState()
1575 						  .setupVertexInputState(&vertexInputStateParams)
1576 						  .setupPreRasterizationShaderState(viewports,
1577 															scissors,
1578 															*m_preRasterizationStatePipelineLayout,
1579 															*m_renderPass,
1580 															0u,
1581 															*m_vertexShaderModule)
1582 						  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
1583 						  .setupFragmentOutputState(*m_renderPass)
1584 						  .buildPipeline();
1585 	}
1586 
1587 	// Create vertex buffer
1588 	{
1589 		const VkBufferCreateInfo vertexBufferParams =
1590 		{
1591 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
1592 			DE_NULL,													// const void*			pNext;
1593 			0u,															// VkBufferCreateFlags	flags;
1594 			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
1595 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
1596 			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
1597 			1u,															// deUint32				queueFamilyCount;
1598 			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
1599 		};
1600 
1601 		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
1602 		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1603 
1604 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1605 
1606 		// Load vertices into vertex buffer
1607 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
1608 		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
1609 	}
1610 
1611 	// Create command pool
1612 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
1613 
1614 	// Create command buffer
1615 	{
1616 		const VkClearValue	attachmentClearValue	= defaultClearValue(m_colorFormat);
1617 		const VkDeviceSize	vertexBufferOffset		= 0;
1618 
1619 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1620 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
1621 		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
1622 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
1623 		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1624 
1625 		// Draw quads. Switch sampler or image view depending on the test.
1626 		vector<VkSampler>	samplers;
1627 		vector<VkImageView> imageViews;
1628 
1629 		samplers.push_back(*m_whiteBorderSampler);
1630 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1631 		{
1632 			// Vary sampler between draws
1633 			samplers.push_back(*m_blackBorderSampler);
1634 		}
1635 		else
1636 		{
1637 			// Usa a single sampler
1638 			samplers.push_back(*m_whiteBorderSampler);
1639 		}
1640 
1641 		imageViews.push_back(**m_textureViews[0]);
1642 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1643 		{
1644 			// Vary image view between draws
1645 			imageViews.push_back(**m_textureViews[1]);
1646 		}
1647 		else
1648 		{
1649 			// Usa a single image view
1650 			imageViews.push_back(**m_textureViews[0]);
1651 		}
1652 
1653 		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
1654 		{
1655 			VkDescriptorImageInfo	descriptorImageInfo	=
1656 			{
1657 				samplers[quadNdx],							// VkSampler		sampler;
1658 				imageViews[quadNdx],						// VkImageView		imageView;
1659 				textureImageLayout							// VkImageLayout	imageLayout;
1660 			};
1661 
1662 			VkWriteDescriptorSet	writeDescriptorSet	=
1663 			{
1664 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
1665 				DE_NULL,								// const void*						pNext;
1666 				0u,										// VkDescriptorSet					dstSet;
1667 				m_params.binding,						// uint32_t							dstBinding;
1668 				0u,										// uint32_t							dstArrayElement;
1669 				1u,										// uint32_t							descriptorCount;
1670 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
1671 				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
1672 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
1673 				DE_NULL									// const VkBufferView*				pTexelBufferView;
1674 			};
1675 
1676 			vector<VkWriteDescriptorSet> writeDescriptorSets;
1677 			writeDescriptorSets.push_back(writeDescriptorSet);
1678 
1679 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1680 			{
1681 				// Sampler also needs an image.
1682 				writeDescriptorSet.dstBinding++;
1683 				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1684 				writeDescriptorSets.push_back(writeDescriptorSet);
1685 			}
1686 			else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1687 			{
1688 				// Image also needs a sampler.
1689 				writeDescriptorSet.dstBinding++;
1690 				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1691 				writeDescriptorSets.push_back(writeDescriptorSet);
1692 			}
1693 
1694 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
1695 			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
1696 		}
1697 
1698 		endRenderPass(m_vkd, *m_cmdBuffer);
1699 		endCommandBuffer(m_vkd, *m_cmdBuffer);
1700 	}
1701 }
1702 
~PushDescriptorImageGraphicsTestInstance(void)1703 PushDescriptorImageGraphicsTestInstance::~PushDescriptorImageGraphicsTestInstance (void)
1704 {
1705 }
1706 
iterate(void)1707 tcu::TestStatus PushDescriptorImageGraphicsTestInstance::iterate (void)
1708 {
1709 	init();
1710 
1711 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
1712 
1713 	return verifyImage();
1714 }
1715 
verifyImage(void)1716 tcu::TestStatus PushDescriptorImageGraphicsTestInstance::verifyImage (void)
1717 {
1718 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
1719 	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
1720 	const ColorVertexShader		vertexShader;
1721 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
1722 	const rr::Program			program			(&vertexShader, &fragmentShader);
1723 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1724 	bool						compareOk		= false;
1725 
1726 	// Render reference image
1727 	{
1728 		vector<Vertex4RGBA>	refQuadsOuter	= createQuads(m_params.numCalls, 0.25f);
1729 		vector<Vertex4RGBA>	refQuadsInner	= createQuads(m_params.numCalls, 0.25f * 0.8f);
1730 		tcu::Vec4			outerColor[2];
1731 		tcu::Vec4			innerColor[2];
1732 		const bool			hasBorder		= m_params.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1733 
1734 		if (hasBorder)
1735 		{
1736 			outerColor[0] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1737 			innerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1738 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1739 				outerColor[1] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1740 			else
1741 				outerColor[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1742 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1743 				innerColor[1] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1744 			else
1745 				innerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1746 		}
1747 		else
1748 		{
1749 			outerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1750 			outerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1751 		}
1752 
1753 		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
1754 			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
1755 			{
1756 				const deUint32 idx = quadIdx * 6 + vertexIdx;
1757 				refQuadsOuter[idx].color.xyzw() = outerColor[quadIdx];
1758 				refQuadsInner[idx].color.xyzw() = innerColor[quadIdx];
1759 			}
1760 
1761 		if (hasBorder)
1762 			refQuadsOuter.insert(refQuadsOuter.end(), refQuadsInner.begin(), refQuadsInner.end());
1763 
1764 		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
1765 						 rr::PRIMITIVETYPE_TRIANGLES, refQuadsOuter);
1766 	}
1767 
1768 	// Compare result with reference image
1769 	{
1770 		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
1771 
1772 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1773 															  "IntImageCompare",
1774 															  "Image comparison",
1775 															  refRenderer.getAccess(),
1776 															  result->getAccess(),
1777 															  tcu::UVec4(2, 2, 2, 2),
1778 															  tcu::IVec3(1, 1, 0),
1779 															  true,
1780 															  tcu::COMPARE_LOG_RESULT);
1781 	}
1782 
1783 	if (compareOk)
1784 		return tcu::TestStatus::pass("Result image matches reference");
1785 	else
1786 		return tcu::TestStatus::fail("Image mismatch");
1787 }
1788 
1789 class PushDescriptorImageGraphicsTest : public vkt::TestCase
1790 {
1791 public:
1792 						PushDescriptorImageGraphicsTest		(tcu::TestContext&	testContext,
1793 															 const string&		name,
1794 															 const string&		description,
1795 															 const TestParams&	params);
1796 						~PushDescriptorImageGraphicsTest	(void);
1797 
1798 	void				checkSupport						(Context& context) const;
1799 	void				initPrograms						(SourceCollections& sourceCollections) const;
1800 	TestInstance*		createInstance						(Context& context) const;
1801 
1802 protected:
1803 	const TestParams	m_params;
1804 };
1805 
PushDescriptorImageGraphicsTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)1806 PushDescriptorImageGraphicsTest::PushDescriptorImageGraphicsTest	(tcu::TestContext&	testContext,
1807 																	const string&		name,
1808 																	const string&		description,
1809 																	const TestParams&	params)
1810 	: vkt::TestCase	(testContext, name, description)
1811 	, m_params		(params)
1812 {
1813 }
1814 
~PushDescriptorImageGraphicsTest(void)1815 PushDescriptorImageGraphicsTest::~PushDescriptorImageGraphicsTest (void)
1816 {
1817 }
1818 
createInstance(Context & context) const1819 TestInstance* PushDescriptorImageGraphicsTest::createInstance (Context& context) const
1820 {
1821 	return new PushDescriptorImageGraphicsTestInstance(context, m_params);
1822 }
1823 
checkSupport(Context & context) const1824 void PushDescriptorImageGraphicsTest::checkSupport(Context& context) const
1825 {
1826 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
1827 }
1828 
initPrograms(SourceCollections & sourceCollections) const1829 void PushDescriptorImageGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
1830 {
1831 	const string	vertexSrc	=
1832 		"#version 450\n"
1833 		"layout(location = 0) in highp vec4 position;\n"
1834 		"layout(location = 1) in highp vec4 texcoordVtx;\n"
1835 		"layout(location = 0) out highp vec2 texcoordFrag;\n"
1836 		"\n"
1837 		"out gl_PerVertex { vec4 gl_Position; };\n"
1838 		"\n"
1839 		"void main()\n"
1840 		"{\n"
1841 		"	gl_Position = position;\n"
1842 		"	texcoordFrag = texcoordVtx.xy;\n"
1843 		"}\n";
1844 
1845 	sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
1846 
1847 	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1848 	{
1849 		const string	fragmentSrc	=
1850 			"#version 450\n"
1851 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
1852 			"layout(location = 0) out highp vec4 fragColor;\n"
1853 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
1854 			"\n"
1855 			"void main (void)\n"
1856 			"{\n"
1857 			"	fragColor = texture(combinedSampler, texcoordFrag);\n"
1858 			"}\n";
1859 
1860 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1861 	}
1862 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1863 	{
1864 		const string	fragmentSrc	=
1865 			"#version 450\n"
1866 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
1867 			"layout(location = 0) out highp vec4 fragColor;\n"
1868 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
1869 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
1870 			"\n"
1871 			"void main (void)\n"
1872 			"{\n"
1873 			"	fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
1874 			"}\n";
1875 
1876 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1877 	}
1878 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1879 	{
1880 		const string	fragmentSrc	=
1881 			"#version 450\n"
1882 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
1883 			"layout(location = 0) out highp vec4 fragColor;\n"
1884 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
1885 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
1886 			"\n"
1887 			"void main (void)\n"
1888 			"{\n"
1889 			"	fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
1890 			"}\n";
1891 
1892 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1893 	}
1894 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1895 	{
1896 		const string	fragmentSrc	=
1897 			"#version 450\n"
1898 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
1899 			"layout(location = 0) out highp vec4 fragColor;\n"
1900 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
1901 			"\n"
1902 			"void main (void)\n"
1903 			"{\n"
1904 			"	fragColor = imageLoad(storageImage, ivec2(0));\n"
1905 			"}\n";
1906 
1907 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1908 	}
1909 	else
1910 	{
1911 		DE_FATAL("Unexpected descriptor type");
1912 	}
1913 }
1914 
1915 class PushDescriptorImageComputeTestInstance : public vkt::TestInstance
1916 {
1917 public:
1918 								PushDescriptorImageComputeTestInstance	(Context& context, const TestParams& params);
1919 	virtual						~PushDescriptorImageComputeTestInstance	(void);
1920 	void						init									(void);
1921 	virtual tcu::TestStatus		iterate									(void);
1922 	tcu::TestStatus				verifyOutput							(void);
1923 
1924 private:
1925 	const TestParams			m_params;
1926 	const PlatformInterface&	m_vkp;
1927 	const Extensions			m_instanceExtensions;
1928 	const CustomInstance		m_instance;
1929 	const InstanceDriver&		m_vki;
1930 	const VkPhysicalDevice		m_physicalDevice;
1931 	const deUint32				m_queueFamilyIndex;
1932 	const Extensions			m_deviceExtensions;
1933 	const Unique<VkDevice>		m_device;
1934 	const DeviceDriver			m_vkd;
1935 	const VkQueue				m_queue;
1936 	const VkDeviceSize			m_itemSize;
1937 	const VkDeviceSize			m_blockSize;
1938 	SimpleAllocator				m_allocator;
1939 	const tcu::UVec2			m_textureSize;
1940 	const VkFormat				m_colorFormat;
1941 	Move<VkShaderModule>		m_computeShaderModule;
1942 	vector<VkImageSp>			m_textureImages;
1943 	vector<AllocationSp>		m_textureImageAllocs;
1944 	vector<VkImageViewSp>		m_textureViews;
1945 	Move<VkSampler>				m_whiteBorderSampler;
1946 	Move<VkSampler>				m_blackBorderSampler;
1947 	Move<VkBuffer>				m_outputBuffer;
1948 	de::MovePtr<Allocation>		m_outputBufferAlloc;
1949 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
1950 	Move<VkPipelineLayout>		m_pipelineLayout;
1951 	Move<VkPipeline>			m_computePipeline;
1952 	Move<VkCommandPool>			m_cmdPool;
1953 	Move<VkCommandBuffer>		m_cmdBuffer;
1954 	deUint32					m_outputBufferBinding;
1955 };
1956 
PushDescriptorImageComputeTestInstance(Context & context,const TestParams & params)1957 PushDescriptorImageComputeTestInstance::PushDescriptorImageComputeTestInstance (Context& context, const TestParams& params)
1958 	: vkt::TestInstance		(context)
1959 	, m_params				(params)
1960 	, m_vkp					(context.getPlatformInterface())
1961 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
1962 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
1963 	, m_vki					(m_instance.getDriver())
1964 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
1965 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT))
1966 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
1967 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
1968 	, m_vkd					(m_vkp, m_instance, *m_device)
1969 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
1970 	, m_itemSize			(calcItemSize(m_vki, m_physicalDevice, 2u))
1971 	, m_blockSize			(kSizeofVec4 * 2u)
1972 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
1973 	, m_textureSize			(32, 32)
1974 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
1975 	, m_outputBufferBinding	(0)
1976 {
1977 }
1978 
init(void)1979 void PushDescriptorImageComputeTestInstance::init (void)
1980 {
1981 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
1982 
1983 	// Create texture images
1984 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
1985 	{
1986 		VkImageUsageFlags			usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1987 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1988 			usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
1989 		if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1990 			usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
1991 
1992 		const VkImageCreateInfo		textureImageParams	=
1993 		{
1994 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
1995 			DE_NULL,										// const void*				pNext;
1996 			0u,												// VkImageCreateFlags		flags;
1997 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
1998 			m_colorFormat,									// VkFormat					format;
1999 			{ m_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
2000 			1u,												// deUint32					mipLevels;
2001 			1u,												// deUint32					arrayLayers;
2002 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
2003 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
2004 			usageFlags,										// VkImageUsageFlags		usage;
2005 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
2006 			1u,												// deUint32					queueFamilyIndexCount;
2007 			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
2008 			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
2009 		};
2010 
2011 		m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
2012 
2013 		// Allocate and bind texture image memory
2014 		m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
2015 		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
2016 	}
2017 
2018 	// Create texture image views
2019 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
2020 	{
2021 		const VkImageViewCreateInfo textureViewParams =
2022 		{
2023 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2024 			DE_NULL,										// const void*				pNext;
2025 			0u,												// VkImageViewCreateFlags	flags;
2026 			**m_textureImages[texIdx],						// VkImage					image;
2027 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2028 			m_colorFormat,									// VkFormat					format;
2029 			componentMappingRGBA,							// VkChannelMapping			channels;
2030 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2031 		};
2032 
2033 		m_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
2034 	}
2035 
2036 	VkClearValue	clearValues[2];
2037 	clearValues[0].color.float32[0] = 0.0f;
2038 	clearValues[0].color.float32[1] = 1.0f;
2039 	clearValues[0].color.float32[2] = 0.0f;
2040 	clearValues[0].color.float32[3] = 1.0f;
2041 	clearValues[1].color.float32[0] = 1.0f;
2042 	clearValues[1].color.float32[1] = 0.0f;
2043 	clearValues[1].color.float32[2] = 0.0f;
2044 	clearValues[1].color.float32[3] = 1.0f;
2045 
2046 	const VkImageLayout	textureImageLayout = (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
2047 											  VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2048 
2049 	// Clear textures
2050 	for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
2051 	{
2052 		const VkImageAspectFlags		aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
2053 		Move<VkCommandPool>				cmdPool;
2054 		Move<VkCommandBuffer>			cmdBuffer;
2055 
2056 		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
2057 		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2058 
2059 		const VkImageMemoryBarrier preImageBarrier =
2060 		{
2061 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
2062 			DE_NULL,								// const void*				pNext;
2063 			0u,										// VkAccessFlags			srcAccessMask;
2064 			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2065 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
2066 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
2067 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
2068 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
2069 			**m_textureImages[texIdx],				// VkImage					image;
2070 			{										// VkImageSubresourceRange	subresourceRange;
2071 				aspectMask,							// VkImageAspect			aspect;
2072 				0u,									// deUint32					baseMipLevel;
2073 				1u,									// deUint32					mipLevels;
2074 				0u,									// deUint32					baseArraySlice;
2075 				1u									// deUint32					arraySize;
2076 			}
2077 		};
2078 
2079 		const VkImageMemoryBarrier postImageBarrier =
2080 		{
2081 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2082 			DE_NULL,									// const void*				pNext;
2083 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2084 			VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
2085 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2086 			textureImageLayout,							// VkImageLayout			newLayout;
2087 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2088 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2089 			**m_textureImages[texIdx],					// VkImage					image;
2090 			{											// VkImageSubresourceRange	subresourceRange;
2091 				aspectMask,								// VkImageAspect			aspect;
2092 				0u,										// deUint32					baseMipLevel;
2093 				1u,										// deUint32					mipLevels;
2094 				0u,										// deUint32					baseArraySlice;
2095 				1u										// deUint32					arraySize;
2096 			}
2097 		};
2098 
2099 		const VkImageSubresourceRange clearRange	=
2100 		{
2101 			aspectMask,	// VkImageAspectFlags	aspectMask;
2102 			0u,			// deUint32				baseMipLevel;
2103 			1u,			// deUint32				levelCount;
2104 			0u,			// deUint32				baseArrayLayer;
2105 			1u			// deUint32				layerCount;
2106 		};
2107 
2108 		beginCommandBuffer(m_vkd, *cmdBuffer);
2109 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
2110 		m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
2111 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
2112 		endCommandBuffer(m_vkd, *cmdBuffer);
2113 
2114 		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
2115 	}
2116 
2117 	// Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
2118 	{
2119 		VkSamplerCreateInfo samplerParams =
2120 		{
2121 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType		sType;
2122 			DE_NULL,									// const void*			pNext;
2123 			0u,											// VkSamplerCreateFlags	flags;
2124 			VK_FILTER_NEAREST,							// VkFilter				magFilter;
2125 			VK_FILTER_NEAREST,							// VkFilter				minFilter;
2126 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode	mipmapMode;
2127 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeU;
2128 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeV;
2129 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,	// VkSamplerAddressMode	addressModeW;
2130 			0.0f,										// float				mipLodBias;
2131 			VK_FALSE,									// VkBool32				anisotropyEnable;
2132 			0.0f,										// float				maxAnisotropy;
2133 			VK_FALSE,									// VkBool32				compareEnable;
2134 			VK_COMPARE_OP_NEVER,						// VkCompareOp			compareOp;
2135 			0.0f,										// float				minLod;
2136 			0.0f,										// float				maxLod;
2137 			VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,			// VkBorderColor		borderColor;
2138 			VK_FALSE									// VkBool32				unnormalizedCoordinates;
2139 		};
2140 
2141 		m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
2142 		samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
2143 		m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
2144 	}
2145 
2146 	// Create pipeline layout
2147 	{
2148 		// Create descriptor set layout
2149 		vector<VkDescriptorSetLayoutBinding>	layoutBindings;
2150 
2151 		switch(m_params.descriptorType)
2152 		{
2153 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2154 				{
2155 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
2156 					{
2157 						m_params.binding,							// uint32_t				binding;
2158 						VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType;
2159 						1u,											// uint32_t				descriptorCount;
2160 						VK_SHADER_STAGE_COMPUTE_BIT,				// VkShaderStageFlags	stageFlags;
2161 						DE_NULL										// const VkSampler*		pImmutableSamplers;
2162 					};
2163 					layoutBindings.push_back(descriptorSetLayoutBinding);
2164 					m_outputBufferBinding = m_params.binding + 1;
2165 				}
2166 				break;
2167 
2168 			case VK_DESCRIPTOR_TYPE_SAMPLER:
2169 				{
2170 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
2171 					{
2172 						m_params.binding,				// uint32_t				binding;
2173 						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
2174 						1u,								// uint32_t				descriptorCount;
2175 						VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
2176 						DE_NULL							// const VkSampler*		pImmutableSamplers;
2177 					};
2178 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
2179 					{
2180 						m_params.binding + 1,				// uint32_t				binding;
2181 						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
2182 						1u,									// uint32_t				descriptorCount;
2183 						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
2184 						DE_NULL								// const VkSampler*		pImmutableSamplers;
2185 					};
2186 					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
2187 					layoutBindings.push_back(descriptorSetLayoutBindingTex);
2188 					m_outputBufferBinding = m_params.binding + 2;
2189 				}
2190 				break;
2191 
2192 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2193 				{
2194 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingSampler	=
2195 					{
2196 						m_params.binding + 1,			// uint32_t				binding;
2197 						VK_DESCRIPTOR_TYPE_SAMPLER,		// VkDescriptorType		descriptorType;
2198 						1u,								// uint32_t				descriptorCount;
2199 						VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
2200 						DE_NULL							// const VkSampler*		pImmutableSamplers;
2201 					};
2202 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingTex	=
2203 					{
2204 						m_params.binding,					// uint32_t				binding;
2205 						VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,	// VkDescriptorType		descriptorType;
2206 						1u,									// uint32_t				descriptorCount;
2207 						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
2208 						DE_NULL								// const VkSampler*		pImmutableSamplers;
2209 					};
2210 					layoutBindings.push_back(descriptorSetLayoutBindingSampler);
2211 					layoutBindings.push_back(descriptorSetLayoutBindingTex);
2212 					m_outputBufferBinding = m_params.binding + 2;
2213 				}
2214 				break;
2215 
2216 			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2217 				{
2218 					const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
2219 					{
2220 						m_params.binding,					// uint32_t				binding;
2221 						VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,	// VkDescriptorType		descriptorType;
2222 						1u,									// uint32_t				descriptorCount;
2223 						VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
2224 						DE_NULL								// const VkSampler*		pImmutableSamplers;
2225 					};
2226 					layoutBindings.push_back(descriptorSetLayoutBinding);
2227 					m_outputBufferBinding = m_params.binding + 1;
2228 				}
2229 				break;
2230 
2231 			default:
2232 				DE_FATAL("unexpected descriptor type");
2233 				break;
2234 		}
2235 
2236 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindingOutputBuffer	=
2237 		{
2238 			m_outputBufferBinding,				// uint32_t				binding;
2239 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
2240 			1u,									// uint32_t				descriptorCount;
2241 			VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
2242 			DE_NULL								// const VkSampler*		pImmutableSamplers;
2243 		};
2244 
2245 		layoutBindings.push_back(descriptorSetLayoutBindingOutputBuffer);
2246 
2247 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
2248 		{
2249 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
2250 			DE_NULL,													// const void*							pNext;
2251 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
2252 			(deUint32)layoutBindings.size(),							// uint32_t								bindingCount;
2253 			layoutBindings.data()										// const VkDescriptorSetLayoutBinding*	pBindings;
2254 		};
2255 
2256 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
2257 
2258 		// Create pipeline layout
2259 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams			=
2260 		{
2261 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
2262 			DE_NULL,										// const void*					pNext;
2263 			0u,												// VkPipelineLayoutCreateFlags	flags;
2264 			1u,												// deUint32						descriptorSetCount;
2265 			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
2266 			0u,												// deUint32						pushConstantRangeCount;
2267 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
2268 		};
2269 
2270 		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
2271 	}
2272 
2273 	// Create output buffer
2274 	{
2275 		DE_ASSERT(m_params.numCalls <= 2u);
2276 
2277 		const VkBufferCreateInfo bufferCreateInfo =
2278 		{
2279 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
2280 			DE_NULL,								// const void*			pNext;
2281 			0u,										// VkBufferCreateFlags	flags
2282 			m_itemSize * 2u,						// VkDeviceSize			size;
2283 			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
2284 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2285 			1u,										// deUint32				queueFamilyCount;
2286 			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
2287 		};
2288 
2289 		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
2290 		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
2291 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
2292 	}
2293 
2294 	// Create shader
2295 	{
2296 		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
2297 	}
2298 
2299 	// Create pipeline
2300 	{
2301 		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
2302 		{
2303 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
2304 			DE_NULL,												// const void*						pNext;
2305 			0u,														// VkPipelineShaderStageCreateFlags	flags;
2306 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
2307 			*m_computeShaderModule,									// VkShaderModule					module;
2308 			"main",													// const char*						pName;
2309 			DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
2310 		};
2311 
2312 		const VkComputePipelineCreateInfo		createInfo		=
2313 		{
2314 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType;
2315 			DE_NULL,												// const void*						pNext;
2316 			0u,														// VkPipelineCreateFlags			flags;
2317 			stageCreateInfo,										// VkPipelineShaderStageCreateInfo	stage;
2318 			*m_pipelineLayout,										// VkPipelineLayout					layout;
2319 			(VkPipeline)0,											// VkPipeline						basePipelineHandle;
2320 			0u,														// int32_t							basePipelineIndex;
2321 		};
2322 
2323 		m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
2324 	}
2325 
2326 	// Create command pool
2327 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
2328 
2329 	// Create command buffer
2330 	{
2331 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2332 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
2333 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
2334 
2335 		// Dispatch: Each dispatch switches the input image.
2336 		// Output buffer is exposed as a 2 x vec4 sized window.
2337 		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
2338 		{
2339 			vector<VkSampler>	samplers;
2340 			vector<VkImageView> imageViews;
2341 
2342 			samplers.push_back(*m_whiteBorderSampler);
2343 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2344 			{
2345 				// Vary sampler between draws
2346 				samplers.push_back(*m_blackBorderSampler);
2347 			}
2348 			else
2349 			{
2350 				// Usa a single sampler
2351 				samplers.push_back(*m_whiteBorderSampler);
2352 			}
2353 
2354 			imageViews.push_back(**m_textureViews[0]);
2355 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2356 			{
2357 				// Vary image view between draws
2358 				imageViews.push_back(**m_textureViews[1]);
2359 			}
2360 			else
2361 			{
2362 				// Usa a single image view
2363 				imageViews.push_back(**m_textureViews[0]);
2364 			}
2365 
2366 			const VkDescriptorImageInfo	descriptorImageInfo	=
2367 			{
2368 				samplers[dispatchNdx],					// VkSampler		sampler;
2369 				imageViews[dispatchNdx],				// VkImageView		imageView;
2370 				textureImageLayout						// VkImageLayout	imageLayout;
2371 			};
2372 
2373 			VkWriteDescriptorSet	writeDescriptorSet		=
2374 			{
2375 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
2376 				DE_NULL,								// const void*						pNext;
2377 				0u,										// VkDescriptorSet					dstSet;
2378 				m_params.binding,						// uint32_t							dstBinding;
2379 				0u,										// uint32_t							dstArrayElement;
2380 				1u,										// uint32_t							descriptorCount;
2381 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
2382 				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
2383 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
2384 				DE_NULL									// const VkBufferView*				pTexelBufferView;
2385 			};
2386 
2387 			vector<VkWriteDescriptorSet> writeDescriptorSets;
2388 			writeDescriptorSets.push_back(writeDescriptorSet);
2389 
2390 			if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2391 			{
2392 				// Sampler also needs an image.
2393 				writeDescriptorSet.dstBinding++;
2394 				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
2395 				writeDescriptorSets.push_back(writeDescriptorSet);
2396 			}
2397 			else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
2398 			{
2399 				// Image also needs a sampler.
2400 				writeDescriptorSet.dstBinding++;
2401 				writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
2402 				writeDescriptorSets.push_back(writeDescriptorSet);
2403 			}
2404 
2405 			const VkDescriptorBufferInfo descriptorBufferInfoOutput	=
2406 			{
2407 				*m_outputBuffer,			// VkBuffer		buffer;
2408 				m_itemSize * dispatchNdx,	// VkDeviceSize	offset;
2409 				m_blockSize,				// VkDeviceSize	range;
2410 			};
2411 
2412 			// Write output buffer descriptor set
2413 			const VkWriteDescriptorSet	writeDescriptorSetOutput	=
2414 			{
2415 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
2416 				DE_NULL,								// const void*						pNext;
2417 				0u,										// VkDescriptorSet					dstSet;
2418 				m_outputBufferBinding,					// uint32_t							dstBinding;
2419 				0u,										// uint32_t							dstArrayElement;
2420 				1u,										// uint32_t							descriptorCount;
2421 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
2422 				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
2423 				&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
2424 				DE_NULL									// const VkBufferView*				pTexelBufferView;
2425 			};
2426 
2427 			writeDescriptorSets.push_back(writeDescriptorSetOutput);
2428 
2429 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
2430 			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
2431 		}
2432 
2433 		endCommandBuffer(m_vkd, *m_cmdBuffer);
2434 	}
2435 }
2436 
~PushDescriptorImageComputeTestInstance(void)2437 PushDescriptorImageComputeTestInstance::~PushDescriptorImageComputeTestInstance (void)
2438 {
2439 }
2440 
iterate(void)2441 tcu::TestStatus PushDescriptorImageComputeTestInstance::iterate (void)
2442 {
2443 	init();
2444 
2445 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
2446 
2447 	return verifyOutput();
2448 }
2449 
verifyOutput(void)2450 tcu::TestStatus PushDescriptorImageComputeTestInstance::verifyOutput (void)
2451 {
2452 	const auto			floatsPerDispatch	= 8u; // 8 floats (2 vec4s) per dispatch.
2453 	std::vector<float>	ref					(floatsPerDispatch * 2u);
2454 
2455 	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
2456 
2457 	switch(m_params.descriptorType)
2458 	{
2459 		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2460 			// Dispatch 1: inner & outer = green
2461 			ref[0] = ref[4] = 0.0f;
2462 			ref[1] = ref[5] = 1.0f;
2463 			ref[2] = ref[6] = 0.0f;
2464 			ref[3] = ref[7] = 1.0f;
2465 
2466 			// Dispatch 2: inner & outer = red
2467 			ref[8] = ref[12] = 1.0f;
2468 			ref[9] = ref[13] = 0.0f;
2469 			ref[10] = ref[14] = 0.0f;
2470 			ref[11] = ref[15] = 1.0f;
2471 			break;
2472 
2473 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2474 			// Dispatch 1: inner = green, outer = white
2475 			ref[0] = 0.0f;
2476 			ref[1] = 1.0f;
2477 			ref[2] = 0.0f;
2478 			ref[3] = 1.0f;
2479 
2480 			ref[4] = 1.0f;
2481 			ref[5] = 1.0f;
2482 			ref[6] = 1.0f;
2483 			ref[7] = 1.0f;
2484 
2485 			// Dispatch 2: inner = red, outer = black
2486 			ref[8] = 1.0f;
2487 			ref[9] = 0.0f;
2488 			ref[10] = 0.0f;
2489 			ref[11] = 1.0f;
2490 
2491 			ref[12] = 0.0f;
2492 			ref[13] = 0.0f;
2493 			ref[14] = 0.0f;
2494 			ref[15] = 1.0f;
2495 			break;
2496 
2497 		case VK_DESCRIPTOR_TYPE_SAMPLER:
2498 			// Dispatch 1: inner = green, outer = white
2499 			ref[0] = 0.0f;
2500 			ref[1] = 1.0f;
2501 			ref[2] = 0.0f;
2502 			ref[3] = 1.0f;
2503 
2504 			ref[4] = 1.0f;
2505 			ref[5] = 1.0f;
2506 			ref[6] = 1.0f;
2507 			ref[7] = 1.0f;
2508 
2509 			// Dispatch 2: inner = green, outer = black
2510 			ref[8] = 0.0f;
2511 			ref[9] = 1.0f;
2512 			ref[10] = 0.0f;
2513 			ref[11] = 1.0f;
2514 
2515 			ref[12] = 0.0f;
2516 			ref[13] = 0.0f;
2517 			ref[14] = 0.0f;
2518 			ref[15] = 1.0f;
2519 			break;
2520 
2521 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2522 			// Dispatch 1: inner = green, outer = white
2523 			ref[0] = 0.0f;
2524 			ref[1] = 1.0f;
2525 			ref[2] = 0.0f;
2526 			ref[3] = 1.0f;
2527 
2528 			ref[4] = 1.0f;
2529 			ref[5] = 1.0f;
2530 			ref[6] = 1.0f;
2531 			ref[7] = 1.0f;
2532 
2533 			// Dispatch 2: inner = red, outer = white
2534 			ref[8] = 1.0f;
2535 			ref[9] = 0.0f;
2536 			ref[10] = 0.0f;
2537 			ref[11] = 1.0f;
2538 
2539 			ref[12] = 1.0f;
2540 			ref[13] = 1.0f;
2541 			ref[14] = 1.0f;
2542 			ref[15] = 1.0f;
2543 			break;
2544 
2545 		default:
2546 			DE_FATAL("unexpected descriptor type");
2547 			break;
2548 	}
2549 
2550 	// Verify result
2551 	const auto			bufferDataPtr		= reinterpret_cast<const char*>(m_outputBufferAlloc->getHostPtr());
2552 	const auto			blockSize			= static_cast<size_t>(m_blockSize);
2553 
2554 	for (deUint32 dispatchNdx = 0u; dispatchNdx < m_params.numCalls; ++dispatchNdx)
2555 	{
2556 		const auto refIdx		= floatsPerDispatch * dispatchNdx;
2557 		const auto bufferOffset	= m_itemSize * dispatchNdx;	// Each dispatch uses m_itemSize bytes in the buffer to meet alignment reqs.
2558 
2559 		if (deMemCmp(&ref[refIdx], bufferDataPtr + bufferOffset, blockSize) != 0)
2560 		{
2561 			std::vector<float> buffferValues	(floatsPerDispatch);
2562 			std::vector<float> refValues		(floatsPerDispatch);
2563 
2564 			deMemcpy(refValues.data(), &ref[refIdx], blockSize);
2565 			deMemcpy(buffferValues.data(), bufferDataPtr + bufferOffset, blockSize);
2566 
2567 			std::ostringstream msg;
2568 			msg << "Output mismatch at dispatch " << dispatchNdx << ": Reference ";
2569 			for (deUint32 i = 0; i < floatsPerDispatch; ++i)
2570 				msg << ((i == 0) ? "[" : ", ") << refValues[i];
2571 			msg << "]; Buffer ";
2572 			for (deUint32 i = 0; i < floatsPerDispatch; ++i)
2573 				msg << ((i == 0) ? "[" : ", ") << buffferValues[i];
2574 			msg << "]";
2575 
2576 			m_context.getTestContext().getLog() << tcu::TestLog::Message << msg.str() << tcu::TestLog::EndMessage;
2577 			return tcu::TestStatus::fail("Output mismatch");
2578 		}
2579 	}
2580 
2581 	return tcu::TestStatus::pass("Output matches expected values");
2582 }
2583 
2584 class PushDescriptorImageComputeTest : public vkt::TestCase
2585 {
2586 public:
2587 						PushDescriptorImageComputeTest	(tcu::TestContext&	testContext,
2588 														 const string&		name,
2589 														 const string&		description,
2590 														 const TestParams&	params);
2591 						~PushDescriptorImageComputeTest	(void);
2592 	void				initPrograms					(SourceCollections& sourceCollections) const;
2593 	TestInstance*		createInstance					(Context& context) const;
2594 
2595 protected:
2596 	const TestParams	m_params;
2597 };
2598 
PushDescriptorImageComputeTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)2599 PushDescriptorImageComputeTest::PushDescriptorImageComputeTest	(tcu::TestContext&	testContext,
2600 																 const string&		name,
2601 																 const string&		description,
2602 																 const TestParams&	params)
2603 	: vkt::TestCase	(testContext, name, description)
2604 	, m_params		(params)
2605 {
2606 }
2607 
~PushDescriptorImageComputeTest(void)2608 PushDescriptorImageComputeTest::~PushDescriptorImageComputeTest (void)
2609 {
2610 }
2611 
createInstance(Context & context) const2612 TestInstance* PushDescriptorImageComputeTest::createInstance (Context& context) const
2613 {
2614 	return new PushDescriptorImageComputeTestInstance(context, m_params);
2615 }
2616 
initPrograms(SourceCollections & sourceCollections) const2617 void PushDescriptorImageComputeTest::initPrograms (SourceCollections& sourceCollections) const
2618 {
2619 	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2620 	{
2621 		const string	computeSrc	=
2622 			"#version 450\n"
2623 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
2624 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
2625 			"{\n"
2626 			"	vec4 innerColor;\n"
2627 			"	vec4 outerColor;\n"
2628 			"} outData;\n"
2629 			"\n"
2630 			"void main()\n"
2631 			"{\n"
2632 			"	outData.innerColor = texture(combinedSampler, vec2(0.5));\n"
2633 			"	outData.outerColor = texture(combinedSampler, vec2(-0.1));\n"
2634 			"}\n";
2635 
2636 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2637 	}
2638 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2639 	{
2640 		const string	computeSrc	=
2641 			"#version 450\n"
2642 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
2643 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
2644 			"layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
2645 			"{\n"
2646 			"	vec4 innerColor;\n"
2647 			"	vec4 outerColor;\n"
2648 			"} outData;\n"
2649 			"\n"
2650 			"void main()\n"
2651 			"{\n"
2652 			"	outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
2653 			"	outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
2654 			"}\n";
2655 
2656 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2657 	}
2658 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
2659 	{
2660 		const string	computeSrc	=
2661 			"#version 450\n"
2662 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
2663 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
2664 			"layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
2665 			"{\n"
2666 			"	vec4 innerColor;\n"
2667 			"	vec4 outerColor;\n"
2668 			"} outData;\n"
2669 			"\n"
2670 			"void main()\n"
2671 			"{\n"
2672 			"	outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
2673 			"	outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
2674 			"}\n";
2675 
2676 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2677 	}
2678 	else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2679 	{
2680 		const string	computeSrc	=
2681 			"#version 450\n"
2682 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
2683 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
2684 			"{\n"
2685 			"	vec4 innerColor;\n"
2686 			"	vec4 outerColor;\n"
2687 			"} outData;\n"
2688 			"\n"
2689 			"void main()\n"
2690 			"{\n"
2691 			"	outData.innerColor = imageLoad(storageImage, ivec2(0));\n"
2692 			"	outData.outerColor = imageLoad(storageImage, ivec2(0));\n"
2693 			"}\n";
2694 
2695 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2696 	}
2697 	else
2698 	{
2699 		DE_FATAL("Unexpected descriptor type");
2700 	}
2701 }
2702 
2703 class PushDescriptorTexelBufferGraphicsTestInstance : public vkt::TestInstance
2704 {
2705 public:
2706 								PushDescriptorTexelBufferGraphicsTestInstance	(Context& context, const TestParams& params);
2707 	virtual						~PushDescriptorTexelBufferGraphicsTestInstance	(void);
2708 	void						init											(void);
2709 	virtual tcu::TestStatus		iterate											(void);
2710 	tcu::TestStatus				verifyImage										(void);
2711 
2712 private:
2713 	const TestParams				m_params;
2714 	const PlatformInterface&		m_vkp;
2715 	const Extensions				m_instanceExtensions;
2716 	const CustomInstance			m_instance;
2717 	const InstanceDriver&			m_vki;
2718 	const VkPhysicalDevice			m_physicalDevice;
2719 	const deUint32					m_queueFamilyIndex;
2720 	const Extensions				m_deviceExtensions;
2721 	const Unique<VkDevice>			m_device;
2722 	const DeviceDriver				m_vkd;
2723 	const VkQueue					m_queue;
2724 	SimpleAllocator					m_allocator;
2725 	const tcu::UVec2				m_renderSize;
2726 	const VkFormat					m_colorFormat;
2727 	Move<VkImage>					m_colorImage;
2728 	de::MovePtr<Allocation>			m_colorImageAlloc;
2729 	Move<VkImageView>				m_colorAttachmentView;
2730 	vector<VkBufferSp>				m_buffers;
2731 	vector<AllocationSp>			m_bufferAllocs;
2732 	vector<VkBufferViewSp>			m_bufferViews;
2733 	const VkFormat					m_bufferFormat;
2734 	Move<VkRenderPass>				m_renderPass;
2735 	Move<VkFramebuffer>				m_framebuffer;
2736 	Move<VkShaderModule>			m_vertexShaderModule;
2737 	Move<VkShaderModule>			m_fragmentShaderModule;
2738 	Move<VkBuffer>					m_vertexBuffer;
2739 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
2740 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
2741 	Move<VkPipelineLayout>			m_preRasterizationStatePipelineLayout;
2742 	Move<VkPipelineLayout>			m_fragmentStatePipelineLayout;
2743 	GraphicsPipelineWrapper			m_graphicsPipeline;
2744 	Move<VkCommandPool>				m_cmdPool;
2745 	Move<VkCommandBuffer>			m_cmdBuffer;
2746 	vector<Vertex4RGBA>				m_vertices;
2747 };
2748 
PushDescriptorTexelBufferGraphicsTestInstance(Context & context,const TestParams & params)2749 PushDescriptorTexelBufferGraphicsTestInstance::PushDescriptorTexelBufferGraphicsTestInstance (Context& context, const TestParams& params)
2750 	: vkt::TestInstance		(context)
2751 	, m_params				(params)
2752 	, m_vkp					(context.getPlatformInterface())
2753 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
2754 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
2755 	, m_vki					(m_instance.getDriver())
2756 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
2757 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
2758 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
2759 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
2760 	, m_vkd					(m_vkp, m_instance, *m_device)
2761 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
2762 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
2763 	, m_renderSize			(32, 32)
2764 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
2765 	, m_bufferFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
2766 	, m_graphicsPipeline	(m_vkd, *m_device, params.pipelineConstructionType)
2767 	, m_vertices			(createQuads(params.numCalls, 0.25f))
2768 {
2769 }
2770 
init(void)2771 void PushDescriptorTexelBufferGraphicsTestInstance::init (void)
2772 {
2773 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2774 
2775 	// Create color image
2776 	{
2777 
2778 		const VkImageCreateInfo		colorImageParams		=
2779 		{
2780 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
2781 			DE_NULL,																// const void*				pNext;
2782 			0u,																		// VkImageCreateFlags		flags;
2783 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
2784 			m_colorFormat,															// VkFormat					format;
2785 			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
2786 			1u,																		// deUint32					mipLevels;
2787 			1u,																		// deUint32					arrayLayers;
2788 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
2789 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
2790 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
2791 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
2792 			1u,																		// deUint32					queueFamilyIndexCount;
2793 			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
2794 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
2795 		};
2796 
2797 		m_colorImage			= createImage(m_vkd, *m_device, &colorImageParams);
2798 
2799 		// Allocate and bind color image memory
2800 		m_colorImageAlloc		= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
2801 		VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
2802 	}
2803 
2804 	// Create color attachment view
2805 	{
2806 		const VkImageViewCreateInfo colorAttachmentViewParams =
2807 		{
2808 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType				sType;
2809 			DE_NULL,										// const void*					pNext;
2810 			0u,												// VkImageViewCreateFlags		flags;
2811 			*m_colorImage,									// VkImage						image;
2812 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType				viewType;
2813 			m_colorFormat,									// VkFormat						format;
2814 			componentMappingRGBA,							// VkChannelMapping				channels;
2815 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange		subresourceRange;
2816 		};
2817 
2818 		m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
2819 	}
2820 
2821 	// Create buffers
2822 	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
2823 	{
2824 		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
2825 
2826 		const VkBufferCreateInfo	bufferCreateInfo	=
2827 		{
2828 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
2829 			DE_NULL,								// const void*			pNext;
2830 			0u,										// VkBufferCreateFlags	flags
2831 			kSizeofVec4,							// VkDeviceSize			size;
2832 			usageFlags,								// VkBufferUsageFlags	usage;
2833 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2834 			1u,										// deUint32				queueFamilyCount;
2835 			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
2836 		};
2837 
2838 		m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
2839 		m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
2840 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
2841 
2842 		deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], static_cast<size_t>(kSizeofVec4));
2843 		flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
2844 	}
2845 
2846 	// Create buffer views
2847 	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
2848 	{
2849 		const VkBufferViewCreateInfo bufferViewParams =
2850 		{
2851 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
2852 			DE_NULL,									// const void*				pNext;
2853 			0u,											// VkBufferViewCreateFlags	flags;
2854 			**m_buffers[bufIdx],						// VkBuffer					buffer;
2855 			m_bufferFormat,								// VkFormat					format;
2856 			0u,											// VkDeviceSize				offset;
2857 			VK_WHOLE_SIZE								// VkDeviceSize				range;
2858 		};
2859 
2860 		m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
2861 	}
2862 
2863 	// Create render pass
2864 	m_renderPass = makeRenderPass(m_vkd, *m_device, m_colorFormat);
2865 
2866 	// Create framebuffer
2867 	{
2868 		const VkImageView				attachmentBindInfos[]	=
2869 		{
2870 			*m_colorAttachmentView
2871 		};
2872 
2873 		const VkFramebufferCreateInfo	framebufferParams		=
2874 		{
2875 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
2876 			DE_NULL,									// const void*				pNext;
2877 			0u,											// VkFramebufferCreateFlags	flags;
2878 			*m_renderPass,								// VkRenderPass				renderPass;
2879 			1u,											// deUint32					attachmentCount;
2880 			attachmentBindInfos,						// const VkImageView*		pAttachments;
2881 			(deUint32)m_renderSize.x(),					// deUint32					width;
2882 			(deUint32)m_renderSize.y(),					// deUint32					height;
2883 			1u											// deUint32					layers;
2884 		};
2885 
2886 		m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
2887 	}
2888 
2889 	// Create pipeline layout
2890 	{
2891 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
2892 		{
2893 			m_params.binding,				// uint32_t				binding;
2894 			m_params.descriptorType,		// VkDescriptorType		descriptorType;
2895 			1u,								// uint32_t				descriptorCount;
2896 			VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
2897 			DE_NULL							// const VkSampler*		pImmutableSamplers;
2898 		};
2899 
2900 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
2901 		{
2902 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
2903 			DE_NULL,													// const void*							pNext;
2904 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
2905 			1u,															// uint32_t								bindingCount;
2906 			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
2907 		};
2908 
2909 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
2910 
2911 		VkPipelineLayoutCreateFlags	pipelineLayoutFlags = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
2912 		VkPipelineLayoutCreateInfo	pipelineLayoutParams
2913 		{
2914 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
2915 			DE_NULL,										// const void*					pNext;
2916 			pipelineLayoutFlags,							// VkPipelineLayoutCreateFlags	flags;
2917 			0u,												// deUint32						setLayoutCount;
2918 			DE_NULL,										// const VkDescriptorSetLayout*	pSetLayouts;
2919 			0u,												// deUint32						pushConstantRangeCount;
2920 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
2921 		};
2922 
2923 		m_preRasterizationStatePipelineLayout	= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
2924 		pipelineLayoutParams.setLayoutCount		= 1u;
2925 		pipelineLayoutParams.pSetLayouts		= &(*m_descriptorSetLayout);
2926 		m_fragmentStatePipelineLayout			= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
2927 	}
2928 
2929 	// Create shaders
2930 	{
2931 		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
2932 		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
2933 	}
2934 
2935 	// Create pipeline
2936 	{
2937 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
2938 		{
2939 			0u,							// deUint32					binding;
2940 			sizeof(Vertex4RGBA),		// deUint32					strideInBytes;
2941 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
2942 		};
2943 
2944 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[]	=
2945 		{
2946 			{
2947 				0u,									// deUint32	location;
2948 				0u,									// deUint32	binding;
2949 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
2950 				0u									// deUint32	offsetInBytes;
2951 			},
2952 			{
2953 				1u,									// deUint32	location;
2954 				0u,									// deUint32	binding;
2955 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
2956 				DE_OFFSET_OF(Vertex4RGBA, color)	// deUint32	offset;
2957 			}
2958 		};
2959 
2960 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
2961 		{
2962 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
2963 			DE_NULL,													// const void*								pNext;
2964 			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
2965 			1u,															// deUint32									bindingCount;
2966 			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2967 			2u,															// deUint32									attributeCount;
2968 			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
2969 		};
2970 
2971 		const vector<VkViewport>					viewports			{ makeViewport(m_renderSize) };
2972 		const vector<VkRect2D>						scissors			{ makeRect2D(m_renderSize) };
2973 
2974 		m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
2975 						  .setDefaultRasterizationState()
2976 						  .setDefaultDepthStencilState()
2977 						  .setDefaultMultisampleState()
2978 						  .setDefaultColorBlendState()
2979 						  .setupVertexInputState(&vertexInputStateParams)
2980 						  .setupPreRasterizationShaderState(viewports,
2981 															scissors,
2982 															*m_preRasterizationStatePipelineLayout,
2983 															*m_renderPass,
2984 															0u,
2985 															*m_vertexShaderModule)
2986 						  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
2987 						  .setupFragmentOutputState(*m_renderPass)
2988 						  .buildPipeline();
2989 	}
2990 
2991 	// Create vertex buffer
2992 	{
2993 		const VkBufferCreateInfo vertexBufferParams =
2994 		{
2995 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
2996 			DE_NULL,													// const void*			pNext;
2997 			0u,															// VkBufferCreateFlags	flags;
2998 			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
2999 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
3000 			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
3001 			1u,															// deUint32				queueFamilyCount;
3002 			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
3003 		};
3004 
3005 		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
3006 		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
3007 
3008 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
3009 
3010 		// Load vertices into vertex buffer
3011 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
3012 		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
3013 	}
3014 
3015 	// Create command pool
3016 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3017 
3018 	// Create command buffer
3019 	{
3020 		const VkClearValue	attachmentClearValue	= defaultClearValue(m_colorFormat);
3021 		const VkDeviceSize	vertexBufferOffset		= 0;
3022 
3023 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3024 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
3025 		beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
3026 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
3027 		m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3028 
3029 		// Draw quads. Switch buffer view between draws.
3030 		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
3031 		{
3032 			VkWriteDescriptorSet	writeDescriptorSet	=
3033 			{
3034 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
3035 				DE_NULL,								// const void*						pNext;
3036 				0u,										// VkDescriptorSet					dstSet;
3037 				m_params.binding,						// uint32_t							dstBinding;
3038 				0u,										// uint32_t							dstArrayElement;
3039 				1u,										// uint32_t							descriptorCount;
3040 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
3041 				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
3042 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
3043 				&m_bufferViews[quadNdx]->get()			// const VkBufferView*				pTexelBufferView;
3044 			};
3045 
3046 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1u, &writeDescriptorSet);
3047 			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
3048 		}
3049 
3050 		endRenderPass(m_vkd, *m_cmdBuffer);
3051 		endCommandBuffer(m_vkd, *m_cmdBuffer);
3052 	}
3053 }
3054 
~PushDescriptorTexelBufferGraphicsTestInstance(void)3055 PushDescriptorTexelBufferGraphicsTestInstance::~PushDescriptorTexelBufferGraphicsTestInstance (void)
3056 {
3057 }
3058 
iterate(void)3059 tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::iterate (void)
3060 {
3061 	init();
3062 
3063 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
3064 
3065 	return verifyImage();
3066 }
3067 
verifyImage(void)3068 tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::verifyImage (void)
3069 {
3070 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
3071 	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
3072 	const ColorVertexShader		vertexShader;
3073 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
3074 	const rr::Program			program			(&vertexShader, &fragmentShader);
3075 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
3076 	bool						compareOk		= false;
3077 
3078 	// Render reference image
3079 	{
3080 		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
3081 			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
3082 				m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];
3083 
3084 		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
3085 						 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
3086 	}
3087 
3088 	// Compare result with reference image
3089 	{
3090 		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
3091 
3092 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
3093 															  "IntImageCompare",
3094 															  "Image comparison",
3095 															  refRenderer.getAccess(),
3096 															  result->getAccess(),
3097 															  tcu::UVec4(2, 2, 2, 2),
3098 															  tcu::IVec3(1, 1, 0),
3099 															  true,
3100 															  tcu::COMPARE_LOG_RESULT);
3101 	}
3102 
3103 	if (compareOk)
3104 		return tcu::TestStatus::pass("Result image matches reference");
3105 	else
3106 		return tcu::TestStatus::fail("Image mismatch");
3107 }
3108 
3109 class PushDescriptorTexelBufferGraphicsTest : public vkt::TestCase
3110 {
3111 public:
3112 						PushDescriptorTexelBufferGraphicsTest	(tcu::TestContext&	testContext,
3113 																 const string&		name,
3114 																 const string&		description,
3115 																 const TestParams&	params);
3116 						~PushDescriptorTexelBufferGraphicsTest	(void);
3117 
3118 	void				checkSupport						(Context& context) const;
3119 	void				initPrograms						(SourceCollections& sourceCollections) const;
3120 	TestInstance*		createInstance						(Context& context) const;
3121 
3122 protected:
3123 	const TestParams	m_params;
3124 };
3125 
PushDescriptorTexelBufferGraphicsTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)3126 PushDescriptorTexelBufferGraphicsTest::PushDescriptorTexelBufferGraphicsTest	(tcu::TestContext&	testContext,
3127 																				 const string&		name,
3128 																				 const string&		description,
3129 																				 const TestParams&	params)
3130 	: vkt::TestCase	(testContext, name, description)
3131 	, m_params		(params)
3132 {
3133 }
3134 
~PushDescriptorTexelBufferGraphicsTest(void)3135 PushDescriptorTexelBufferGraphicsTest::~PushDescriptorTexelBufferGraphicsTest (void)
3136 {
3137 }
3138 
createInstance(Context & context) const3139 TestInstance* PushDescriptorTexelBufferGraphicsTest::createInstance (Context& context) const
3140 {
3141 	return new PushDescriptorTexelBufferGraphicsTestInstance(context, m_params);
3142 }
3143 
checkSupport(Context & context) const3144 void PushDescriptorTexelBufferGraphicsTest::checkSupport(Context& context) const
3145 {
3146 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
3147 }
3148 
initPrograms(SourceCollections & sourceCollections) const3149 void PushDescriptorTexelBufferGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
3150 {
3151 	const string	vertexSrc	=
3152 		"#version 450\n"
3153 		"layout(location = 0) in highp vec4 position;\n"
3154 		"layout(location = 1) in highp vec4 texcoordVtx;\n"
3155 		"layout(location = 0) out highp vec2 texcoordFrag;\n"
3156 		"\n"
3157 		"out gl_PerVertex { vec4 gl_Position; };\n"
3158 		"\n"
3159 		"void main()\n"
3160 		"{\n"
3161 		"	gl_Position = position;\n"
3162 		"	texcoordFrag = texcoordVtx.xy;\n"
3163 		"}\n";
3164 
3165 	sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
3166 
3167 	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
3168 	{
3169 		const string	fragmentSrc	=
3170 			"#version 450\n"
3171 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
3172 			"layout(location = 0) out highp vec4 fragColor;\n"
3173 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
3174 			"\n"
3175 			"void main (void)\n"
3176 			"{\n"
3177 			"	fragColor = texelFetch(texelBuffer, 0);\n"
3178 			"}\n";
3179 
3180 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
3181 	}
3182 	else
3183 	{
3184 		DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
3185 		const string	fragmentSrc	=
3186 			"#version 450\n"
3187 			"layout(location = 0) in highp vec2 texcoordFrag;\n"
3188 			"layout(location = 0) out highp vec4 fragColor;\n"
3189 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
3190 			"\n"
3191 			"void main (void)\n"
3192 			"{\n"
3193 			"	fragColor = imageLoad(texelBuffer, 0);\n"
3194 			"}\n";
3195 
3196 		sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
3197 	}
3198 }
3199 
3200 class PushDescriptorTexelBufferComputeTestInstance : public vkt::TestInstance
3201 {
3202 public:
3203 								PushDescriptorTexelBufferComputeTestInstance	(Context& context, const TestParams& params);
3204 	virtual						~PushDescriptorTexelBufferComputeTestInstance	(void);
3205 	void						init											(void);
3206 	virtual tcu::TestStatus		iterate											(void);
3207 	tcu::TestStatus				verifyOutput									(void);
3208 
3209 private:
3210 	const TestParams			m_params;
3211 	const PlatformInterface&	m_vkp;
3212 	const Extensions			m_instanceExtensions;
3213 	const CustomInstance		m_instance;
3214 	const InstanceDriver&		m_vki;
3215 	const VkPhysicalDevice		m_physicalDevice;
3216 	const deUint32				m_queueFamilyIndex;
3217 	const Extensions			m_deviceExtensions;
3218 	const Unique<VkDevice>		m_device;
3219 	const DeviceDriver			m_vkd;
3220 	const VkQueue				m_queue;
3221 	const VkDeviceSize			m_itemSize;
3222 	SimpleAllocator				m_allocator;
3223 	vector<VkBufferSp>			m_buffers;
3224 	vector<AllocationSp>		m_bufferAllocs;
3225 	vector<VkBufferViewSp>		m_bufferViews;
3226 	const VkFormat				m_bufferFormat;
3227 	Move<VkShaderModule>		m_computeShaderModule;
3228 	Move<VkBuffer>				m_outputBuffer;
3229 	de::MovePtr<Allocation>		m_outputBufferAlloc;
3230 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
3231 	Move<VkPipelineLayout>		m_pipelineLayout;
3232 	Move<VkPipeline>			m_computePipeline;
3233 	Move<VkCommandPool>			m_cmdPool;
3234 	Move<VkCommandBuffer>		m_cmdBuffer;
3235 };
3236 
PushDescriptorTexelBufferComputeTestInstance(Context & context,const TestParams & params)3237 PushDescriptorTexelBufferComputeTestInstance::PushDescriptorTexelBufferComputeTestInstance (Context& context, const TestParams& params)
3238 	: vkt::TestInstance		(context)
3239 	, m_params				(params)
3240 	, m_vkp					(context.getPlatformInterface())
3241 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
3242 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
3243 	, m_vki					(m_instance.getDriver())
3244 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
3245 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
3246 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
3247 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
3248 	, m_vkd					(m_vkp, m_instance, *m_device)
3249 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
3250 	, m_itemSize			(calcItemSize(m_vki, m_physicalDevice))
3251 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
3252 	, m_bufferFormat		(VK_FORMAT_R32G32B32A32_SFLOAT)
3253 {
3254 }
3255 
init(void)3256 void PushDescriptorTexelBufferComputeTestInstance::init (void)
3257 {
3258 	// Create buffers
3259 	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
3260 	{
3261 		const VkBufferUsageFlags	usageFlags			= m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
3262 
3263 		const VkBufferCreateInfo	bufferCreateInfo	=
3264 		{
3265 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
3266 			DE_NULL,								// const void*			pNext;
3267 			0u,										// VkBufferCreateFlags	flags
3268 			kSizeofVec4,							// VkDeviceSize			size;
3269 			usageFlags,								// VkBufferUsageFlags	usage;
3270 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3271 			1u,										// deUint32				queueFamilyCount;
3272 			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
3273 		};
3274 
3275 		m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
3276 		m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
3277 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
3278 
3279 		deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], static_cast<size_t>(kSizeofVec4));
3280 		flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
3281 	}
3282 
3283 	// Create buffer views
3284 	for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
3285 	{
3286 		const VkBufferViewCreateInfo bufferViewParams =
3287 		{
3288 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	// VkStructureType			sType;
3289 			DE_NULL,									// const void*				pNext;
3290 			0u,											// VkBufferViewCreateFlags	flags;
3291 			**m_buffers[bufIdx],						// VkBuffer					buffer;
3292 			m_bufferFormat,								// VkFormat					format;
3293 			0u,											// VkDeviceSize				offset;
3294 			VK_WHOLE_SIZE								// VkDeviceSize				range;
3295 		};
3296 
3297 		m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
3298 	}
3299 
3300 	// Create pipeline layout
3301 	{
3302 		vector<VkDescriptorSetLayoutBinding>	layoutBindings;
3303 
3304 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBindings[]		=
3305 		{
3306 			{
3307 				m_params.binding,				// uint32_t				binding;
3308 				m_params.descriptorType,		// VkDescriptorType		descriptorType;
3309 				1u,								// uint32_t				descriptorCount;
3310 				VK_SHADER_STAGE_COMPUTE_BIT,	// VkShaderStageFlags	stageFlags;
3311 				DE_NULL							// const VkSampler*		pImmutableSamplers;
3312 			},
3313 			{
3314 				m_params.binding + 1,				// uint32_t				binding;
3315 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	// VkDescriptorType		descriptorType;
3316 				1u,									// uint32_t				descriptorCount;
3317 				VK_SHADER_STAGE_COMPUTE_BIT,		// VkShaderStageFlags	stageFlags;
3318 				DE_NULL								// const VkSampler*		pImmutableSamplers;
3319 			}
3320 		};
3321 
3322 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
3323 		{
3324 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
3325 			DE_NULL,													// const void*							pNext;
3326 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
3327 			2u,															// uint32_t								bindingCount;
3328 			descriptorSetLayoutBindings									// const VkDescriptorSetLayoutBinding*	pBindings;
3329 		};
3330 
3331 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
3332 
3333 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams			=
3334 		{
3335 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
3336 			DE_NULL,										// const void*					pNext;
3337 			0u,												// VkPipelineLayoutCreateFlags	flags;
3338 			1u,												// deUint32						descriptorSetCount;
3339 			&(*m_descriptorSetLayout),						// const VkDescriptorSetLayout*	pSetLayouts;
3340 			0u,												// deUint32						pushConstantRangeCount;
3341 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
3342 		};
3343 
3344 		m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
3345 	}
3346 
3347 	// Create output buffer
3348 	{
3349 		DE_ASSERT(m_params.numCalls <= 2u);
3350 
3351 		const VkBufferCreateInfo bufferCreateInfo =
3352 		{
3353 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
3354 			DE_NULL,								// const void*			pNext;
3355 			0u,										// VkBufferCreateFlags	flags
3356 			m_itemSize * m_params.numCalls,			// VkDeviceSize			size;
3357 			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage;
3358 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3359 			1u,										// deUint32				queueFamilyCount;
3360 			&m_queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
3361 		};
3362 
3363 		m_outputBuffer		= createBuffer(m_vkd, *m_device, &bufferCreateInfo);
3364 		m_outputBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
3365 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
3366 	}
3367 
3368 	// Create shader
3369 	{
3370 		m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
3371 	}
3372 
3373 	// Create pipeline
3374 	{
3375 		const VkPipelineShaderStageCreateInfo	stageCreateInfo	=
3376 		{
3377 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
3378 			DE_NULL,												// const void*						pNext;
3379 			0u,														// VkPipelineShaderStageCreateFlags	flags;
3380 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
3381 			*m_computeShaderModule,									// VkShaderModule					module;
3382 			"main",													// const char*						pName;
3383 			DE_NULL													// const VkSpecializationInfo*		pSpecializationInfo;
3384 		};
3385 
3386 		const VkComputePipelineCreateInfo		createInfo		=
3387 		{
3388 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType					sType;
3389 			DE_NULL,												// const void*						pNext;
3390 			0u,														// VkPipelineCreateFlags			flags;
3391 			stageCreateInfo,										// VkPipelineShaderStageCreateInfo	stage;
3392 			*m_pipelineLayout,										// VkPipelineLayout					layout;
3393 			(VkPipeline)0,											// VkPipeline						basePipelineHandle;
3394 			0u,														// int32_t							basePipelineIndex;
3395 		};
3396 
3397 		m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
3398 	}
3399 
3400 	// Create command pool
3401 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3402 
3403 	// Create command buffer
3404 	{
3405 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3406 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
3407 		m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
3408 
3409 		// Dispatch: Each dispatch switches the input image.
3410 		// Output buffer is exposed as a vec4 sized window.
3411 		for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
3412 		{
3413 			VkWriteDescriptorSet	writeDescriptorSet	=
3414 			{
3415 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
3416 				DE_NULL,								// const void*						pNext;
3417 				0u,										// VkDescriptorSet					dstSet;
3418 				m_params.binding,						// uint32_t							dstBinding;
3419 				0u,										// uint32_t							dstArrayElement;
3420 				1u,										// uint32_t							descriptorCount;
3421 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
3422 				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
3423 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
3424 				&m_bufferViews[dispatchNdx]->get()		// const VkBufferView*				pTexelBufferView;
3425 			};
3426 
3427 			vector<VkWriteDescriptorSet> writeDescriptorSets;
3428 			writeDescriptorSets.push_back(writeDescriptorSet);
3429 
3430 			const VkDescriptorBufferInfo descriptorBufferInfoOutput	=
3431 			{
3432 				*m_outputBuffer,			// VkBuffer			buffer;
3433 				m_itemSize * dispatchNdx,	// VkDeviceSize		offset;
3434 				kSizeofVec4,				// VkDeviceSize		range;
3435 			};
3436 
3437 			// Write output buffer descriptor set
3438 			const VkWriteDescriptorSet	writeDescriptorSetOutput	=
3439 			{
3440 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
3441 				DE_NULL,								// const void*						pNext;
3442 				0u,										// VkDescriptorSet					dstSet;
3443 				m_params.binding + 1,					// uint32_t							dstBinding;
3444 				0u,										// uint32_t							dstArrayElement;
3445 				1u,										// uint32_t							descriptorCount;
3446 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,		// VkDescriptorType					descriptorType;
3447 				DE_NULL,								// const VkDescriptorImageInfo*		pImageInfo;
3448 				&descriptorBufferInfoOutput,			// const VkDescriptorBufferInfo*	pBufferInfo;
3449 				DE_NULL									// const VkBufferView*				pTexelBufferView;
3450 			};
3451 
3452 			writeDescriptorSets.push_back(writeDescriptorSetOutput);
3453 
3454 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
3455 			m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
3456 		}
3457 
3458 		endCommandBuffer(m_vkd, *m_cmdBuffer);
3459 	}
3460 }
3461 
~PushDescriptorTexelBufferComputeTestInstance(void)3462 PushDescriptorTexelBufferComputeTestInstance::~PushDescriptorTexelBufferComputeTestInstance (void)
3463 {
3464 }
3465 
iterate(void)3466 tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::iterate (void)
3467 {
3468 	init();
3469 
3470 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
3471 
3472 	return verifyOutput();
3473 }
3474 
verifyOutput(void)3475 tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::verifyOutput (void)
3476 {
3477 	const tcu::Vec4 ref[2] = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };
3478 	invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
3479 
3480 	// Verify result
3481 	DE_ASSERT(m_params.numCalls <= 2u);
3482 
3483 	auto bufferPtr = reinterpret_cast<const char*>(m_outputBufferAlloc->getHostPtr());
3484 	for (deUint32 i = 0; i < m_params.numCalls; ++i)
3485 	{
3486 		tcu::Vec4 bufferColor;
3487 		deMemcpy(&bufferColor, bufferPtr + (i * m_itemSize), static_cast<size_t>(kSizeofVec4));
3488 
3489 		if (bufferColor != ref[i])
3490 		{
3491 			std::ostringstream msg;
3492 			msg << "Output mismatch at item " << i << ": expected " << ref[i] << " but found " << bufferColor;
3493 			TCU_FAIL(msg.str());
3494 		}
3495 	}
3496 
3497 	return tcu::TestStatus::pass("Output matches expected values");
3498 }
3499 
3500 class PushDescriptorTexelBufferComputeTest : public vkt::TestCase
3501 {
3502 public:
3503 						PushDescriptorTexelBufferComputeTest	(tcu::TestContext&	testContext,
3504 																 const string&		name,
3505 																 const string&		description,
3506 																 const TestParams&	params);
3507 						~PushDescriptorTexelBufferComputeTest	(void);
3508 	void				initPrograms							(SourceCollections& sourceCollections) const;
3509 	TestInstance*		createInstance							(Context& context) const;
3510 
3511 protected:
3512 	const TestParams	m_params;
3513 };
3514 
PushDescriptorTexelBufferComputeTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)3515 PushDescriptorTexelBufferComputeTest::PushDescriptorTexelBufferComputeTest	(tcu::TestContext&	testContext,
3516 																			 const string&		name,
3517 																			 const string&		description,
3518 																			 const TestParams&	params)
3519 	: vkt::TestCase	(testContext, name, description)
3520 	, m_params		(params)
3521 {
3522 }
3523 
~PushDescriptorTexelBufferComputeTest(void)3524 PushDescriptorTexelBufferComputeTest::~PushDescriptorTexelBufferComputeTest (void)
3525 {
3526 }
3527 
createInstance(Context & context) const3528 TestInstance* PushDescriptorTexelBufferComputeTest::createInstance (Context& context) const
3529 {
3530 	return new PushDescriptorTexelBufferComputeTestInstance(context, m_params);
3531 }
3532 
initPrograms(SourceCollections & sourceCollections) const3533 void PushDescriptorTexelBufferComputeTest::initPrograms (SourceCollections& sourceCollections) const
3534 {
3535 	if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
3536 	{
3537 		const string	computeSrc	=
3538 			"#version 450\n"
3539 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
3540 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
3541 			"{\n"
3542 			"	vec4 color;\n"
3543 			"} outData;\n"
3544 			"\n"
3545 			"void main()\n"
3546 			"{\n"
3547 			"	outData.color = texelFetch(texelBuffer, 0);\n"
3548 			"}\n";
3549 
3550 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
3551 	}
3552 	else
3553 	{
3554 		DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
3555 
3556 		const string	computeSrc	=
3557 			"#version 450\n"
3558 			"layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
3559 			"layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
3560 			"{\n"
3561 			"	vec4 color;\n"
3562 			"} outData;\n"
3563 			"\n"
3564 			"void main()\n"
3565 			"{\n"
3566 			"	outData.color = imageLoad(texelBuffer, 0);\n"
3567 			"}\n";
3568 
3569 		sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
3570 	}
3571 }
3572 
3573 class PushDescriptorInputAttachmentGraphicsTestInstance : public vkt::TestInstance
3574 {
3575 public:
3576 								PushDescriptorInputAttachmentGraphicsTestInstance	(Context& context, const TestParams& params);
3577 	virtual						~PushDescriptorInputAttachmentGraphicsTestInstance	(void);
3578 	void						init												(void);
3579 	virtual tcu::TestStatus		iterate												(void);
3580 	tcu::TestStatus				verifyImage											(void);
3581 
3582 private:
3583 	const TestParams				m_params;
3584 	const PlatformInterface&		m_vkp;
3585 	const Extensions				m_instanceExtensions;
3586 	const CustomInstance			m_instance;
3587 	const InstanceDriver&			m_vki;
3588 	const VkPhysicalDevice			m_physicalDevice;
3589 	const deUint32					m_queueFamilyIndex;
3590 	const Extensions				m_deviceExtensions;
3591 	const Unique<VkDevice>			m_device;
3592 	const DeviceDriver				m_vkd;
3593 	const VkQueue					m_queue;
3594 	SimpleAllocator					m_allocator;
3595 	const tcu::UVec2				m_renderSize;
3596 	const tcu::UVec2				m_textureSize;
3597 	const VkFormat					m_colorFormat;
3598 	Move<VkImage>					m_colorImage;
3599 	de::MovePtr<Allocation>			m_colorImageAlloc;
3600 	Move<VkImageView>				m_colorAttachmentView;
3601 	vector<VkImageSp>				m_inputImages;
3602 	vector<AllocationSp>			m_inputImageAllocs;
3603 	vector<VkImageViewSp>			m_inputImageViews;
3604 	vector<VkRenderPassSp>			m_renderPasses;
3605 	vector<VkFramebufferSp>			m_framebuffers;
3606 	Move<VkShaderModule>			m_vertexShaderModule;
3607 	Move<VkShaderModule>			m_fragmentShaderModule;
3608 	Move<VkBuffer>					m_vertexBuffer;
3609 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
3610 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
3611 	Move<VkPipelineLayout>			m_preRasterizationStatePipelineLayout;
3612 	Move<VkPipelineLayout>			m_fragmentStatePipelineLayout;
3613 	vector<GraphicsPipelineWrapper>	m_graphicsPipelines;
3614 	Move<VkCommandPool>				m_cmdPool;
3615 	Move<VkCommandBuffer>			m_cmdBuffer;
3616 	vector<Vertex4Tex4>				m_vertices;
3617 };
3618 
PushDescriptorInputAttachmentGraphicsTestInstance(Context & context,const TestParams & params)3619 PushDescriptorInputAttachmentGraphicsTestInstance::PushDescriptorInputAttachmentGraphicsTestInstance (Context& context, const TestParams& params)
3620 	: vkt::TestInstance		(context)
3621 	, m_params				(params)
3622 	, m_vkp					(context.getPlatformInterface())
3623 	, m_instanceExtensions	(enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
3624 	, m_instance			(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
3625 	, m_vki					(m_instance.getDriver())
3626 	, m_physicalDevice		(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
3627 	, m_queueFamilyIndex	(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
3628 	, m_deviceExtensions	(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
3629 	, m_device				(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, params))
3630 	, m_vkd					(m_vkp, m_instance, *m_device)
3631 	, m_queue				(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
3632 	, m_allocator			(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
3633 	, m_renderSize			(32, 32)
3634 	, m_textureSize			(32, 32)
3635 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
3636 	, m_vertices			(createTexQuads(params.numCalls, 0.25f))
3637 {
3638 }
3639 
init(void)3640 void PushDescriptorInputAttachmentGraphicsTestInstance::init (void)
3641 {
3642 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
3643 
3644 	// Create color image
3645 	{
3646 
3647 		const VkImageCreateInfo		colorImageParams		=
3648 		{
3649 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
3650 			DE_NULL,																// const void*				pNext;
3651 			0u,																		// VkImageCreateFlags		flags;
3652 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
3653 			m_colorFormat,															// VkFormat					format;
3654 			{ m_renderSize.x(), m_renderSize.y(), 1u },								// VkExtent3D				extent;
3655 			1u,																		// deUint32					mipLevels;
3656 			1u,																		// deUint32					arrayLayers;
3657 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
3658 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
3659 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
3660 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
3661 			1u,																		// deUint32					queueFamilyIndexCount;
3662 			&m_queueFamilyIndex,													// const deUint32*			pQueueFamilyIndices;
3663 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
3664 		};
3665 
3666 		m_colorImage		= createImage(m_vkd, *m_device, &colorImageParams);
3667 
3668 		// Allocate and bind color image memory
3669 		m_colorImageAlloc	= m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
3670 		VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
3671 	}
3672 
3673 	// Create color attachment view
3674 	{
3675 		const VkImageViewCreateInfo colorAttachmentViewParams =
3676 		{
3677 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
3678 			DE_NULL,										// const void*				pNext;
3679 			0u,												// VkImageViewCreateFlags	flags;
3680 			*m_colorImage,									// VkImage					image;
3681 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
3682 			m_colorFormat,									// VkFormat					format;
3683 			componentMappingRGBA,							// VkChannelMapping			channels;
3684 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
3685 		};
3686 
3687 		m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
3688 	}
3689 
3690 	// Create input images
3691 	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
3692 	{
3693 		const VkImageUsageFlags		usageFlags			= VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3694 
3695 		const VkImageCreateInfo		inputImageParams	=
3696 		{
3697 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
3698 			DE_NULL,										// const void*				pNext;
3699 			0u,												// VkImageCreateFlags		flags;
3700 			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
3701 			m_colorFormat,									// VkFormat					format;
3702 			{ m_textureSize.x(), m_textureSize.y(), 1u },	// VkExtent3D				extent;
3703 			1u,												// deUint32					mipLevels;
3704 			1u,												// deUint32					arrayLayers;
3705 			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
3706 			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
3707 			usageFlags,										// VkImageUsageFlags		usage;
3708 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
3709 			1u,												// deUint32					queueFamilyIndexCount;
3710 			&m_queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
3711 			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
3712 		};
3713 
3714 		m_inputImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &inputImageParams))));
3715 
3716 		// Allocate and bind image memory
3717 		m_inputImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_inputImages.back()), MemoryRequirement::Any).release()));
3718 		VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_inputImages.back(), m_inputImageAllocs.back()->getMemory(), m_inputImageAllocs.back()->getOffset()));
3719 	}
3720 
3721 	// Create texture image views
3722 	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
3723 	{
3724 		const VkImageViewCreateInfo textureViewParams =
3725 		{
3726 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
3727 			DE_NULL,										// const void*				pNext;
3728 			0u,												// VkImageViewCreateFlags	flags;
3729 			**m_inputImages[imageIdx],						// VkImage					image;
3730 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
3731 			m_colorFormat,									// VkFormat					format;
3732 			componentMappingRGBA,							// VkChannelMapping			channels;
3733 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
3734 		};
3735 
3736 		m_inputImageViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
3737 	}
3738 
3739 	VkClearValue clearValues[2];
3740 	clearValues[0].color.float32[0] = 0.0f;
3741 	clearValues[0].color.float32[1] = 1.0f;
3742 	clearValues[0].color.float32[2] = 0.0f;
3743 	clearValues[0].color.float32[3] = 1.0f;
3744 	clearValues[1].color.float32[0] = 1.0f;
3745 	clearValues[1].color.float32[1] = 0.0f;
3746 	clearValues[1].color.float32[2] = 0.0f;
3747 	clearValues[1].color.float32[3] = 1.0f;
3748 
3749 	// Clear input images
3750 	for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
3751 	{
3752 		const VkImageAspectFlags	aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
3753 		Move<VkCommandPool>			cmdPool;
3754 		Move<VkCommandBuffer>		cmdBuffer;
3755 		const VkAccessFlags			accessFlags	= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
3756 
3757 		cmdPool		= createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3758 		cmdBuffer	= allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3759 
3760 		const VkImageMemoryBarrier preImageBarrier =
3761 		{
3762 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
3763 			DE_NULL,								// const void*				pNext;
3764 			0u,										// VkAccessFlags			srcAccessMask;
3765 			VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3766 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
3767 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
3768 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
3769 			VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
3770 			**m_inputImages[imageIdx],				// VkImage					image;
3771 			{										// VkImageSubresourceRange	subresourceRange;
3772 				aspectMask,							// VkImageAspect			aspect;
3773 				0u,									// deUint32					baseMipLevel;
3774 				1u,									// deUint32					mipLevels;
3775 				0u,									// deUint32					baseArraySlice;
3776 				1u									// deUint32					arraySize;
3777 			}
3778 		};
3779 
3780 		const VkImageMemoryBarrier postImageBarrier =
3781 		{
3782 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3783 			DE_NULL,									// const void*				pNext;
3784 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3785 			accessFlags,								// VkAccessFlags			dstAccessMask;
3786 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3787 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			newLayout;
3788 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3789 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3790 			**m_inputImages[imageIdx],					// VkImage					image;
3791 			{											// VkImageSubresourceRange	subresourceRange;
3792 				aspectMask,								// VkImageAspect			aspect;
3793 				0u,										// deUint32					baseMipLevel;
3794 				1u,										// deUint32					mipLevels;
3795 				0u,										// deUint32					baseArraySlice;
3796 				1u										// deUint32					arraySize;
3797 			}
3798 		};
3799 
3800 		const VkImageSubresourceRange clearRange	=
3801 		{
3802 			aspectMask,	// VkImageAspectFlags	aspectMask;
3803 			0u,			// deUint32				baseMipLevel;
3804 			1u,			// deUint32				levelCount;
3805 			0u,			// deUint32				baseArrayLayer;
3806 			1u			// deUint32				layerCount;
3807 		};
3808 
3809 		beginCommandBuffer(m_vkd, *cmdBuffer);
3810 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
3811 		m_vkd.cmdClearColorImage(*cmdBuffer, **m_inputImages[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[imageIdx].color, 1, &clearRange);
3812 		m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
3813 		endCommandBuffer(m_vkd, *cmdBuffer);
3814 
3815 		submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
3816 	}
3817 
3818 	// Create render passes
3819 	for (deUint32 renderPassIdx = 0; renderPassIdx < 2; renderPassIdx++)
3820 	{
3821 		// The first pass clears the output image, and the second one draws on top of the first pass.
3822 		const VkAttachmentLoadOp		loadOps[]					=
3823 		{
3824 			VK_ATTACHMENT_LOAD_OP_CLEAR,
3825 			VK_ATTACHMENT_LOAD_OP_LOAD
3826 		};
3827 
3828 		const VkImageLayout				initialLayouts[]			=
3829 		{
3830 			VK_IMAGE_LAYOUT_UNDEFINED,
3831 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
3832 		};
3833 
3834 		const VkAttachmentDescription	attachmentDescriptions[]	=
3835 		{
3836 			// Result attachment
3837 			{
3838 				(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
3839 				VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
3840 				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
3841 				loadOps[renderPassIdx],						// VkAttachmentLoadOp			loadOp
3842 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
3843 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
3844 				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
3845 				initialLayouts[renderPassIdx],				// VkImageLayout				initialLayout
3846 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout				finalLayout
3847 			},
3848 			// Input attachment
3849 			{
3850 				(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags	flags
3851 				VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat						format
3852 				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples
3853 				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp			loadOp
3854 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp
3855 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp
3856 				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp
3857 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout				initialLayout
3858 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout				finalLayout
3859 			}
3860 		};
3861 
3862 		const VkAttachmentReference		resultAttachmentRef		=
3863 		{
3864 			0u,											// deUint32			attachment
3865 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
3866 		};
3867 
3868 		const VkAttachmentReference		inputAttachmentRef		=
3869 		{
3870 			1u,											// deUint32			attachment
3871 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	layout
3872 		};
3873 
3874 		const VkSubpassDescription		subpassDescription		=
3875 		{
3876 			(VkSubpassDescriptionFlags)0,				// VkSubpassDescriptionFlags	flags
3877 			VK_PIPELINE_BIND_POINT_GRAPHICS,			// VkPipelineBindPoint			pipelineBindPoint
3878 			1u,											// deUint32						inputAttachmentCount
3879 			&inputAttachmentRef,							// const VkAttachmentReference*	pInputAttachments
3880 			1u,											// deUint32						colorAttachmentCount
3881 			&resultAttachmentRef,						// const VkAttachmentReference*	pColorAttachments
3882 			DE_NULL,									// const VkAttachmentReference*	pResolveAttachments
3883 			DE_NULL,									// const VkAttachmentReference*	pDepthStencilAttachment
3884 			0u,											// deUint32						preserveAttachmentCount
3885 			DE_NULL										// const deUint32*				pPreserveAttachments
3886 		};
3887 
3888 		const VkSubpassDependency		subpassDependency		=
3889 		{
3890 			VK_SUBPASS_EXTERNAL,							// deUint32				srcSubpass
3891 			0,												// deUint32				dstSubpass
3892 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags	srcStageMask
3893 			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			// VkPipelineStageFlags	dstStageMask
3894 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags		srcAccessMask
3895 			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT,	//	dstAccessMask
3896 			VK_DEPENDENCY_BY_REGION_BIT						// VkDependencyFlags	dependencyFlags
3897 		};
3898 
3899 		const VkRenderPassCreateInfo	renderPassInfo			=
3900 		{
3901 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureTypei					sType
3902 			DE_NULL,									// const void*						pNext
3903 			(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags			flags
3904 			2u,											// deUint32							attachmentCount
3905 			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments
3906 			1u,											// deUint32							subpassCount
3907 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses
3908 			1u,											// deUint32							dependencyCount
3909 			&subpassDependency							// const VkSubpassDependency*		pDependencies
3910 		};
3911 
3912 		m_renderPasses.push_back(VkRenderPassSp(new Unique<VkRenderPass>(createRenderPass(m_vkd, *m_device, &renderPassInfo))));
3913 	}
3914 
3915 	// Create framebuffers
3916 	for (deUint32 framebufferIdx = 0; framebufferIdx < 2; framebufferIdx++)
3917 	{
3918 		const VkImageView				attachmentBindInfos[]	=
3919 		{
3920 			*m_colorAttachmentView,
3921 			**m_inputImageViews[framebufferIdx],
3922 		};
3923 
3924 		const VkFramebufferCreateInfo	framebufferParams		=
3925 		{
3926 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
3927 			DE_NULL,									// const void*				pNext;
3928 			0u,											// VkFramebufferCreateFlags	flags;
3929 			**m_renderPasses[framebufferIdx],			// VkRenderPass				renderPass;
3930 			2u,											// deUint32					attachmentCount;
3931 			attachmentBindInfos,						// const VkImageView*		pAttachments;
3932 			(deUint32)m_renderSize.x(),					// deUint32					width;
3933 			(deUint32)m_renderSize.y(),					// deUint32					height;
3934 			1u											// deUint32					layers;
3935 		};
3936 
3937 		m_framebuffers.push_back(VkFramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(m_vkd, *m_device, &framebufferParams))));
3938 	}
3939 
3940 	// Create pipeline layout
3941 	{
3942 		// Create descriptor set layout
3943 		const VkDescriptorSetLayoutBinding		descriptorSetLayoutBinding		=
3944 		{
3945 			m_params.binding,						// uint32_t				binding;
3946 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType;
3947 			1u,										// uint32_t				descriptorCount;
3948 			VK_SHADER_STAGE_FRAGMENT_BIT,			// VkShaderStageFlags	stageFlags;
3949 			DE_NULL									// const VkSampler*		pImmutableSamplers;
3950 		};
3951 
3952 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutCreateInfo	=
3953 		{
3954 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType;
3955 			DE_NULL,													// const void*							pNext;
3956 			VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,	// VkDescriptorSetLayoutCreateFlags		flags;
3957 			1u,															// uint32_t								bindingCount;
3958 			&descriptorSetLayoutBinding									// const VkDescriptorSetLayoutBinding*	pBindings;
3959 		};
3960 
3961 		m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
3962 
3963 		// Create pipeline layout
3964 		VkPipelineLayoutCreateFlags	pipelineLayoutFlags = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
3965 		VkPipelineLayoutCreateInfo	pipelineLayoutParams
3966 		{
3967 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
3968 			DE_NULL,										// const void*					pNext;
3969 			pipelineLayoutFlags,							// VkPipelineLayoutCreateFlags	flags;
3970 			0u,												// deUint32						setLayoutCount;
3971 			DE_NULL,										// const VkDescriptorSetLayout*	pSetLayouts;
3972 			0u,												// deUint32						pushConstantRangeCount;
3973 			DE_NULL											// const VkPushDescriptorRange*	pPushDescriptorRanges;
3974 		};
3975 
3976 		m_preRasterizationStatePipelineLayout	= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
3977 		pipelineLayoutParams.setLayoutCount		= 1u;
3978 		pipelineLayoutParams.pSetLayouts		= &(*m_descriptorSetLayout);
3979 		m_fragmentStatePipelineLayout			= createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
3980 	}
3981 
3982 	// Create shaders
3983 	{
3984 		m_vertexShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
3985 		m_fragmentShaderModule	= createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
3986 	}
3987 
3988 	m_graphicsPipelines.reserve(2);
3989 
3990 	// Create pipelines
3991 	for (deUint32 pipelineIdx = 0; pipelineIdx < 2; pipelineIdx++)
3992 	{
3993 		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
3994 		{
3995 			0u,							// deUint32					binding;
3996 			sizeof(Vertex4Tex4),		// deUint32					strideInBytes;
3997 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
3998 		};
3999 
4000 		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[]	=
4001 		{
4002 			{
4003 				0u,										// deUint32	location;
4004 				0u,										// deUint32	binding;
4005 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
4006 				0u										// deUint32	offsetInBytes;
4007 			},
4008 			{
4009 				1u,										// deUint32	location;
4010 				0u,										// deUint32	binding;
4011 				VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat	format;
4012 				DE_OFFSET_OF(Vertex4Tex4, texCoord),	// deUint32	offset;
4013 			}
4014 		};
4015 
4016 		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
4017 		{
4018 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
4019 			DE_NULL,													// const void*								pNext;
4020 			0u,															// vkPipelineVertexInputStateCreateFlags	flags;
4021 			1u,															// deUint32									bindingCount;
4022 			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
4023 			2u,															// deUint32									attributeCount;
4024 			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
4025 		};
4026 
4027 		const vector<VkViewport>	viewports	{ makeViewport(m_renderSize) };
4028 		const vector<VkRect2D>		scissors	{ makeRect2D(m_renderSize) };
4029 
4030 		m_graphicsPipelines.emplace_back(m_vkd, *m_device, m_params.pipelineConstructionType);
4031 		m_graphicsPipelines.back().setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
4032 								  .setDefaultRasterizationState()
4033 								  .setDefaultDepthStencilState()
4034 								  .setDefaultMultisampleState()
4035 								  .setDefaultColorBlendState()
4036 								  .setupVertexInputState(&vertexInputStateParams)
4037 								  .setupPreRasterizationShaderState(viewports,
4038 																	scissors,
4039 																	*m_preRasterizationStatePipelineLayout,
4040 																	**m_renderPasses[pipelineIdx],
4041 																	0u,
4042 																	*m_vertexShaderModule)
4043 								  .setupFragmentShaderState(*m_fragmentStatePipelineLayout, **m_renderPasses[pipelineIdx], 0u, *m_fragmentShaderModule)
4044 								  .setupFragmentOutputState(**m_renderPasses[pipelineIdx])
4045 								  .buildPipeline();
4046 	}
4047 
4048 	// Create vertex buffer
4049 	{
4050 		const VkBufferCreateInfo vertexBufferParams =
4051 		{
4052 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType;
4053 			DE_NULL,													// const void*			pNext;
4054 			0u,															// VkBufferCreateFlags	flags;
4055 			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size;
4056 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage;
4057 			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode;
4058 			1u,															// deUint32				queueFamilyCount;
4059 			&m_queueFamilyIndex											// const deUint32*		pQueueFamilyIndices;
4060 		};
4061 
4062 		m_vertexBuffer		= createBuffer(m_vkd, *m_device, &vertexBufferParams);
4063 		m_vertexBufferAlloc	= m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
4064 
4065 		VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
4066 
4067 		// Load vertices into vertex buffer
4068 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
4069 		flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
4070 	}
4071 
4072 	// Create command pool
4073 	m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
4074 
4075 	// Create command buffer
4076 	{
4077 		const VkClearValue	attachmentClearValue	= defaultClearValue(m_colorFormat);
4078 		const VkDeviceSize	vertexBufferOffset		= 0;
4079 
4080 		m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4081 		beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
4082 		for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
4083 		{
4084 			beginRenderPass(m_vkd, *m_cmdBuffer, **m_renderPasses[quadNdx], **m_framebuffers[quadNdx], makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
4085 			m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipelines[quadNdx].getPipeline());
4086 			m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4087 
4088 			VkDescriptorImageInfo	descriptorImageInfo	=
4089 			{
4090 				0,											// VkSampler		sampler;
4091 				**m_inputImageViews[quadNdx],				// VkImageView		imageView;
4092 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout;
4093 			};
4094 
4095 			VkWriteDescriptorSet	writeDescriptorSet	=
4096 			{
4097 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType;
4098 				DE_NULL,								// const void*						pNext;
4099 				0u,										// VkDescriptorSet					dstSet;
4100 				m_params.binding,						// uint32_t							dstBinding;
4101 				0u,										// uint32_t							dstArrayElement;
4102 				1u,										// uint32_t							descriptorCount;
4103 				m_params.descriptorType,				// VkDescriptorType					descriptorType;
4104 				&descriptorImageInfo,					// const VkDescriptorImageInfo*		pImageInfo;
4105 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo;
4106 				DE_NULL									// const VkBufferView*				pTexelBufferView;
4107 			};
4108 
4109 			m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &writeDescriptorSet);
4110 			m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
4111 
4112 			endRenderPass(m_vkd, *m_cmdBuffer);
4113 		}
4114 
4115 		endCommandBuffer(m_vkd, *m_cmdBuffer);
4116 	}
4117 }
4118 
~PushDescriptorInputAttachmentGraphicsTestInstance(void)4119 PushDescriptorInputAttachmentGraphicsTestInstance::~PushDescriptorInputAttachmentGraphicsTestInstance (void)
4120 {
4121 }
4122 
iterate(void)4123 tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::iterate (void)
4124 {
4125 	init();
4126 
4127 	submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
4128 
4129 	return verifyImage();
4130 }
4131 
verifyImage(void)4132 tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::verifyImage (void)
4133 {
4134 	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
4135 	const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
4136 	const ColorVertexShader		vertexShader;
4137 	const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
4138 	const rr::Program			program			(&vertexShader, &fragmentShader);
4139 	ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
4140 	bool						compareOk		= false;
4141 
4142 	// Render reference image
4143 	{
4144 		vector<Vertex4RGBA>	refQuads = createQuads(m_params.numCalls, 0.25f);
4145 		tcu::Vec4			colors[2];
4146 
4147 		colors[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
4148 		colors[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
4149 
4150 		for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
4151 			for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
4152 			{
4153 				const deUint32 idx = quadIdx * 6 + vertexIdx;
4154 				refQuads[idx].color.xyzw() = colors[quadIdx];
4155 			}
4156 
4157 		refRenderer.draw(rr::RenderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits),
4158 						 rr::PRIMITIVETYPE_TRIANGLES, refQuads);
4159 	}
4160 
4161 	// Compare result with reference image
4162 	{
4163 		de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
4164 
4165 		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
4166 															  "IntImageCompare",
4167 															  "Image comparison",
4168 															  refRenderer.getAccess(),
4169 															  result->getAccess(),
4170 															  tcu::UVec4(2, 2, 2, 2),
4171 															  tcu::IVec3(1, 1, 0),
4172 															  true,
4173 															  tcu::COMPARE_LOG_RESULT);
4174 	}
4175 
4176 	if (compareOk)
4177 		return tcu::TestStatus::pass("Result image matches reference");
4178 	else
4179 		return tcu::TestStatus::fail("Image mismatch");
4180 }
4181 
4182 class PushDescriptorInputAttachmentGraphicsTest : public vkt::TestCase
4183 {
4184 public:
4185 						PushDescriptorInputAttachmentGraphicsTest		(tcu::TestContext&	testContext,
4186 															 const string&		name,
4187 															 const string&		description,
4188 															 const TestParams&	params);
4189 						~PushDescriptorInputAttachmentGraphicsTest	(void);
4190 
4191 	void				checkSupport						(Context& context) const;
4192 	void				initPrograms						(SourceCollections& sourceCollections) const;
4193 	TestInstance*		createInstance						(Context& context) const;
4194 
4195 protected:
4196 	const TestParams	m_params;
4197 };
4198 
PushDescriptorInputAttachmentGraphicsTest(tcu::TestContext & testContext,const string & name,const string & description,const TestParams & params)4199 PushDescriptorInputAttachmentGraphicsTest::PushDescriptorInputAttachmentGraphicsTest	(tcu::TestContext&	testContext,
4200 																	const string&		name,
4201 																	const string&		description,
4202 																	const TestParams&	params)
4203 	: vkt::TestCase	(testContext, name, description)
4204 	, m_params		(params)
4205 {
4206 }
4207 
~PushDescriptorInputAttachmentGraphicsTest(void)4208 PushDescriptorInputAttachmentGraphicsTest::~PushDescriptorInputAttachmentGraphicsTest (void)
4209 {
4210 }
4211 
createInstance(Context & context) const4212 TestInstance* PushDescriptorInputAttachmentGraphicsTest::createInstance (Context& context) const
4213 {
4214 	return new PushDescriptorInputAttachmentGraphicsTestInstance(context, m_params);
4215 }
4216 
checkSupport(Context & context) const4217 void PushDescriptorInputAttachmentGraphicsTest::checkSupport(Context& context) const
4218 {
4219 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
4220 }
4221 
initPrograms(SourceCollections & sourceCollections) const4222 void PushDescriptorInputAttachmentGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
4223 {
4224 	const string	vertexSrc	=
4225 		"#version 450\n"
4226 		"layout(location = 0) in highp vec4 position;\n"
4227 		"layout(location = 1) in highp vec4 texcoordVtx;\n"
4228 		"layout(location = 0) out highp vec2 texcoordFrag;\n"
4229 		"\n"
4230 		"out gl_PerVertex { vec4 gl_Position; };\n"
4231 		"\n"
4232 		"void main()\n"
4233 		"{\n"
4234 		"	gl_Position = position;\n"
4235 		"	texcoordFrag = texcoordVtx.xy;\n"
4236 		"}\n";
4237 
4238 	sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
4239 
4240 	const string	fragmentSrc	=
4241 		"#version 450\n"
4242 		"layout(location = 0) in highp vec2 texcoordFrag;\n"
4243 		"layout(location = 0) out highp vec4 fragColor;\n"
4244 		"layout(input_attachment_index = 0, set = 0, binding = " + de::toString(m_params.binding) + ") uniform subpassInput inputColor;\n"
4245 		"\n"
4246 		"void main (void)\n"
4247 		"{\n"
4248 		"	fragColor = subpassLoad(inputColor);\n"
4249 		"}\n";
4250 
4251 	sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
4252 }
4253 
4254 } // anonymous
4255 
createPushDescriptorTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineType)4256 tcu::TestCaseGroup* createPushDescriptorTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineType)
4257 {
4258 	const TestParams params[] =
4259 	{
4260 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,				0u, 1u },
4261 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,				0u, 2u },
4262 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,				1u, 2u },
4263 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,				3u, 2u },
4264 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,				0u, 1u },
4265 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,				0u, 2u },
4266 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,				1u, 2u },
4267 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,				3u, 2u },
4268 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,				1u, 128u },
4269 		{ pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,		0u, 1u },
4270 		{ pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,		0u, 2u },
4271 		{ pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,		1u, 2u },
4272 		{ pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,		3u, 2u },
4273 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER,						0u, 1u },
4274 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER,						0u, 2u },
4275 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER,						1u, 2u },
4276 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER,						3u, 2u },
4277 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				0u, 1u },
4278 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				0u, 2u },
4279 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				1u, 2u },
4280 		{ pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,				3u, 2u },
4281 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				0u, 1u },
4282 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				0u, 2u },
4283 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				1u, 2u },
4284 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,				3u, 2u },
4285 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		0u, 1u },
4286 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		0u, 2u },
4287 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		1u, 2u },
4288 		{ pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,		3u, 2u },
4289 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		0u, 1u },
4290 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		0u, 2u },
4291 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		1u, 2u },
4292 		{ pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,		3u, 2u },
4293 		{ pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			0u, 1u },
4294 		{ pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			0u, 2u },
4295 		{ pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			1u, 2u },
4296 		{ pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			3u, 2u }
4297 	};
4298 
4299 	de::MovePtr<tcu::TestCaseGroup>	pushDescriptorTests	(new tcu::TestCaseGroup(testCtx, "push_descriptor", "Push descriptor tests"));
4300 
4301 	de::MovePtr<tcu::TestCaseGroup>	graphicsTests		(new tcu::TestCaseGroup(testCtx, "graphics", "graphics pipeline"));
4302 	de::MovePtr<tcu::TestCaseGroup>	computeTests		(new tcu::TestCaseGroup(testCtx, "compute", "compute pipeline"));
4303 
4304 	for (deUint32 testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(params); testIdx++)
4305 	{
4306 		string testName;
4307 		testName += "binding" + de::toString(params[testIdx].binding) + "_numcalls" + de::toString(params[testIdx].numCalls);
4308 		switch(params[testIdx].descriptorType)
4309 		{
4310 			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4311 				testName += "_uniform_buffer";
4312 				if (params[testIdx].numCalls <= 2)
4313 					graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4314 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4315 					computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4316 				break;
4317 
4318 			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4319 				testName += "_storage_buffer";
4320 				if (params[testIdx].numCalls <= 2)
4321 					graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4322 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4323 					computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4324 				break;
4325 
4326 			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4327 				testName += "_combined_image_sampler";
4328 				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4329 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4330 					computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4331 				break;
4332 
4333 			case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4334 				testName += "_sampled_image";
4335 				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4336 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4337 					computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4338 				break;
4339 
4340 			case VK_DESCRIPTOR_TYPE_SAMPLER:
4341 				testName += "_sampler";
4342 				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4343 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4344 					computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4345 				break;
4346 
4347 			case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4348 				testName += "_storage_image";
4349 				graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4350 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4351 					computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4352 				break;
4353 
4354 			case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4355 				testName += "_uniform_texel_buffer";
4356 				graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4357 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4358 					computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4359 				break;
4360 
4361 			case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4362 				testName += "_storage_texel_buffer";
4363 				graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4364 				if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4365 					computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
4366 				break;
4367 
4368 			case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4369 				testName += "_input_attachment";
4370 				graphicsTests->addChild(new PushDescriptorInputAttachmentGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
4371 				break;
4372 
4373 			default:
4374 				DE_FATAL("Unexpected descriptor type");
4375 				break;
4376 		}
4377 	}
4378 
4379 	pushDescriptorTests->addChild(graphicsTests.release());
4380 	if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4381 		pushDescriptorTests->addChild(computeTests.release());
4382 
4383 	return pushDescriptorTests.release();
4384 }
4385 
4386 } // pipeline
4387 } // vkt
4388