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