• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Tests sparse render target.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRenderPassSparseRenderTargetTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkRef.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40 
41 #include "tcuImageCompare.hpp"
42 #include "tcuResultCollector.hpp"
43 #include "tcuTextureUtil.hpp"
44 
45 #include "deUniquePtr.hpp"
46 #include "deSharedPtr.hpp"
47 
48 using namespace vk;
49 
50 using tcu::UVec4;
51 using tcu::Vec4;
52 
53 using tcu::ConstPixelBufferAccess;
54 using tcu::PixelBufferAccess;
55 
56 using tcu::TestLog;
57 
58 using std::string;
59 using std::vector;
60 
61 namespace vkt
62 {
63 namespace
64 {
65 using namespace renderpass;
66 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)67 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
68 											VkDevice				device,
69 											Allocator&				allocator,
70 											VkBuffer				buffer)
71 {
72 	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
73 	VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
74 	return allocation;
75 }
76 
createSparseImageAndMemory(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,Allocator & allocator,vector<de::SharedPtr<Allocation>> & allocations,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,deUint32 sparseQueueFamilyIndex,const VkSemaphore & bindSemaphore,VkFormat format,deUint32 width,deUint32 height)77 Move<VkImage> createSparseImageAndMemory (const DeviceInterface&				vk,
78 										  VkDevice								device,
79 										  const VkPhysicalDevice				physicalDevice,
80 										  const InstanceInterface&				instance,
81 										  Allocator&							allocator,
82 										  vector<de::SharedPtr<Allocation> >&	allocations,
83 										  deUint32								universalQueueFamilyIndex,
84 										  VkQueue								sparseQueue,
85 										  deUint32								sparseQueueFamilyIndex,
86 										  const VkSemaphore&					bindSemaphore,
87 										  VkFormat								format,
88 										  deUint32								width,
89 										  deUint32								height)
90 {
91 	deUint32				queueFamilyIndices[]	= {universalQueueFamilyIndex, sparseQueueFamilyIndex};
92 	const VkSharingMode		sharingMode             = universalQueueFamilyIndex != sparseQueueFamilyIndex ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
93 
94 	const VkExtent3D		imageExtent				=
95 	{
96 		width,
97 		height,
98 		1u
99 	};
100 
101 	const VkImageCreateInfo	imageCreateInfo			=
102 	{
103 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
104 		DE_NULL,
105 		VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
106 		VK_IMAGE_TYPE_2D,
107 		format,
108 		imageExtent,
109 		1u,
110 		1u,
111 		VK_SAMPLE_COUNT_1_BIT,
112 		VK_IMAGE_TILING_OPTIMAL,
113 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
114 		sharingMode,
115 		sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,
116 		queueFamilyIndices,
117 		VK_IMAGE_LAYOUT_UNDEFINED
118 	};
119 
120 	Move<VkImage>			destImage			= createImage(vk, device, &imageCreateInfo);
121 
122 	allocateAndBindSparseImage(vk, device, physicalDevice, instance, imageCreateInfo, bindSemaphore, sparseQueue, allocator, allocations, mapVkFormat(format), *destImage);
123 
124 	return destImage;
125 }
126 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)127 Move<VkImageView> createImageView (const DeviceInterface&	vk,
128 								   VkDevice					device,
129 								   VkImageViewCreateFlags	flags,
130 								   VkImage					image,
131 								   VkImageViewType			viewType,
132 								   VkFormat					format,
133 								   VkComponentMapping		components,
134 								   VkImageSubresourceRange	subresourceRange)
135 {
136 	const VkImageViewCreateInfo pCreateInfo =
137 	{
138 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
139 		DE_NULL,
140 		flags,
141 		image,
142 		viewType,
143 		format,
144 		components,
145 		subresourceRange,
146 	};
147 
148 	return createImageView(vk, device, &pCreateInfo);
149 }
150 
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)151 Move<VkImageView> createImageView (const DeviceInterface&	vkd,
152 								   VkDevice					device,
153 								   VkImage					image,
154 								   VkFormat					format,
155 								   VkImageAspectFlags		aspect)
156 {
157 	const VkImageSubresourceRange range =
158 	{
159 		aspect,
160 		0u,
161 		1u,
162 		0u,
163 		1u
164 	};
165 
166 	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
167 }
168 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)169 Move<VkBuffer> createBuffer (const DeviceInterface&		vkd,
170 							 VkDevice					device,
171 							 VkFormat					format,
172 							 deUint32					width,
173 							 deUint32					height)
174 {
175 	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
176 	const VkDeviceSize			pixelSize			= mapVkFormat(format).getPixelSize();
177 	const VkBufferCreateInfo	createInfo			=
178 	{
179 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
180 		DE_NULL,
181 		0u,
182 
183 		width * height * pixelSize,
184 		bufferUsage,
185 
186 		VK_SHARING_MODE_EXCLUSIVE,
187 		0u,
188 		DE_NULL
189 	};
190 
191 	return createBuffer(vkd, device, &createInfo);
192 }
193 
194 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat)195 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
196 									 VkDevice				device,
197 									 VkFormat				dstFormat)
198 {
199 	const AttachmentRef		dstAttachmentRef		//  VkAttachmentReference										||  VkAttachmentReference2KHR
200 	(
201 													//																||  VkStructureType						sType;
202 		DE_NULL,									//																||  const void*							pNext;
203 		0u,											//  deUint32						attachment;					||  deUint32							attachment;
204 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//  VkImageLayout					layout;						||  VkImageLayout						layout;
205 		0u											//																||  VkImageAspectFlags					aspectMask;
206 	);
207 	const AttachmentDesc	dstAttachment			//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
208 	(
209 													//																||  VkStructureType						sType;
210 		DE_NULL,									//																||  const void*							pNext;
211 		0u,											//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
212 		dstFormat,									//  VkFormat						format;						||  VkFormat							format;
213 		VK_SAMPLE_COUNT_1_BIT,						//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
214 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
215 		VK_ATTACHMENT_STORE_OP_STORE,				//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
216 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
217 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
218 		VK_IMAGE_LAYOUT_UNDEFINED,					//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
219 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
220 	);
221 	const SubpassDesc			subpass				//  VkSubpassDescription										||  VkSubpassDescription2KHR
222 	(
223 													//																||  VkStructureType						sType;
224 		DE_NULL,									//																||  const void*							pNext;
225 		(VkSubpassDescriptionFlags)0,				//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
226 		VK_PIPELINE_BIND_POINT_GRAPHICS,			//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
227 		0u,											//																||  deUint32							viewMask;
228 		0u,											//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
229 		DE_NULL,									//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
230 		1u,											//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
231 		&dstAttachmentRef,							//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
232 		DE_NULL,									//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
233 		DE_NULL,									//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
234 		0u,											//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
235 		DE_NULL										//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
236 	);
237 	const RenderPassCreateInfo	renderPassCreator	//  VkRenderPassCreateInfo										||  VkRenderPassCreateInfo2KHR
238 	(
239 													//  VkStructureType					sType;						||  VkStructureType						sType;
240 		DE_NULL,									//  const void*						pNext;						||  const void*							pNext;
241 		(VkRenderPassCreateFlags)0u,				//  VkRenderPassCreateFlags			flags;						||  VkRenderPassCreateFlags				flags;
242 		1u,											//  deUint32						attachmentCount;			||  deUint32							attachmentCount;
243 		&dstAttachment,								//  const VkAttachmentDescription*	pAttachments;				||  const VkAttachmentDescription2KHR*	pAttachments;
244 		1u,											//  deUint32						subpassCount;				||  deUint32							subpassCount;
245 		&subpass,									//  const VkSubpassDescription*		pSubpasses;					||  const VkSubpassDescription2KHR*		pSubpasses;
246 		0u,											//  deUint32						dependencyCount;			||  deUint32							dependencyCount;
247 		DE_NULL,									//  const VkSubpassDependency*		pDependencies;				||  const VkSubpassDependency2KHR*		pDependencies;
248 		0u,											//																||  deUint32							correlatedViewMaskCount;
249 		DE_NULL										//																||  const deUint32*						pCorrelatedViewMasks;
250 	);
251 
252 	return renderPassCreator.createRenderPass(vkd, device);
253 }
254 
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat,const RenderPassType renderPassType)255 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
256 									 VkDevice				device,
257 									 VkFormat				dstFormat,
258 									 const RenderPassType	renderPassType)
259 {
260 	switch (renderPassType)
261 	{
262 		case RENDERPASS_TYPE_LEGACY:
263 			return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, dstFormat);
264 		case RENDERPASS_TYPE_RENDERPASS2:
265 			return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, dstFormat);
266 		default:
267 			TCU_THROW(InternalError, "Impossible");
268 	}
269 }
270 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView dstImageView,deUint32 width,deUint32 height)271 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&	vkd,
272 									   VkDevice					device,
273 									   VkRenderPass				renderPass,
274 									   VkImageView				dstImageView,
275 									   deUint32					width,
276 									   deUint32					height)
277 {
278 	const VkFramebufferCreateInfo createInfo =
279 	{
280 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
281 		DE_NULL,
282 		0u,
283 
284 		renderPass,
285 		1u,
286 		&dstImageView,
287 
288 		width,
289 		height,
290 		1u
291 	};
292 
293 	return createFramebuffer(vkd, device, &createInfo);
294 }
295 
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)296 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface&	vkd,
297 												   VkDevice					device)
298 {
299 	const VkPipelineLayoutCreateInfo createInfo =
300 	{
301 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
302 		DE_NULL,
303 		(vk::VkPipelineLayoutCreateFlags)0,
304 
305 		0u,
306 		DE_NULL,
307 
308 		0u,
309 		DE_NULL
310 	};
311 
312 	return createPipelineLayout(vkd, device, &createInfo);
313 }
314 
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)315 Move<VkPipeline> createRenderPipeline (const DeviceInterface&							vkd,
316 									   VkDevice											device,
317 									   VkRenderPass										renderPass,
318 									   VkPipelineLayout									pipelineLayout,
319 									   const BinaryCollection&							binaryCollection,
320 									   deUint32											width,
321 									   deUint32											height)
322 {
323 	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
324 	const Unique<VkShaderModule>					fragmentShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
325 
326 	const VkPipelineVertexInputStateCreateInfo		vertexInputState				=
327 	{
328 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
329 		DE_NULL,
330 		(VkPipelineVertexInputStateCreateFlags)0u,
331 
332 		0u,
333 		DE_NULL,
334 
335 		0u,
336 		DE_NULL
337 	};
338 
339 	const std::vector<VkViewport>					viewports						(1, makeViewport(tcu::UVec2(width, height)));
340 	const std::vector<VkRect2D>						scissors						(1, makeRect2D(tcu::UVec2(width, height)));
341 
342 	return makeGraphicsPipeline(vkd,									// const DeviceInterface&                        vk
343 								device,									// const VkDevice                                device
344 								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
345 								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
346 								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
347 								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
348 								DE_NULL,								// const VkShaderModule                          geometryShaderModule
349 								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
350 								renderPass,								// const VkRenderPass                            renderPass
351 								viewports,								// const std::vector<VkViewport>&                viewports
352 								scissors,								// const std::vector<VkRect2D>&                  scissors
353 								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
354 								0u,										// const deUint32                                subpass
355 								0u,										// const deUint32                                patchControlPoints
356 								&vertexInputState);						// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
357 }
358 
359 struct TestConfig
360 {
TestConfigvkt::__anone8d174220111::TestConfig361 				TestConfig		(VkFormat		format_,
362 								 RenderPassType	renderPassType_)
363 		: format			(format_)
364 		, renderPassType	(renderPassType_)
365 	{
366 	}
367 
368 	VkFormat		format;
369 	RenderPassType	renderPassType;
370 };
371 
372 class SparseRenderTargetTestInstance : public TestInstance
373 {
374 public:
375 											SparseRenderTargetTestInstance	(Context& context, TestConfig testConfig);
376 											~SparseRenderTargetTestInstance	(void);
377 
378 	tcu::TestStatus							iterate					(void);
379 
380 	template<typename RenderpassSubpass>
381 	tcu::TestStatus							iterateInternal			(void);
382 
383 private:
384 	const bool								m_extensionSupported;
385 	const RenderPassType					m_renderPassType;
386 
387 	const deUint32							m_width;
388 	const deUint32							m_height;
389 	const VkFormat							m_format;
390 
391 	vector<de::SharedPtr<Allocation> >		m_allocations;
392 
393 	const Unique<VkSemaphore>				m_bindSemaphore;
394 
395 	const Unique<VkImage>					m_dstImage;
396 	const Unique<VkImageView>				m_dstImageView;
397 
398 	const Unique<VkBuffer>					m_dstBuffer;
399 	const de::UniquePtr<Allocation>			m_dstBufferMemory;
400 
401 	const Unique<VkRenderPass>				m_renderPass;
402 	const Unique<VkFramebuffer>				m_framebuffer;
403 
404 	const Unique<VkPipelineLayout>			m_renderPipelineLayout;
405 	const Unique<VkPipeline>				m_renderPipeline;
406 
407 	const Unique<VkCommandPool>				m_commandPool;
408 	tcu::ResultCollector					m_resultCollector;
409 };
410 
SparseRenderTargetTestInstance(Context & context,TestConfig testConfig)411 SparseRenderTargetTestInstance::SparseRenderTargetTestInstance (Context& context, TestConfig testConfig)
412 	: TestInstance				(context)
413 	, m_extensionSupported		((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
414 	, m_renderPassType			(testConfig.renderPassType)
415 	, m_width					(32u)
416 	, m_height					(32u)
417 	, m_format					(testConfig.format)
418 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
419 	, m_dstImage				(createSparseImageAndMemory(context.getDeviceInterface(), context.getDevice(), context.getPhysicalDevice(), context.getInstanceInterface(), context.getDefaultAllocator(), m_allocations, context.getUniversalQueueFamilyIndex(), context.getSparseQueue(), context.getSparseQueueFamilyIndex(), *m_bindSemaphore, m_format, m_width, m_height))
420 	, m_dstImageView			(createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstImage, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
421 	, m_dstBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
422 	, m_dstBufferMemory			(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
423 	, m_renderPass				(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, testConfig.renderPassType))
424 	, m_framebuffer				(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_dstImageView, m_width, m_height))
425 	, m_renderPipelineLayout	(createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
426 	, m_renderPipeline			(createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height))
427 	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
428 {
429 }
430 
~SparseRenderTargetTestInstance(void)431 SparseRenderTargetTestInstance::~SparseRenderTargetTestInstance (void)
432 {
433 }
434 
iterate(void)435 tcu::TestStatus SparseRenderTargetTestInstance::iterate (void)
436 {
437 	switch (m_renderPassType)
438 	{
439 		case RENDERPASS_TYPE_LEGACY:
440 			return iterateInternal<RenderpassSubpass1>();
441 		case RENDERPASS_TYPE_RENDERPASS2:
442 			return iterateInternal<RenderpassSubpass2>();
443 		default:
444 			TCU_THROW(InternalError, "Impossible");
445 	}
446 }
447 
448 template<typename RenderpassSubpass>
iterateInternal(void)449 tcu::TestStatus SparseRenderTargetTestInstance::iterateInternal (void)
450 
451 {
452 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
453 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
454 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
455 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
456 
457 	beginCommandBuffer(vkd, *commandBuffer);
458 
459 	{
460 		const VkRenderPassBeginInfo beginInfo =
461 		{
462 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
463 			DE_NULL,
464 
465 			*m_renderPass,
466 			*m_framebuffer,
467 
468 			{
469 				{ 0u, 0u },
470 				{ m_width, m_height }
471 			},
472 
473 			0u,
474 			DE_NULL
475 		};
476 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
477 	}
478 
479 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
480 	vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
481 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
482 
483 	copyImageToBuffer(vkd, *commandBuffer, *m_dstImage, *m_dstBuffer, tcu::IVec2(m_width, m_height));
484 
485 	endCommandBuffer(vkd, *commandBuffer);
486 
487 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
488 
489 	{
490 		const tcu::TextureFormat			format			(mapVkFormat(m_format));
491 		const void* const					ptr				(m_dstBufferMemory->getHostPtr());
492 		const tcu::ConstPixelBufferAccess	access			(format, m_width, m_height, 1, ptr);
493 		tcu::TextureLevel					reference		(format, m_width, m_height);
494 		const tcu::TextureChannelClass		channelClass	(tcu::getTextureChannelClass(format.type));
495 
496 		switch (channelClass)
497 		{
498 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
499 			{
500 				const UVec4	bits	(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
501 				const UVec4	color	(1u << (bits.x()-1), 1u << (bits.y()-2), 1u << (bits.z()-3), 0xffffffff);
502 
503 				for (deUint32 y = 0; y < m_height; y++)
504 				for (deUint32 x = 0; x < m_width; x++)
505 				{
506 					reference.getAccess().setPixel(color, x, y);
507 				}
508 
509 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
510 					m_resultCollector.fail("Compare failed.");
511 			}
512 			break;
513 
514 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
515 			{
516 				const UVec4	bits	(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
517 				const UVec4	color	(1u << (bits.x()-2), 1u << (bits.y()-3), 1u << (bits.z()-4), 0xffffffff);
518 
519 				for (deUint32 y = 0; y < m_height; y++)
520 				for (deUint32 x = 0; x < m_width; x++)
521 				{
522 					reference.getAccess().setPixel(color, x, y);
523 				}
524 
525 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
526 					m_resultCollector.fail("Compare failed.");
527 			}
528 			break;
529 
530 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
531 			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
532 			{
533 				const tcu::TextureFormatInfo	info		(tcu::getTextureFormatInfo(format));
534 				const Vec4						maxValue	(info.valueMax);
535 				const Vec4						color		(maxValue.x() / 2.0f, maxValue.y() / 4.0f, maxValue.z() / 8.0f, maxValue.w());
536 
537 				for (deUint32 y = 0; y < m_height; y++)
538 				for (deUint32 x = 0; x < m_width; x++)
539 				{
540 					if (tcu::isSRGB(format))
541 						reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
542 					else
543 						reference.getAccess().setPixel(color, x, y);
544 				}
545 
546 				{
547 					// Allow error of 4 times the minimum presentable difference
548 					const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
549 
550 					if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
551 						m_resultCollector.fail("Compare failed.");
552 				}
553 			}
554 			break;
555 
556 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
557 			{
558 				const Vec4 color(0.5f, 0.25f, 0.125f, 1.0f);
559 
560 				for (deUint32 y = 0; y < m_height; y++)
561 				for (deUint32 x = 0; x < m_width; x++)
562 				{
563 					if (tcu::isSRGB(format))
564 						reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
565 					else
566 						reference.getAccess().setPixel(color, x, y);
567 				}
568 
569 				{
570 					// Convert target format ulps to float ulps and allow 64ulp differences
571 					const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
572 
573 					if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
574 						m_resultCollector.fail("Compare failed.");
575 				}
576 			}
577 			break;
578 
579 			default:
580 				DE_FATAL("Unknown channel class");
581 		}
582 	}
583 
584 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
585 }
586 
587 struct Programs
588 {
initvkt::__anone8d174220111::Programs589 	void init (vk::SourceCollections& dst, TestConfig testConfig) const
590 	{
591 		std::ostringstream				fragmentShader;
592 		const VkFormat					format			(testConfig.format);
593 		const tcu::TextureFormat		texFormat		(mapVkFormat(format));
594 		const UVec4						bits			(tcu::getTextureFormatBitDepth(texFormat).cast<deUint32>());
595 		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(texFormat.type));
596 
597 		dst.glslSources.add("quad-vert") << glu::VertexSource(
598 			"#version 450\n"
599 			"out gl_PerVertex {\n"
600 			"\tvec4 gl_Position;\n"
601 			"};\n"
602 			"highp float;\n"
603 			"void main (void)\n"
604 			"{\n"
605 			"    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
606 			"                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
607 			"}\n");
608 
609 		switch (channelClass)
610 		{
611 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
612 			{
613 				fragmentShader <<
614 					"#version 450\n"
615 					"layout(location = 0) out highp uvec4 o_color;\n"
616 					"void main (void)\n"
617 					"{\n"
618 					"    o_color = uvec4(" << de::toString(1u << (bits.x()-1)) << ", " << de::toString(1u << (bits.y()-2)) << ", " << de::toString(1u << (bits.z()-3)) << ", 0xffffffff);"
619 					"}\n";
620 			}
621 			break;
622 
623 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
624 			{
625 				fragmentShader <<
626 					"#version 450\n"
627 					"layout(location = 0) out highp ivec4 o_color;\n"
628 					"void main (void)\n"
629 					"{\n"
630 					"    o_color = ivec4(" << de::toString(1u << (bits.x()-2)) << ", " << de::toString(1u << (bits.y()-3)) << ", " << de::toString(1u << (bits.z()-4)) << ", 0xffffffff);"
631 					"}\n";
632 			}
633 			break;
634 
635 			default:
636 			{
637 				fragmentShader <<
638 					"#version 450\n"
639 					"layout(location = 0) out highp vec4 o_color;\n"
640 					"void main (void)\n"
641 					"{\n"
642 					"    o_color = vec4(0.5, 0.25, 0.125, 1.0);\n"
643 					"}\n";
644 			}
645 			break;
646 		};
647 
648 		dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
649 	}
650 };
651 
formatToName(VkFormat format)652 std::string formatToName (VkFormat format)
653 {
654 	const std::string	formatStr	= de::toString(format);
655 	const std::string	prefix		= "VK_FORMAT_";
656 
657 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
658 
659 	return de::toLower(formatStr.substr(prefix.length()));
660 }
661 
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)662 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
663 {
664 	static const VkFormat	formats[]	=
665 	{
666 		VK_FORMAT_R5G6B5_UNORM_PACK16,
667 		VK_FORMAT_R8_UNORM,
668 		VK_FORMAT_R8_SNORM,
669 		VK_FORMAT_R8_UINT,
670 		VK_FORMAT_R8_SINT,
671 		VK_FORMAT_R8G8_UNORM,
672 		VK_FORMAT_R8G8_SNORM,
673 		VK_FORMAT_R8G8_UINT,
674 		VK_FORMAT_R8G8_SINT,
675 		VK_FORMAT_R8G8B8A8_UNORM,
676 		VK_FORMAT_R8G8B8A8_SNORM,
677 		VK_FORMAT_R8G8B8A8_UINT,
678 		VK_FORMAT_R8G8B8A8_SINT,
679 		VK_FORMAT_R8G8B8A8_SRGB,
680 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
681 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
682 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
683 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
684 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
685 		VK_FORMAT_B8G8R8A8_UNORM,
686 		VK_FORMAT_B8G8R8A8_SRGB,
687 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
688 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
689 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
690 		VK_FORMAT_R16_UNORM,
691 		VK_FORMAT_R16_SNORM,
692 		VK_FORMAT_R16_UINT,
693 		VK_FORMAT_R16_SINT,
694 		VK_FORMAT_R16_SFLOAT,
695 		VK_FORMAT_R16G16_UNORM,
696 		VK_FORMAT_R16G16_SNORM,
697 		VK_FORMAT_R16G16_UINT,
698 		VK_FORMAT_R16G16_SINT,
699 		VK_FORMAT_R16G16_SFLOAT,
700 		VK_FORMAT_R16G16B16A16_UNORM,
701 		VK_FORMAT_R16G16B16A16_SNORM,
702 		VK_FORMAT_R16G16B16A16_UINT,
703 		VK_FORMAT_R16G16B16A16_SINT,
704 		VK_FORMAT_R16G16B16A16_SFLOAT,
705 		VK_FORMAT_R32_UINT,
706 		VK_FORMAT_R32_SINT,
707 		VK_FORMAT_R32_SFLOAT,
708 		VK_FORMAT_R32G32_UINT,
709 		VK_FORMAT_R32G32_SINT,
710 		VK_FORMAT_R32G32_SFLOAT,
711 		VK_FORMAT_R32G32B32A32_UINT,
712 		VK_FORMAT_R32G32B32A32_SINT,
713 		VK_FORMAT_R32G32B32A32_SFLOAT
714 	};
715 
716 	tcu::TestContext&		testCtx		(group->getTestContext());
717 
718 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
719 	{
720 		const VkFormat		format		(formats[formatNdx]);
721 		const TestConfig	testConfig	(format, renderPassType);
722 		string				testName	(formatToName(format));
723 
724 		group->addChild(new InstanceFactory1<SparseRenderTargetTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
725 	}
726 }
727 
728 } // anonymous
729 
createRenderPassSparseRenderTargetTests(tcu::TestContext & testCtx)730 tcu::TestCaseGroup* createRenderPassSparseRenderTargetTests (tcu::TestContext& testCtx)
731 {
732 	return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERPASS_TYPE_LEGACY);
733 }
734 
createRenderPass2SparseRenderTargetTests(tcu::TestContext & testCtx)735 tcu::TestCaseGroup* createRenderPass2SparseRenderTargetTests (tcu::TestContext& testCtx)
736 {
737 	return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
738 }
739 } // vkt
740