• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan Get Render Area Granularity Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiGranularityTests.hpp"
26 
27 #include "deRandom.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deStringUtil.hpp"
30 #include "deUniquePtr.hpp"
31 
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "vktTestCase.hpp"
40 
41 #include "tcuTestLog.hpp"
42 #include "tcuTextureUtil.hpp"
43 
44 #include <string>
45 
46 namespace vkt
47 {
48 
49 namespace api
50 {
51 
52 using namespace vk;
53 
54 namespace
55 {
56 
57 enum class TestMode
58 {
59 	NO_RENDER_PASS = 0,
60 	USE_RENDER_PASS,
61 	USE_DYNAMIC_RENDER_PASS,
62 };
63 
64 struct AttachmentInfo
65 {
AttachmentInfovkt::api::__anon96148d5c0111::AttachmentInfo66 	AttachmentInfo (const VkFormat	vkFormat,
67 					const deUint32	width,
68 					const deUint32	height,
69 					const deUint32	depth)
70 		: format	(vkFormat)
71 	{
72 		extent.width	= width;
73 		extent.height	= height;
74 		extent.depth	= depth;
75 	}
76 
~AttachmentInfovkt::api::__anon96148d5c0111::AttachmentInfo77 	~AttachmentInfo (void)
78 	{}
79 
80 	VkFormat	format;
81 	VkExtent3D	extent;
82 };
83 
84 typedef de::SharedPtr<Allocation>			AllocationSp;
85 typedef de::SharedPtr<Unique<VkImage> >		VkImageSp;
86 typedef de::SharedPtr<Unique<VkImageView> >	VkImageViewSp;
87 
88 class GranularityInstance : public vkt::TestInstance
89 {
90 public:
91 											GranularityInstance			(Context&							context,
92 																		 const std::vector<AttachmentInfo>&	attachments,
93 																		 const TestMode						testMode);
94 	virtual									~GranularityInstance		(void) = default;
95 	void									initAttachmentDescriptions	(void);
96 	void									initImages					(void);
97 	void									initObjects					(void);
98 	virtual	tcu::TestStatus					iterate						(void);
99 private:
100 	const std::vector<AttachmentInfo>		m_attachments;
101 	const TestMode							m_testMode;
102 
103 	Move<VkRenderPass>						m_renderPass;
104 	Move<VkFramebuffer>						m_frameBuffer;
105 	Move<VkCommandPool>						m_cmdPool;
106 	Move<VkCommandBuffer>					m_cmdBuffer;
107 	std::vector<VkAttachmentDescription>	m_attachmentDescriptions;
108 	std::vector<VkImageSp>					m_images;
109 	std::vector<AllocationSp>				m_imageAllocs;
110 	std::vector<VkImageViewSp>				m_imageViews;
111 };
112 
GranularityInstance(Context & context,const std::vector<AttachmentInfo> & attachments,const TestMode testMode)113 GranularityInstance::GranularityInstance (Context&								context,
114 										  const std::vector<AttachmentInfo>&	attachments,
115 										  const TestMode						testMode)
116 	: vkt::TestInstance	(context)
117 	, m_attachments		(attachments)
118 	, m_testMode		(testMode)
119 {
120 	initAttachmentDescriptions();
121 }
122 
initAttachmentDescriptions(void)123 void GranularityInstance::initAttachmentDescriptions (void)
124 {
125 	VkAttachmentDescription	attachmentDescription	=
126 	{
127 		0u,									// VkAttachmentDescriptionFlags	flags;
128 		VK_FORMAT_UNDEFINED,				// VkFormat						format;
129 		VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits		samples;
130 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp			loadOp;
131 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp			storeOp;
132 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp			stencilLoadOp;
133 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp			stencilStoreOp;
134 		VK_IMAGE_LAYOUT_UNDEFINED,			// VkImageLayout				initialLayout;
135 		VK_IMAGE_LAYOUT_GENERAL,			// VkImageLayout				finalLayout;
136 	};
137 
138 	for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
139 	{
140 		attachmentDescription.format = it->format;
141 		m_attachmentDescriptions.push_back(attachmentDescription);
142 	}
143 }
144 
initImages(void)145 void GranularityInstance::initImages (void)
146 {
147 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
148 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
149 	const VkPhysicalDevice		physicalDevice		= m_context.getPhysicalDevice();
150 	const VkDevice				device				= m_context.getDevice();
151 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
152 	SimpleAllocator				memAlloc			(vk, device, getPhysicalDeviceMemoryProperties(vki, physicalDevice));
153 
154 	for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
155 	{
156 		VkImageAspectFlags			aspectFlags	= 0;
157 		VkImageUsageFlags			usage		= 0u;
158 		const tcu::TextureFormat	tcuFormat	= mapVkFormat(it->format);
159 
160 		if (tcu::hasDepthComponent(tcuFormat.order))
161 		{
162 			aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
163 			usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
164 		}
165 
166 		if (tcu::hasStencilComponent(tcuFormat.order))
167 		{
168 			aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
169 			usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
170 		}
171 
172 		if (!aspectFlags)
173 		{
174 			aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
175 			usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
176 		}
177 
178 		const VkImageCreateInfo imageInfo
179 		{
180 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
181 			DE_NULL,								// const void*			pNext;
182 			0u,										// VkImageCreateFlags	flags;
183 			VK_IMAGE_TYPE_2D,						// VkImageType			imageType;
184 			it->format,								// VkFormat				format;
185 			it->extent,								// VkExtent3D			extent;
186 			1u,										// deUint32				mipLevels;
187 			1u,										// deUint32				arrayLayers;
188 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
189 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
190 			usage,									// VkImageUsageFlags	usage;
191 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
192 			1u,										// deUint32				queueFamilyCount;
193 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
194 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
195 		};
196 
197 		// Create the image
198 		Move<VkImage>			image		= createImage(vk, device, &imageInfo);
199 		de::MovePtr<Allocation>	imageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any);
200 		VK_CHECK(vk.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
201 
202 		const VkImageViewCreateInfo		createInfo	=
203 		{
204 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
205 			DE_NULL,										// const void*				pNext;
206 			0,												// VkImageViewCreateFlags	flags;
207 			*image,											// VkImage					image;
208 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
209 			it->format,										// VkFormat					format;
210 			{
211 				VK_COMPONENT_SWIZZLE_R,
212 				VK_COMPONENT_SWIZZLE_G,
213 				VK_COMPONENT_SWIZZLE_B,
214 				VK_COMPONENT_SWIZZLE_A
215 			},												// VkComponentMapping		components;
216 			{ aspectFlags, 0u, 1u, 0u, 1u	}	// VkImageSubresourceRange	subresourceRange;
217 		};
218 
219 		// Create the Image View
220 		Move<VkImageView>	imageView		= createImageView(vk, device, &createInfo);
221 
222 		// To prevent object free
223 		m_images.push_back(VkImageSp(new Unique<VkImage>(image)));
224 		m_imageAllocs.push_back(AllocationSp(imageAlloc.release()));
225 		m_imageViews.push_back(VkImageViewSp(new Unique<VkImageView>(imageView)));
226 	}
227 }
228 
initObjects(void)229 void GranularityInstance::initObjects (void)
230 {
231 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
232 	const VkDevice				device				= m_context.getDevice();
233 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
234 
235 	initImages();
236 
237 	// Create RenderPass and Framebuffer
238 	if (m_testMode != TestMode::USE_DYNAMIC_RENDER_PASS)
239 	{
240 		const VkSubpassDescription subpassDesc
241 		{
242 			(VkSubpassDescriptionFlags)0u,		// VkSubpassDescriptionFlags		flags;
243 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint;
244 			0u,									// deUint32							inputCount;
245 			DE_NULL,							// const VkAttachmentReference*		pInputAttachments;
246 			0u,									// deUint32							colorCount;
247 			DE_NULL,							// const VkAttachmentReference*		pColorAttachments;
248 			DE_NULL,							// const VkAttachmentReference*		pResolveAttachments;
249 			DE_NULL,							// VkAttachmentReference			depthStencilAttachment;
250 			0u,									// deUint32							preserveCount;
251 			DE_NULL								// const VkAttachmentReference*		pPreserveAttachments;
252 		};
253 
254 		const VkRenderPassCreateInfo renderPassParams
255 		{
256 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
257 			DE_NULL,									// const void*						pNext;
258 			(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags			flags;
259 			(deUint32)m_attachmentDescriptions.size(),	// deUint32							attachmentCount;
260 			&m_attachmentDescriptions[0],				// const VkAttachmentDescription*	pAttachments;
261 			1u,											// deUint32							subpassCount;
262 			&subpassDesc,								// const VkSubpassDescription*		pSubpasses;
263 			0u,											// deUint32							dependencyCount;
264 			DE_NULL										// const VkSubpassDependency*		pDependencies;
265 		};
266 
267 		m_renderPass	= createRenderPass(vk, device, &renderPassParams);
268 
269 		std::vector<VkImageView>	imageViews;
270 		for (std::vector<VkImageViewSp>::const_iterator it = m_imageViews.begin(); it != m_imageViews.end(); ++it)
271 			imageViews.push_back(it->get()->get());
272 
273 		const VkFramebufferCreateInfo framebufferParams
274 		{
275 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
276 			DE_NULL,									// const void*				pNext;
277 			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags	flags;
278 			*m_renderPass,								// VkRenderPass				renderPass;
279 			(deUint32)imageViews.size(),				// deUint32					attachmentCount;
280 			&imageViews[0],								// const VkImageView*		pAttachments;
281 			1,											// deUint32					width;
282 			1,											// deUint32					height;
283 			1											// deUint32					layers;
284 		};
285 
286 		m_frameBuffer	= createFramebuffer(vk, device, &framebufferParams);
287 	}
288 
289 	m_cmdPool	= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
290 
291 	// Create CommandBuffer
292 	m_cmdBuffer	= allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
293 }
294 
iterate(void)295 tcu::TestStatus GranularityInstance::iterate (void)
296 {
297 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
298 	const VkDevice			device		= m_context.getDevice();
299 	tcu::TestLog&			log			= m_context.getTestContext().getLog();
300 	const VkRect2D			renderArea	= makeRect2D(1u, 1u);
301 
302 	VkExtent2D	prePassGranularity	= { ~0u, ~0u };
303 	VkExtent2D	granularity			= { 0u, 0u };
304 
305 	initObjects();
306 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
307 
308 #ifndef CTS_USES_VULKANSC
309 	if (m_testMode == TestMode::USE_DYNAMIC_RENDER_PASS)
310 	{
311 		VkImageSubresourceRange subresourceRange(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
312 		std::vector<VkFormat> colorAttachmentFormats;
313 		VkFormat depthAttachmentFormat		= VK_FORMAT_UNDEFINED;
314 		VkFormat stencilAttachmentFormat	= VK_FORMAT_UNDEFINED;
315 
316 		VkRenderingAttachmentInfoKHR defaultAttachment = initVulkanStructure();
317 		defaultAttachment.imageLayout	= VK_IMAGE_LAYOUT_GENERAL;
318 		defaultAttachment.loadOp		= VK_ATTACHMENT_LOAD_OP_DONT_CARE;
319 		defaultAttachment.storeOp		= VK_ATTACHMENT_STORE_OP_DONT_CARE;
320 
321 		std::vector<VkRenderingAttachmentInfoKHR> colorAttachmentInfo;
322 		VkRenderingAttachmentInfoKHR depthAttachmentInfo = defaultAttachment;
323 		VkRenderingAttachmentInfoKHR stencilAttachmentInfo = defaultAttachment;
324 
325 		for (deUint32 i = 0 ; i < m_attachments.size() ; ++i)
326 		{
327 			const auto	format			= m_attachments[i].format;
328 			const auto	tcuFormat		= mapVkFormat(format);
329 			bool		isColorFormat	= true;
330 
331 			subresourceRange.aspectMask = 0;
332 
333 			if (tcu::hasDepthComponent(tcuFormat.order))
334 			{
335 				subresourceRange.aspectMask		= VK_IMAGE_ASPECT_DEPTH_BIT;
336 				depthAttachmentFormat			= format;
337 				depthAttachmentInfo.imageView	= **m_imageViews[i];
338 				isColorFormat					= false;
339 			}
340 			if (tcu::hasStencilComponent(tcuFormat.order))
341 			{
342 				subresourceRange.aspectMask		|= VK_IMAGE_ASPECT_STENCIL_BIT;
343 				stencilAttachmentFormat			= format;
344 				stencilAttachmentInfo.imageView	= **m_imageViews[i];
345 				isColorFormat					= false;
346 			}
347 			if (isColorFormat)
348 			{
349 				subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
350 				colorAttachmentFormats.push_back(format);
351 				colorAttachmentInfo.push_back(defaultAttachment);
352 				colorAttachmentInfo.back().imageView = **m_imageViews[i];
353 			}
354 
355 			// transition layout
356 			const VkImageMemoryBarrier layoutBarrier(makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, **m_images[i], subresourceRange));
357 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &layoutBarrier);
358 		}
359 
360 		VkRenderingAreaInfoKHR renderingAreaInfo
361 		{
362 			VK_STRUCTURE_TYPE_RENDERING_AREA_INFO_KHR,	// VkStructureType		sType;
363 			nullptr,									// const void*			pNext;
364 			0,											// uint32_t				viewMask;
365 			(deUint32)colorAttachmentFormats.size(),	// uint32_t				colorAttachmentCount;
366 			colorAttachmentFormats.data(),				// const VkFormat*		pColorAttachmentFormats;
367 			depthAttachmentFormat,						// VkFormat				depthAttachmentFormat;
368 			stencilAttachmentFormat						// VkFormat				stencilAttachmentFormat;
369 		};
370 
371 		vk.getRenderingAreaGranularityKHR(device, &renderingAreaInfo, &prePassGranularity);
372 
373 		// start dynamic render pass
374 		VkRenderingInfoKHR renderingInfo
375 		{
376 			VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
377 			DE_NULL,
378 			0u,															// VkRenderingFlagsKHR					flags;
379 			renderArea,													// VkRect2D								renderArea;
380 			1u,															// deUint32								layerCount;
381 			0u,															// deUint32								viewMask;
382 			(deUint32)colorAttachmentInfo.size(),						// deUint32								colorAttachmentCount;
383 			colorAttachmentInfo.data(),									// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
384 			depthAttachmentFormat ? &depthAttachmentInfo : DE_NULL,		// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
385 			stencilAttachmentFormat ? &stencilAttachmentInfo : DE_NULL,	// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
386 		};
387 		vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
388 
389 		vk.getRenderingAreaGranularityKHR(device, &renderingAreaInfo, &granularity);
390 	}
391 #endif
392 
393 	if (m_testMode != TestMode::USE_DYNAMIC_RENDER_PASS)
394 	{
395 		vk.getRenderAreaGranularity(device, *m_renderPass, &prePassGranularity);
396 
397 		if (m_testMode == TestMode::USE_RENDER_PASS)
398 			beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_frameBuffer, renderArea);
399 
400 		vk.getRenderAreaGranularity(device, *m_renderPass, &granularity);
401 	}
402 
403 	TCU_CHECK(granularity.width >= 1 && granularity.height >= 1);
404 	TCU_CHECK(prePassGranularity.width == granularity.width && prePassGranularity.height == granularity.height);
405 	TCU_CHECK(granularity.width <= m_context.getDeviceProperties().limits.maxFramebufferWidth && granularity.height <= m_context.getDeviceProperties().limits.maxFramebufferHeight);
406 
407 	if(m_testMode == TestMode::USE_RENDER_PASS)
408 		endRenderPass(vk, *m_cmdBuffer);
409 
410 #ifndef CTS_USES_VULKANSC
411 	if (m_testMode == TestMode::USE_DYNAMIC_RENDER_PASS)
412 		endRendering(vk, *m_cmdBuffer);
413 #endif
414 
415 	endCommandBuffer(vk, *m_cmdBuffer);
416 
417 	log << tcu::TestLog::Message << "Horizontal granularity: " << granularity.width << " Vertical granularity: " << granularity.height << tcu::TestLog::EndMessage;
418 	return tcu::TestStatus::pass("Granularity test");
419 }
420 
421 class GranularityCase : public vkt::TestCase
422 {
423 public:
424 										GranularityCase		(tcu::TestContext&					testCtx,
425 															 const std::string&					name,
426 															 const std::vector<AttachmentInfo>&	attachments,
427 															 const TestMode						testMode);
428 	virtual								~GranularityCase	(void) = default;
429 
430 	void								checkSupport		(Context&	context) const;
431 	virtual TestInstance*				createInstance		(Context&	context) const;
432 private:
433 	const std::vector<AttachmentInfo>	m_attachments;
434 	const TestMode						m_testMode;
435 };
436 
GranularityCase(tcu::TestContext & testCtx,const std::string & name,const std::vector<AttachmentInfo> & attachments,const TestMode testMode=TestMode::NO_RENDER_PASS)437 GranularityCase::GranularityCase (tcu::TestContext&						testCtx,
438 								  const std::string&					name,
439 								  const std::vector<AttachmentInfo>&	attachments,
440 								  const TestMode						testMode = TestMode::NO_RENDER_PASS)
441 	: vkt::TestCase		(testCtx, name)
442 	, m_attachments		(attachments)
443 	, m_testMode		(testMode)
444 {
445 }
446 
checkSupport(Context & context) const447 void GranularityCase::checkSupport(Context& context) const
448 {
449 	const InstanceInterface&	vki					= context.getInstanceInterface();
450 	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
451 	const VkFormatFeatureFlags	requiredFeatures	= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
452 	VkFormatProperties			formatProperties;
453 
454 	for (const AttachmentInfo& attachmentInfo : m_attachments)
455 	{
456 		vki.getPhysicalDeviceFormatProperties(physicalDevice, attachmentInfo.format, &formatProperties);
457 		if ((formatProperties.optimalTilingFeatures & requiredFeatures) == 0)
458 			TCU_THROW(NotSupportedError, "Format not supported");
459 	}
460 
461 	if (m_testMode == TestMode::USE_DYNAMIC_RENDER_PASS)
462 		context.requireDeviceFunctionality("VK_KHR_maintenance5");
463 }
464 
createInstance(Context & context) const465 TestInstance* GranularityCase::createInstance (Context& context) const
466 {
467 	return new GranularityInstance(context, m_attachments, m_testMode);
468 }
469 
470 } // anonymous
471 
createGranularityQueryTests(tcu::TestContext & testCtx)472 tcu::TestCaseGroup* createGranularityQueryTests (tcu::TestContext& testCtx)
473 {
474 	de::MovePtr<tcu::TestCaseGroup>	group			(new tcu::TestCaseGroup(testCtx, "granularity"));
475 	// Subgroups
476 	// Single texture granularity tests.
477 	de::MovePtr<tcu::TestCaseGroup>	single				(new tcu::TestCaseGroup(testCtx, "single"));
478 	de::MovePtr<tcu::TestCaseGroup>	multi				(new tcu::TestCaseGroup(testCtx, "multi", "Multiple textures with same format granularity tests."));
479 	de::MovePtr<tcu::TestCaseGroup>	random				(new tcu::TestCaseGroup(testCtx, "random", "Multiple textures with a guaranteed format occurence."));
480 	de::MovePtr<tcu::TestCaseGroup>	inRenderPass		(new tcu::TestCaseGroup(testCtx, "in_render_pass", "Single texture granularity tests, inside render pass"));
481 	de::MovePtr<tcu::TestCaseGroup>	inDynamicRenderPass	(new tcu::TestCaseGroup(testCtx, "in_dynamic_render_pass", "Single texture granularity tests, inside dynamic render pass"));
482 
483 	de::Random	rnd(215);
484 
485 	const VkFormat mandatoryFormats[] =
486 	{
487 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
488 		VK_FORMAT_R5G6B5_UNORM_PACK16,
489 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
490 		VK_FORMAT_R8_UNORM,
491 		VK_FORMAT_R8_SNORM,
492 		VK_FORMAT_R8_UINT,
493 		VK_FORMAT_R8_SINT,
494 		VK_FORMAT_R8G8_UNORM,
495 		VK_FORMAT_R8G8_SNORM,
496 		VK_FORMAT_R8G8_UINT,
497 		VK_FORMAT_R8G8_SINT,
498 		VK_FORMAT_R8G8B8A8_UNORM,
499 		VK_FORMAT_R8G8B8A8_SNORM,
500 		VK_FORMAT_R8G8B8A8_UINT,
501 		VK_FORMAT_R8G8B8A8_SINT,
502 		VK_FORMAT_R8G8B8A8_SRGB,
503 		VK_FORMAT_B8G8R8A8_UNORM,
504 		VK_FORMAT_B8G8R8A8_SRGB,
505 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
506 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
507 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
508 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
509 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
510 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
511 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
512 		VK_FORMAT_R16_UINT,
513 		VK_FORMAT_R16_SINT,
514 		VK_FORMAT_R16_SFLOAT,
515 		VK_FORMAT_R16G16_UINT,
516 		VK_FORMAT_R16G16_SINT,
517 		VK_FORMAT_R16G16_SFLOAT,
518 		VK_FORMAT_R16G16B16A16_UINT,
519 		VK_FORMAT_R16G16B16A16_SINT,
520 		VK_FORMAT_R16G16B16A16_SFLOAT,
521 		VK_FORMAT_R32_UINT,
522 		VK_FORMAT_R32_SINT,
523 		VK_FORMAT_R32_SFLOAT,
524 		VK_FORMAT_R32G32_UINT,
525 		VK_FORMAT_R32G32_SINT,
526 		VK_FORMAT_R32G32_SFLOAT,
527 		VK_FORMAT_R32G32B32A32_UINT,
528 		VK_FORMAT_R32G32B32A32_SINT,
529 		VK_FORMAT_R32G32B32A32_SFLOAT,
530 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
531 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
532 		VK_FORMAT_D16_UNORM,
533 		VK_FORMAT_D32_SFLOAT,
534 	};
535 
536 	const deUint32	maxDimension	= 500;
537 	const deUint32	minIteration	= 2;
538 	const deUint32	maxIteration	= 10;
539 
540 	for (deUint32 formatIdx = 1; formatIdx <= VK_FORMAT_D32_SFLOAT_S8_UINT; ++formatIdx)
541 	{
542 		VkFormat	format		= VkFormat(formatIdx);
543 		std::string name		= de::toLower(getFormatName(format)).substr(10);
544 
545 		{
546 			std::vector<AttachmentInfo>	attachments;
547 			const int					i0				= rnd.getInt(1, maxDimension);
548 			const int					i1				= rnd.getInt(1, maxDimension);
549 			attachments.push_back(AttachmentInfo(format, i0, i1, 1));
550 			single->addChild(new GranularityCase(testCtx, name.c_str(), attachments));
551 		}
552 
553 		{
554 			std::vector<AttachmentInfo>	attachments;
555 			const deUint32				iterations		= rnd.getInt(minIteration, maxIteration);
556 			const int					i0				= rnd.getInt(1, maxDimension);
557 			const int					i1				= rnd.getInt(1, maxDimension);
558 			for (deUint32 idx = 0; idx < iterations; ++idx)
559 				attachments.push_back(AttachmentInfo(VkFormat(formatIdx), i0, i1, 1));
560 			multi->addChild(new GranularityCase(testCtx, name.c_str(), attachments));
561 		}
562 
563 		{
564 			std::vector<AttachmentInfo>	attachments;
565 			const deUint32				iterations		= rnd.getInt(minIteration, maxIteration);
566 			const int					i0				= rnd.getInt(1, maxDimension);
567 			const int					i1				= rnd.getInt(1, maxDimension);
568 			attachments.push_back(AttachmentInfo(VkFormat(formatIdx), i0, i1, 1));
569 			for (deUint32 idx = 0; idx < iterations; ++idx)
570 			{
571 				const int	i2	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(mandatoryFormats) - 1);
572 				const int	i3	= rnd.getInt(1, maxDimension);
573 				const int	i4	= rnd.getInt(1, maxDimension);
574 				attachments.push_back(AttachmentInfo(mandatoryFormats[i2], i3, i4, 1));
575 			}
576 			random->addChild(new GranularityCase(testCtx, name.c_str(), attachments));
577 		}
578 
579 		{
580 			const int					i0				= rnd.getInt(1, maxDimension);
581 			const int					i1				= rnd.getInt(1, maxDimension);
582 			std::vector<AttachmentInfo>	attachments		= { AttachmentInfo(format, i0, i1, 1) };
583 			inRenderPass->addChild(new GranularityCase(testCtx, name.c_str(), attachments, TestMode::USE_RENDER_PASS));
584 
585 #ifndef CTS_USES_VULKANSC
586 			inDynamicRenderPass->addChild(new GranularityCase(testCtx, name.c_str(), attachments, TestMode::USE_DYNAMIC_RENDER_PASS));
587 #endif
588 		}
589 	}
590 
591 	group->addChild(single.release());
592 	group->addChild(multi.release());
593 	group->addChild(random.release());
594 	group->addChild(inRenderPass.release());
595 
596 #ifndef CTS_USES_VULKANSC
597 	group->addChild(inDynamicRenderPass.release());
598 #endif
599 
600 	return group.release();
601 }
602 
603 } // api
604 } // vkt
605