• 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 	if (!checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo))
121 		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
122 
123 	Move<VkImage> destImage = createImage(vk, device, &imageCreateInfo);
124 	allocateAndBindSparseImage(vk, device, physicalDevice, instance, imageCreateInfo, bindSemaphore, sparseQueue, allocator, allocations, mapVkFormat(format), *destImage);
125 
126 	return destImage;
127 }
128 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)129 Move<VkImageView> createImageView (const DeviceInterface&	vk,
130 								   VkDevice					device,
131 								   VkImageViewCreateFlags	flags,
132 								   VkImage					image,
133 								   VkImageViewType			viewType,
134 								   VkFormat					format,
135 								   VkComponentMapping		components,
136 								   VkImageSubresourceRange	subresourceRange)
137 {
138 	const VkImageViewCreateInfo pCreateInfo =
139 	{
140 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
141 		DE_NULL,
142 		flags,
143 		image,
144 		viewType,
145 		format,
146 		components,
147 		subresourceRange,
148 	};
149 
150 	return createImageView(vk, device, &pCreateInfo);
151 }
152 
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)153 Move<VkImageView> createImageView (const DeviceInterface&	vkd,
154 								   VkDevice					device,
155 								   VkImage					image,
156 								   VkFormat					format,
157 								   VkImageAspectFlags		aspect)
158 {
159 	const VkImageSubresourceRange range =
160 	{
161 		aspect,
162 		0u,
163 		1u,
164 		0u,
165 		1u
166 	};
167 
168 	return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
169 }
170 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)171 Move<VkBuffer> createBuffer (const DeviceInterface&		vkd,
172 							 VkDevice					device,
173 							 VkFormat					format,
174 							 deUint32					width,
175 							 deUint32					height)
176 {
177 	const VkBufferUsageFlags	bufferUsage			(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
178 	const VkDeviceSize			pixelSize			= mapVkFormat(format).getPixelSize();
179 	const VkBufferCreateInfo	createInfo			=
180 	{
181 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
182 		DE_NULL,
183 		0u,
184 
185 		width * height * pixelSize,
186 		bufferUsage,
187 
188 		VK_SHARING_MODE_EXCLUSIVE,
189 		0u,
190 		DE_NULL
191 	};
192 
193 	return createBuffer(vkd, device, &createInfo);
194 }
195 
196 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat)197 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
198 									 VkDevice				device,
199 									 VkFormat				dstFormat)
200 {
201 	const AttachmentRef		dstAttachmentRef		//  VkAttachmentReference										||  VkAttachmentReference2KHR
202 	(
203 													//																||  VkStructureType						sType;
204 		DE_NULL,									//																||  const void*							pNext;
205 		0u,											//  deUint32						attachment;					||  deUint32							attachment;
206 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//  VkImageLayout					layout;						||  VkImageLayout						layout;
207 		0u											//																||  VkImageAspectFlags					aspectMask;
208 	);
209 	const AttachmentDesc	dstAttachment			//  VkAttachmentDescription										||  VkAttachmentDescription2KHR
210 	(
211 													//																||  VkStructureType						sType;
212 		DE_NULL,									//																||  const void*							pNext;
213 		0u,											//  VkAttachmentDescriptionFlags	flags;						||  VkAttachmentDescriptionFlags		flags;
214 		dstFormat,									//  VkFormat						format;						||  VkFormat							format;
215 		VK_SAMPLE_COUNT_1_BIT,						//  VkSampleCountFlagBits			samples;					||  VkSampleCountFlagBits				samples;
216 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//  VkAttachmentLoadOp				loadOp;						||  VkAttachmentLoadOp					loadOp;
217 		VK_ATTACHMENT_STORE_OP_STORE,				//  VkAttachmentStoreOp				storeOp;					||  VkAttachmentStoreOp					storeOp;
218 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//  VkAttachmentLoadOp				stencilLoadOp;				||  VkAttachmentLoadOp					stencilLoadOp;
219 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			//  VkAttachmentStoreOp				stencilStoreOp;				||  VkAttachmentStoreOp					stencilStoreOp;
220 		VK_IMAGE_LAYOUT_UNDEFINED,					//  VkImageLayout					initialLayout;				||  VkImageLayout						initialLayout;
221 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	//  VkImageLayout					finalLayout;				||  VkImageLayout						finalLayout;
222 	);
223 	const SubpassDesc			subpass				//  VkSubpassDescription										||  VkSubpassDescription2KHR
224 	(
225 													//																||  VkStructureType						sType;
226 		DE_NULL,									//																||  const void*							pNext;
227 		(VkSubpassDescriptionFlags)0,				//  VkSubpassDescriptionFlags		flags;						||  VkSubpassDescriptionFlags			flags;
228 		VK_PIPELINE_BIND_POINT_GRAPHICS,			//  VkPipelineBindPoint				pipelineBindPoint;			||  VkPipelineBindPoint					pipelineBindPoint;
229 		0u,											//																||  deUint32							viewMask;
230 		0u,											//  deUint32						inputAttachmentCount;		||  deUint32							inputAttachmentCount;
231 		DE_NULL,									//  const VkAttachmentReference*	pInputAttachments;			||  const VkAttachmentReference2KHR*	pInputAttachments;
232 		1u,											//  deUint32						colorAttachmentCount;		||  deUint32							colorAttachmentCount;
233 		&dstAttachmentRef,							//  const VkAttachmentReference*	pColorAttachments;			||  const VkAttachmentReference2KHR*	pColorAttachments;
234 		DE_NULL,									//  const VkAttachmentReference*	pResolveAttachments;		||  const VkAttachmentReference2KHR*	pResolveAttachments;
235 		DE_NULL,									//  const VkAttachmentReference*	pDepthStencilAttachment;	||  const VkAttachmentReference2KHR*	pDepthStencilAttachment;
236 		0u,											//  deUint32						preserveAttachmentCount;	||  deUint32							preserveAttachmentCount;
237 		DE_NULL										//  const deUint32*					pPreserveAttachments;		||  const deUint32*						pPreserveAttachments;
238 	);
239 	const RenderPassCreateInfo	renderPassCreator	//  VkRenderPassCreateInfo										||  VkRenderPassCreateInfo2KHR
240 	(
241 													//  VkStructureType					sType;						||  VkStructureType						sType;
242 		DE_NULL,									//  const void*						pNext;						||  const void*							pNext;
243 		(VkRenderPassCreateFlags)0u,				//  VkRenderPassCreateFlags			flags;						||  VkRenderPassCreateFlags				flags;
244 		1u,											//  deUint32						attachmentCount;			||  deUint32							attachmentCount;
245 		&dstAttachment,								//  const VkAttachmentDescription*	pAttachments;				||  const VkAttachmentDescription2KHR*	pAttachments;
246 		1u,											//  deUint32						subpassCount;				||  deUint32							subpassCount;
247 		&subpass,									//  const VkSubpassDescription*		pSubpasses;					||  const VkSubpassDescription2KHR*		pSubpasses;
248 		0u,											//  deUint32						dependencyCount;			||  deUint32							dependencyCount;
249 		DE_NULL,									//  const VkSubpassDependency*		pDependencies;				||  const VkSubpassDependency2KHR*		pDependencies;
250 		0u,											//																||  deUint32							correlatedViewMaskCount;
251 		DE_NULL										//																||  const deUint32*						pCorrelatedViewMasks;
252 	);
253 
254 	return renderPassCreator.createRenderPass(vkd, device);
255 }
256 
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat,const RenderingType renderingType)257 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vkd,
258 									 VkDevice				device,
259 									 VkFormat				dstFormat,
260 									 const RenderingType	renderingType)
261 {
262 	switch (renderingType)
263 	{
264 		case RENDERING_TYPE_RENDERPASS_LEGACY:
265 			return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, dstFormat);
266 		case RENDERING_TYPE_RENDERPASS2:
267 			return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, dstFormat);
268 		case RENDERING_TYPE_DYNAMIC_RENDERING:
269 			return Move<VkRenderPass>();
270 		default:
271 			TCU_THROW(InternalError, "Impossible");
272 	}
273 }
274 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView dstImageView,deUint32 width,deUint32 height)275 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&	vkd,
276 									   VkDevice					device,
277 									   VkRenderPass				renderPass,
278 									   VkImageView				dstImageView,
279 									   deUint32					width,
280 									   deUint32					height)
281 {
282 	// when RenderPass was not created then we are testing dynamic rendering
283 	// and we can't create framebuffer without valid RenderPass object
284 	if (!renderPass)
285 		return Move<VkFramebuffer>();
286 
287 	const VkFramebufferCreateInfo createInfo =
288 	{
289 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
290 		DE_NULL,
291 		0u,
292 
293 		renderPass,
294 		1u,
295 		&dstImageView,
296 
297 		width,
298 		height,
299 		1u
300 	};
301 
302 	return createFramebuffer(vkd, device, &createInfo);
303 }
304 
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)305 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface&	vkd,
306 												   VkDevice					device)
307 {
308 	const VkPipelineLayoutCreateInfo createInfo =
309 	{
310 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
311 		DE_NULL,
312 		(vk::VkPipelineLayoutCreateFlags)0,
313 
314 		0u,
315 		DE_NULL,
316 
317 		0u,
318 		DE_NULL
319 	};
320 
321 	return createPipelineLayout(vkd, device, &createInfo);
322 }
323 
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkFormat format,VkPipelineLayout pipelineLayout,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)324 Move<VkPipeline> createRenderPipeline (const DeviceInterface&							vkd,
325 									   VkDevice											device,
326 									   VkRenderPass										renderPass,
327 									   VkFormat											format,
328 									   VkPipelineLayout									pipelineLayout,
329 									   const BinaryCollection&							binaryCollection,
330 									   deUint32											width,
331 									   deUint32											height)
332 {
333 	const Unique<VkShaderModule>					vertexShaderModule				(createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
334 	const Unique<VkShaderModule>					fragmentShaderModule			(createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
335 
336 	const VkPipelineVertexInputStateCreateInfo		vertexInputState				=
337 	{
338 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
339 		DE_NULL,
340 		(VkPipelineVertexInputStateCreateFlags)0u,
341 
342 		0u,
343 		DE_NULL,
344 
345 		0u,
346 		DE_NULL
347 	};
348 
349 	const std::vector<VkViewport>					viewports						(1, makeViewport(tcu::UVec2(width, height)));
350 	const std::vector<VkRect2D>						scissors						(1, makeRect2D(tcu::UVec2(width, height)));
351 
352 	VkPipelineRenderingCreateInfoKHR* pNext = DE_NULL;
353 	VkPipelineRenderingCreateInfoKHR renderingCreateInfo
354 	{
355 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
356 		0u,
357 		DE_NULL,
358 		1u,
359 		&format,
360 		VK_FORMAT_UNDEFINED,
361 		VK_FORMAT_UNDEFINED
362 	};
363 	if (renderPass == DE_NULL)
364 		pNext = &renderingCreateInfo;
365 
366 	return makeGraphicsPipeline(vkd,									// const DeviceInterface&                        vk
367 								device,									// const VkDevice                                device
368 								pipelineLayout,							// const VkPipelineLayout                        pipelineLayout
369 								*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
370 								DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
371 								DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
372 								DE_NULL,								// const VkShaderModule                          geometryShaderModule
373 								*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
374 								renderPass,								// const VkRenderPass                            renderPass
375 								viewports,								// const std::vector<VkViewport>&                viewports
376 								scissors,								// const std::vector<VkRect2D>&                  scissors
377 								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
378 								0u,										// const deUint32                                subpass
379 								0u,										// const deUint32                                patchControlPoints
380 								&vertexInputState,						// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
381 								DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
382 								DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
383 								DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
384 								DE_NULL,								// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
385 								DE_NULL,								// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
386 								pNext);									// const void*                                   pNext
387 }
388 
beginSecondaryCmdBuffer(const DeviceInterface & vkd,VkCommandBuffer cmdBuffer,VkFormat colorFormat,VkRenderingFlagsKHR renderingFlags=0u)389 void beginSecondaryCmdBuffer(const DeviceInterface& vkd, VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags = 0u)
390 {
391 	VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
392 	{
393 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,		// VkStructureType					sType;
394 		DE_NULL,																// const void*						pNext;
395 		renderingFlags,															// VkRenderingFlagsKHR				flags;
396 		0u,																		// uint32_t							viewMask;
397 		1u,																		// uint32_t							colorAttachmentCount;
398 		&colorFormat,															// const VkFormat*					pColorAttachmentFormats;
399 		VK_FORMAT_UNDEFINED,													// VkFormat							depthAttachmentFormat;
400 		VK_FORMAT_UNDEFINED,													// VkFormat							stencilAttachmentFormat;
401 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			rasterizationSamples;
402 	};
403 	const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
404 
405 	VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
406 	if (renderingFlags == 0u)
407 		usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
408 
409 	const VkCommandBufferBeginInfo commandBufBeginParams
410 	{
411 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
412 		DE_NULL,																// const void*						pNext;
413 		usageFlags,																// VkCommandBufferUsageFlags		flags;
414 		&bufferInheritanceInfo
415 	};
416 
417 	vkd.beginCommandBuffer(cmdBuffer, &commandBufBeginParams);
418 }
419 
420 struct TestConfig
421 {
TestConfigvkt::__anone313f19a0111::TestConfig422 				TestConfig		(VkFormat					format_,
423 								 const SharedGroupParams	groupParams_)
424 		: format			(format_)
425 		, groupParams		(groupParams_)
426 	{
427 	}
428 
429 	VkFormat				format;
430 	const SharedGroupParams	groupParams;
431 };
432 
433 class SparseRenderTargetTestInstance : public TestInstance
434 {
435 public:
436 											SparseRenderTargetTestInstance	(Context& context, TestConfig testConfig);
437 											~SparseRenderTargetTestInstance	(void);
438 
439 	tcu::TestStatus							iterate							(void);
440 
441 	template<typename RenderpassSubpass>
442 	tcu::TestStatus							iterateInternal					(void);
443 	tcu::TestStatus							iterateInternalDynamicRendering	(void);
444 
445 	tcu::TestStatus							verify							(void);
446 
447 private:
448 	const SharedGroupParams					m_groupParams;
449 
450 	const deUint32							m_width;
451 	const deUint32							m_height;
452 	const VkFormat							m_format;
453 
454 	vector<de::SharedPtr<Allocation> >		m_allocations;
455 
456 	const Unique<VkSemaphore>				m_bindSemaphore;
457 
458 	const Unique<VkImage>					m_dstImage;
459 	const Unique<VkImageView>				m_dstImageView;
460 
461 	const Unique<VkBuffer>					m_dstBuffer;
462 	const de::UniquePtr<Allocation>			m_dstBufferMemory;
463 
464 	const Unique<VkRenderPass>				m_renderPass;
465 	const Unique<VkFramebuffer>				m_framebuffer;
466 
467 	const Unique<VkPipelineLayout>			m_renderPipelineLayout;
468 	const Unique<VkPipeline>				m_renderPipeline;
469 
470 	const Unique<VkCommandPool>				m_commandPool;
471 	tcu::ResultCollector					m_resultCollector;
472 };
473 
SparseRenderTargetTestInstance(Context & context,TestConfig testConfig)474 SparseRenderTargetTestInstance::SparseRenderTargetTestInstance (Context& context, TestConfig testConfig)
475 	: TestInstance				(context)
476 	, m_groupParams				(testConfig.groupParams)
477 	, m_width					(32u)
478 	, m_height					(32u)
479 	, m_format					(testConfig.format)
480 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
481 	, 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))
482 	, m_dstImageView			(createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstImage, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
483 	, m_dstBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
484 	, m_dstBufferMemory			(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
485 	, m_renderPass				(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, testConfig.groupParams->renderingType))
486 	, m_framebuffer				(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_dstImageView, m_width, m_height))
487 	, m_renderPipelineLayout	(createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
488 	, m_renderPipeline			(createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, testConfig.format, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height))
489 	, m_commandPool				(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
490 {
491 }
492 
~SparseRenderTargetTestInstance(void)493 SparseRenderTargetTestInstance::~SparseRenderTargetTestInstance (void)
494 {
495 }
496 
iterate(void)497 tcu::TestStatus SparseRenderTargetTestInstance::iterate (void)
498 {
499 	switch (m_groupParams->renderingType)
500 	{
501 		case RENDERING_TYPE_RENDERPASS_LEGACY:
502 			return iterateInternal<RenderpassSubpass1>();
503 		case RENDERING_TYPE_RENDERPASS2:
504 			return iterateInternal<RenderpassSubpass2>();
505 		case RENDERING_TYPE_DYNAMIC_RENDERING:
506 			return iterateInternalDynamicRendering();
507 		default:
508 			TCU_THROW(InternalError, "Impossible");
509 	}
510 }
511 
512 template<typename RenderpassSubpass>
iterateInternal(void)513 tcu::TestStatus SparseRenderTargetTestInstance::iterateInternal (void)
514 {
515 	const DeviceInterface&			vkd				(m_context.getDeviceInterface());
516 	const Unique<VkCommandBuffer>	commandBuffer	(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
517 	const VkRect2D					renderArea		= makeRect2D(m_width, m_height);
518 
519 	beginCommandBuffer(vkd, *commandBuffer);
520 
521 	const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
522 	const VkRenderPassBeginInfo beginInfo
523 	{
524 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
525 		DE_NULL,
526 		*m_renderPass,
527 		*m_framebuffer,
528 		renderArea,
529 		0u,
530 		DE_NULL
531 	};
532 	RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
533 
534 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
535 	vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
536 
537 	const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
538 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
539 
540 	copyImageToBuffer(vkd, *commandBuffer, *m_dstImage, *m_dstBuffer, tcu::IVec2(m_width, m_height));
541 
542 	endCommandBuffer(vkd, *commandBuffer);
543 
544 	const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT };
545 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer, false, 1u, 1u, &m_bindSemaphore.get(), stageBits);
546 
547 	return verify();
548 }
549 
iterateInternalDynamicRendering(void)550 tcu::TestStatus SparseRenderTargetTestInstance::iterateInternalDynamicRendering(void)
551 {
552 	const DeviceInterface&			vkd				(m_context.getDeviceInterface());
553 	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
554 	Move<VkCommandBuffer>			secCmdBuffer;
555 	const VkRect2D					renderArea		= makeRect2D(m_width, m_height);
556 	const VkClearValue				clearValue		= makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
557 	const VkImageMemoryBarrier		barrier
558 	{
559 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
560 		DE_NULL,
561 
562 		0,
563 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
564 
565 		VK_IMAGE_LAYOUT_UNDEFINED,
566 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
567 
568 		VK_QUEUE_FAMILY_IGNORED,
569 		VK_QUEUE_FAMILY_IGNORED,
570 
571 		*m_dstImage,
572 		{
573 			VK_IMAGE_ASPECT_COLOR_BIT,
574 			0u,
575 			1u,
576 			0u,
577 			1u
578 		}
579 	};
580 
581 	if (m_groupParams->useSecondaryCmdBuffer)
582 	{
583 		secCmdBuffer = allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
584 
585 		// record secondary command buffer
586 		if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
587 		{
588 			beginSecondaryCmdBuffer(vkd, *secCmdBuffer, m_format, vk::VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
589 			beginRendering(vkd, *secCmdBuffer, *m_dstImageView, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
590 		}
591 		else
592 			beginSecondaryCmdBuffer(vkd, *secCmdBuffer, m_format);
593 
594 		vkd.cmdBindPipeline(*secCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
595 		vkd.cmdDraw(*secCmdBuffer, 6u, 1u, 0u, 0u);
596 
597 		if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
598 			vkd.cmdEndRendering(*secCmdBuffer);
599 
600 		endCommandBuffer(vkd, *secCmdBuffer);
601 
602 		// record primary command buffer
603 		beginCommandBuffer(vkd, *cmdBuffer, 0u);
604 		vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
605 
606 		if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
607 			beginRendering(vkd, *cmdBuffer, *m_dstImageView, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
608 
609 		vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
610 
611 		if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
612 			vkd.cmdEndRendering(*cmdBuffer);
613 	}
614 	else
615 	{
616 		beginCommandBuffer(vkd, *cmdBuffer);
617 
618 		vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
619 
620 		beginRendering(vkd, *cmdBuffer, *m_dstImageView, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
621 
622 		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
623 		vkd.cmdDraw(*cmdBuffer, 6u, 1u, 0u, 0u);
624 
625 		vkd.cmdEndRendering(*cmdBuffer);
626 	}
627 
628 	copyImageToBuffer(vkd, *cmdBuffer, *m_dstImage, *m_dstBuffer, tcu::IVec2(m_width, m_height));
629 
630 	endCommandBuffer(vkd, *cmdBuffer);
631 
632 	const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT };
633 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *cmdBuffer, false, 1u, 1u, &m_bindSemaphore.get(), stageBits);
634 
635 	return verify();
636 }
637 
verify(void)638 tcu::TestStatus SparseRenderTargetTestInstance::verify(void)
639 {
640 	const tcu::TextureFormat			format			(mapVkFormat(m_format));
641 	const void* const					ptr				(m_dstBufferMemory->getHostPtr());
642 	const tcu::ConstPixelBufferAccess	access			(format, m_width, m_height, 1, ptr);
643 	tcu::TextureLevel					reference		(format, m_width, m_height);
644 	const tcu::TextureChannelClass		channelClass	(tcu::getTextureChannelClass(format.type));
645 
646 	switch (channelClass)
647 	{
648 	case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
649 	{
650 		const UVec4	bits(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
651 		const UVec4	color(1u << (bits.x() - 1), 1u << (bits.y() - 2), 1u << (bits.z() - 3), 0xffffffff);
652 
653 		for (deUint32 y = 0; y < m_height; y++)
654 			for (deUint32 x = 0; x < m_width; x++)
655 				reference.getAccess().setPixel(color, x, y);
656 
657 		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
658 			m_resultCollector.fail("Compare failed.");
659 	}
660 	break;
661 
662 	case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
663 	{
664 		const UVec4	bits(tcu::getTextureFormatBitDepth(format).cast<deUint32>());
665 		const UVec4	color(1u << (bits.x() - 2), 1u << (bits.y() - 3), 1u << (bits.z() - 4), 0xffffffff);
666 
667 		for (deUint32 y = 0; y < m_height; y++)
668 			for (deUint32 x = 0; x < m_width; x++)
669 				reference.getAccess().setPixel(color, x, y);
670 
671 		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
672 			m_resultCollector.fail("Compare failed.");
673 	}
674 	break;
675 
676 	case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
677 	case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
678 	{
679 		const tcu::TextureFormatInfo	info(tcu::getTextureFormatInfo(format));
680 		const Vec4						maxValue(info.valueMax);
681 		const Vec4						color(maxValue.x() / 2.0f, maxValue.y() / 4.0f, maxValue.z() / 8.0f, maxValue.w());
682 
683 		for (deUint32 y = 0; y < m_height; y++)
684 			for (deUint32 x = 0; x < m_width; x++)
685 			{
686 				if (tcu::isSRGB(format))
687 					reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
688 				else
689 					reference.getAccess().setPixel(color, x, y);
690 			}
691 
692 		{
693 			// Allow error of 4 times the minimum presentable difference
694 			const Vec4 threshold(4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
695 
696 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
697 				m_resultCollector.fail("Compare failed.");
698 		}
699 	}
700 	break;
701 
702 	case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
703 	{
704 		const Vec4 color(0.5f, 0.25f, 0.125f, 1.0f);
705 
706 		for (deUint32 y = 0; y < m_height; y++)
707 			for (deUint32 x = 0; x < m_width; x++)
708 			{
709 				if (tcu::isSRGB(format))
710 					reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
711 				else
712 					reference.getAccess().setPixel(color, x, y);
713 			}
714 
715 		{
716 			// Convert target format ulps to float ulps and allow 64ulp differences
717 			const UVec4 threshold(64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
718 
719 			if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
720 				m_resultCollector.fail("Compare failed.");
721 		}
722 	}
723 	break;
724 
725 	default:
726 		DE_FATAL("Unknown channel class");
727 	}
728 
729 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
730 }
731 
732 struct Programs
733 {
initvkt::__anone313f19a0111::Programs734 	void init (vk::SourceCollections& dst, TestConfig testConfig) const
735 	{
736 		std::ostringstream				fragmentShader;
737 		const VkFormat					format			(testConfig.format);
738 		const tcu::TextureFormat		texFormat		(mapVkFormat(format));
739 		const UVec4						bits			(tcu::getTextureFormatBitDepth(texFormat).cast<deUint32>());
740 		const tcu::TextureChannelClass	channelClass	(tcu::getTextureChannelClass(texFormat.type));
741 
742 		dst.glslSources.add("quad-vert") << glu::VertexSource(
743 			"#version 450\n"
744 			"out gl_PerVertex {\n"
745 			"\tvec4 gl_Position;\n"
746 			"};\n"
747 			"highp float;\n"
748 			"void main (void)\n"
749 			"{\n"
750 			"    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
751 			"                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
752 			"}\n");
753 
754 		switch (channelClass)
755 		{
756 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
757 			{
758 				fragmentShader <<
759 					"#version 450\n"
760 					"layout(location = 0) out highp uvec4 o_color;\n"
761 					"void main (void)\n"
762 					"{\n"
763 					"    o_color = uvec4(" << de::toString(1u << (bits.x()-1)) << ", " << de::toString(1u << (bits.y()-2)) << ", " << de::toString(1u << (bits.z()-3)) << ", 0xffffffff);"
764 					"}\n";
765 			}
766 			break;
767 
768 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
769 			{
770 				fragmentShader <<
771 					"#version 450\n"
772 					"layout(location = 0) out highp ivec4 o_color;\n"
773 					"void main (void)\n"
774 					"{\n"
775 					"    o_color = ivec4(" << de::toString(1u << (bits.x()-2)) << ", " << de::toString(1u << (bits.y()-3)) << ", " << de::toString(1u << (bits.z()-4)) << ", 0xffffffff);"
776 					"}\n";
777 			}
778 			break;
779 
780 			default:
781 			{
782 				fragmentShader <<
783 					"#version 450\n"
784 					"layout(location = 0) out highp vec4 o_color;\n"
785 					"void main (void)\n"
786 					"{\n"
787 					"    o_color = vec4(0.5, 0.25, 0.125, 1.0);\n"
788 					"}\n";
789 			}
790 			break;
791 		}
792 
793 		dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
794 	}
795 };
796 
formatToName(VkFormat format)797 std::string formatToName (VkFormat format)
798 {
799 	const std::string	formatStr	= de::toString(format);
800 	const std::string	prefix		= "VK_FORMAT_";
801 
802 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
803 
804 	return de::toLower(formatStr.substr(prefix.length()));
805 }
806 
807 template<class TestConfigType>
checkSupport(Context & context,TestConfigType config)808 void checkSupport(Context& context, TestConfigType config)
809 {
810 #ifndef CTS_USES_VULKANSC
811 	if (config.format == VK_FORMAT_A8_UNORM_KHR)
812 		context.requireDeviceFunctionality("VK_KHR_maintenance5");
813 #endif // CTS_USES_VULKANSC
814 
815 	if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
816 		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
817 
818 	if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
819 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
820 
821 	const auto& vki = context.getInstanceInterface();
822 	const auto& physicalDevice = context.getPhysicalDevice();
823 	VkImageFormatProperties formatProperties;
824 	const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, config.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0u, &formatProperties);
825 	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
826 		TCU_THROW(NotSupportedError, "Image format not supported");
827 	}
828 }
829 
initTests(tcu::TestCaseGroup * group,const SharedGroupParams groupParams)830 void initTests (tcu::TestCaseGroup* group, const SharedGroupParams groupParams)
831 {
832 	static const VkFormat	formats[]	=
833 	{
834 		VK_FORMAT_R5G6B5_UNORM_PACK16,
835 		VK_FORMAT_R8_UNORM,
836 		VK_FORMAT_R8_SNORM,
837 		VK_FORMAT_R8_UINT,
838 		VK_FORMAT_R8_SINT,
839 #ifndef CTS_USES_VULKANSC
840 		VK_FORMAT_A8_UNORM_KHR,
841 #endif // CTS_USES_VULKANSC
842 		VK_FORMAT_R8G8_UNORM,
843 		VK_FORMAT_R8G8_SNORM,
844 		VK_FORMAT_R8G8_UINT,
845 		VK_FORMAT_R8G8_SINT,
846 		VK_FORMAT_R8G8B8A8_UNORM,
847 		VK_FORMAT_R8G8B8A8_SNORM,
848 		VK_FORMAT_R8G8B8A8_UINT,
849 		VK_FORMAT_R8G8B8A8_SINT,
850 		VK_FORMAT_R8G8B8A8_SRGB,
851 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
852 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
853 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
854 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
855 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
856 		VK_FORMAT_B8G8R8A8_UNORM,
857 		VK_FORMAT_B8G8R8A8_SRGB,
858 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
859 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
860 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
861 		VK_FORMAT_R16_UNORM,
862 		VK_FORMAT_R16_SNORM,
863 		VK_FORMAT_R16_UINT,
864 		VK_FORMAT_R16_SINT,
865 		VK_FORMAT_R16_SFLOAT,
866 		VK_FORMAT_R16G16_UNORM,
867 		VK_FORMAT_R16G16_SNORM,
868 		VK_FORMAT_R16G16_UINT,
869 		VK_FORMAT_R16G16_SINT,
870 		VK_FORMAT_R16G16_SFLOAT,
871 		VK_FORMAT_R16G16B16A16_UNORM,
872 		VK_FORMAT_R16G16B16A16_SNORM,
873 		VK_FORMAT_R16G16B16A16_UINT,
874 		VK_FORMAT_R16G16B16A16_SINT,
875 		VK_FORMAT_R16G16B16A16_SFLOAT,
876 		VK_FORMAT_R32_UINT,
877 		VK_FORMAT_R32_SINT,
878 		VK_FORMAT_R32_SFLOAT,
879 		VK_FORMAT_R32G32_UINT,
880 		VK_FORMAT_R32G32_SINT,
881 		VK_FORMAT_R32G32_SFLOAT,
882 		VK_FORMAT_R32G32B32A32_UINT,
883 		VK_FORMAT_R32G32B32A32_SINT,
884 		VK_FORMAT_R32G32B32A32_SFLOAT,
885 		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
886 	};
887 
888 	tcu::TestContext&		testCtx		(group->getTestContext());
889 
890 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
891 	{
892 		const VkFormat		format		(formats[formatNdx]);
893 		const TestConfig	testConfig	(format, groupParams);
894 		string				testName	(formatToName(format));
895 
896 		group->addChild(new InstanceFactory1WithSupport<SparseRenderTargetTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
897 	}
898 }
899 
900 } // anonymous
901 
createRenderPassSparseRenderTargetTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)902 tcu::TestCaseGroup* createRenderPassSparseRenderTargetTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
903 {
904 	return createTestGroup(testCtx, "sparserendertarget", initTests, groupParams);
905 }
906 
createRenderPass2SparseRenderTargetTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)907 tcu::TestCaseGroup* createRenderPass2SparseRenderTargetTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
908 {
909 	return createTestGroup(testCtx, "sparserendertarget", initTests, groupParams);
910 }
911 
createDynamicRenderingSparseRenderTargetTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)912 tcu::TestCaseGroup* createDynamicRenderingSparseRenderTargetTests(tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
913 {
914 	return createTestGroup(testCtx, "sparserendertarget", initTests, groupParams);
915 }
916 
917 } // vkt
918