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