• 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 "vktTestCase.hpp"
39 
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42 
43 #include <string>
44 
45 namespace vkt
46 {
47 
48 namespace api
49 {
50 
51 using namespace vk;
52 
53 namespace
54 {
55 
56 struct AttachmentInfo
57 {
AttachmentInfovkt::api::__anonfc51f3c80111::AttachmentInfo58 	AttachmentInfo (const VkFormat	vkFormat,
59 					const deUint32	width,
60 					const deUint32	height,
61 					const deUint32	depth)
62 		: format	(vkFormat)
63 	{
64 		extent.width	= width;
65 		extent.height	= height;
66 		extent.depth	= depth;
67 	}
68 
~AttachmentInfovkt::api::__anonfc51f3c80111::AttachmentInfo69 	~AttachmentInfo (void)
70 	{}
71 
72 	VkFormat	format;
73 	VkExtent3D	extent;
74 };
75 
76 typedef de::SharedPtr<Allocation>			AllocationSp;
77 typedef de::SharedPtr<Unique<VkImage> >		VkImageSp;
78 typedef de::SharedPtr<Unique<VkImageView> >	VkImageViewSp;
79 
80 class GranularityInstance : public vkt::TestInstance
81 {
82 public:
83 											GranularityInstance			(Context&							context,
84 																		 const std::vector<AttachmentInfo>&	attachments,
85 																		 const bool							useRenderPass);
86 	virtual									~GranularityInstance		(void);
87 	void									checkFormatSupport			(const VkFormat format);
88 	void									initAttachmentDescriptions	(void);
89 	void									initImages					(void);
90 	void									initRenderPass				(void);
91 	void									beginRenderPass				(void);
92 	void									endRenderPass				(void);
93 	virtual	tcu::TestStatus					iterate						(void);
94 private:
95 	const std::vector<AttachmentInfo>		m_attachments;
96 	const bool								m_useRenderPass;
97 
98 	Move<VkRenderPass>						m_renderPass;
99 	Move<VkFramebuffer>						m_frameBuffer;
100 	Move<VkCommandPool>						m_cmdPool;
101 	Move<VkCommandBuffer>					m_cmdBuffer;
102 	std::vector<VkAttachmentDescription>	m_attachmentDescriptions;
103 	std::vector<VkImageSp>					m_images;
104 	std::vector<AllocationSp>				m_imageAllocs;
105 	std::vector<VkImageViewSp>				m_imageViews;
106 };
107 
GranularityInstance(Context & context,const std::vector<AttachmentInfo> & attachments,const bool useRenderPass)108 GranularityInstance::GranularityInstance (Context&								context,
109 										  const std::vector<AttachmentInfo>&	attachments,
110 										  const bool							useRenderPass)
111 	: vkt::TestInstance	(context)
112 	, m_attachments		(attachments)
113 	, m_useRenderPass	(useRenderPass)
114 {
115 	initAttachmentDescriptions();
116 }
117 
~GranularityInstance(void)118 GranularityInstance::~GranularityInstance (void)
119 {
120 }
121 
checkFormatSupport(const VkFormat format)122 void GranularityInstance::checkFormatSupport (const VkFormat format)
123 {
124 	VkImageFormatProperties	properties;
125 
126 	VkResult result = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
127 																							  format, VK_IMAGE_TYPE_2D,
128 																							  VK_IMAGE_TILING_OPTIMAL,
129 																							  VK_IMAGE_USAGE_SAMPLED_BIT,
130 																							  0,
131 																							  &properties);
132 
133 	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
134 		TCU_THROW(NotSupportedError, "Format not supported");
135 }
136 
initAttachmentDescriptions(void)137 void GranularityInstance::initAttachmentDescriptions (void)
138 {
139 	VkAttachmentDescription	attachmentDescription	=
140 	{
141 		0u,									// VkAttachmentDescriptionFlags	flags;
142 		VK_FORMAT_UNDEFINED,				// VkFormat						format;
143 		VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits		samples;
144 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp			loadOp;
145 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp			storeOp;
146 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp			stencilLoadOp;
147 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp			stencilStoreOp;
148 		VK_IMAGE_LAYOUT_UNDEFINED,			// VkImageLayout				initialLayout;
149 		VK_IMAGE_LAYOUT_GENERAL,			// VkImageLayout				finalLayout;
150 	};
151 
152 	for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
153 	{
154 		checkFormatSupport(it->format);
155 		attachmentDescription.format = it->format;
156 		m_attachmentDescriptions.push_back(attachmentDescription);
157 	}
158 }
159 
initImages(void)160 void GranularityInstance::initImages (void)
161 {
162 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
163 	const VkDevice			device				= m_context.getDevice();
164 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
165 	SimpleAllocator			memAlloc			(vk, device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
166 
167 	for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
168 	{
169 		const VkImageCreateInfo		imageInfo	=
170 		{
171 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
172 			DE_NULL,								// const void*			pNext;
173 			0u,										// VkImageCreateFlags	flags;
174 			VK_IMAGE_TYPE_2D,						// VkImageType			imageType;
175 			it->format,								// VkFormat				format;
176 			it->extent,								// VkExtent3D			extent;
177 			1u,										// deUint32				mipLevels;
178 			1u,										// deUint32				arrayLayers;
179 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
180 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
181 			VK_IMAGE_USAGE_SAMPLED_BIT,				// VkImageUsageFlags	usage;
182 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
183 			1u,										// deUint32				queueFamilyCount;
184 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
185 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
186 		};
187 
188 		// Create the image
189 		Move<VkImage>			image		= createImage(vk, device, &imageInfo);
190 		de::MovePtr<Allocation>	imageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any);
191 		VK_CHECK(vk.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
192 
193 		VkImageAspectFlags			aspectFlags = 0;
194 		const tcu::TextureFormat	tcuFormat	= mapVkFormat(it->format);
195 
196 		if (tcu::hasDepthComponent(tcuFormat.order))
197 			aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
198 
199 		if (tcu::hasStencilComponent(tcuFormat.order))
200 			aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
201 
202 		if (!aspectFlags)
203 			aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
204 
205 		VkFormatProperties formatProperties;
206 		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(),
207 										   it->format, &formatProperties);
208 
209 		if ((formatProperties.optimalTilingFeatures & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
210 							       VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
211 			throw tcu::NotSupportedError("Format not supported as attachment");
212 
213 		const VkImageViewCreateInfo		createInfo	=
214 		{
215 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
216 			DE_NULL,										// const void*				pNext;
217 			0,												// VkImageViewCreateFlags	flags;
218 			*image,											// VkImage					image;
219 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
220 			it->format,										// VkFormat					format;
221 			{
222 				VK_COMPONENT_SWIZZLE_R,
223 				VK_COMPONENT_SWIZZLE_G,
224 				VK_COMPONENT_SWIZZLE_B,
225 				VK_COMPONENT_SWIZZLE_A
226 			},												// VkComponentMapping		components;
227 			{ aspectFlags, 0u, 1u, 0u, 1u	}	// VkImageSubresourceRange	subresourceRange;
228 		};
229 
230 		// Create the Image View
231 		Move<VkImageView>	imageView		= createImageView(vk, device, &createInfo);
232 
233 		// To prevent object free
234 		m_images.push_back(VkImageSp(new Unique<VkImage>(image)));
235 		m_imageAllocs.push_back(AllocationSp(imageAlloc.release()));
236 		m_imageViews.push_back(VkImageViewSp(new Unique<VkImageView>(imageView)));
237 	}
238 }
239 
initRenderPass(void)240 void GranularityInstance::initRenderPass (void)
241 {
242 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
243 	const VkDevice				device				= m_context.getDevice();
244 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
245 
246 	{	// Create RenderPass
247 		const VkSubpassDescription	subpassDesc =
248 		{
249 			(VkSubpassDescriptionFlags)0u,		// VkSubpassDescriptionFlags		flags;
250 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint;
251 			0u,									// deUint32							inputCount;
252 			DE_NULL,							// const VkAttachmentReference*		pInputAttachments;
253 			0u,									// deUint32							colorCount;
254 			DE_NULL,							// const VkAttachmentReference*		pColorAttachments;
255 			DE_NULL,							// const VkAttachmentReference*		pResolveAttachments;
256 			DE_NULL,							// VkAttachmentReference			depthStencilAttachment;
257 			0u,									// deUint32							preserveCount;
258 			DE_NULL								// const VkAttachmentReference*		pPreserveAttachments;
259 		};
260 
261 		const VkRenderPassCreateInfo	renderPassParams =
262 		{
263 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
264 			DE_NULL,									// const void*						pNext;
265 			(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags			flags;
266 			(deUint32)m_attachmentDescriptions.size(),	// deUint32							attachmentCount;
267 			&m_attachmentDescriptions[0],				// const VkAttachmentDescription*	pAttachments;
268 			1u,											// deUint32							subpassCount;
269 			&subpassDesc,								// const VkSubpassDescription*		pSubpasses;
270 			0u,											// deUint32							dependencyCount;
271 			DE_NULL										// const VkSubpassDependency*		pDependencies;
272 		};
273 
274 		m_renderPass	= createRenderPass(vk, device, &renderPassParams);
275 	}
276 
277 	initImages();
278 
279 	{	// Create Framebuffer
280 		std::vector<VkImageView>	imageViews;
281 
282 		for (std::vector<VkImageViewSp>::const_iterator it = m_imageViews.begin(); it != m_imageViews.end(); ++it)
283 			imageViews.push_back(it->get()->get());
284 
285 		const VkFramebufferCreateInfo	framebufferParams	=
286 		{
287 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
288 			DE_NULL,									// const void*				pNext;
289 			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags	flags;
290 			*m_renderPass,								// VkRenderPass				renderPass;
291 			(deUint32)imageViews.size(),				// deUint32					attachmentCount;
292 			&imageViews[0],								// const VkImageView*		pAttachments;
293 			1,											// deUint32					width;
294 			1,											// deUint32					height;
295 			1											// deUint32					layers;
296 		};
297 
298 		m_frameBuffer	= createFramebuffer(vk, device, &framebufferParams);
299 	}
300 
301 	m_cmdPool	= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
302 
303 	// Create CommandBuffer
304 	m_cmdBuffer	= allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
305 
306 	// Begin CommandBuffer
307 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
308 }
309 
beginRenderPass(void)310 void GranularityInstance::beginRenderPass (void)
311 {
312 	const DeviceInterface&	vk	= m_context.getDeviceInterface();
313 
314 	const VkRect2D	renderArea	= makeRect2D(1u, 1u);
315 
316 	vk::beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_frameBuffer, renderArea);
317 }
318 
endRenderPass(void)319 void GranularityInstance::endRenderPass (void)
320 {
321 	const DeviceInterface&	vk	= m_context.getDeviceInterface();
322 
323 	vk::endRenderPass(vk, *m_cmdBuffer);
324 	endCommandBuffer(vk, *m_cmdBuffer);
325 }
326 
iterate(void)327 tcu::TestStatus GranularityInstance::iterate (void)
328 {
329 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
330 	const VkDevice			device	= m_context.getDevice();
331 	tcu::TestLog&			log		= m_context.getTestContext().getLog();
332 
333 	initRenderPass();
334 
335 	VkExtent2D prePassGranularity = { ~0u, ~0u };
336 	vk.getRenderAreaGranularity(device, *m_renderPass, &prePassGranularity);
337 
338 	if(m_useRenderPass)
339 		beginRenderPass();
340 
341 	VkExtent2D	granularity = { 0u, 0u };
342 	vk.getRenderAreaGranularity(device, *m_renderPass, &granularity);
343 	TCU_CHECK(granularity.width >= 1 && granularity.height >= 1);
344 	TCU_CHECK(prePassGranularity.width == granularity.width && prePassGranularity.height == granularity.height);
345 	TCU_CHECK(granularity.width <= m_context.getDeviceProperties().limits.maxFramebufferWidth && granularity.height <= m_context.getDeviceProperties().limits.maxFramebufferHeight);
346 
347 	if(m_useRenderPass)
348 		endRenderPass();
349 
350 	log << tcu::TestLog::Message << "Horizontal granularity: " << granularity.width << " Vertical granularity: " << granularity.height << tcu::TestLog::EndMessage;
351 	return tcu::TestStatus::pass("Granularity test");
352 }
353 
354 class GranularityCase : public vkt::TestCase
355 {
356 public:
357 										GranularityCase		(tcu::TestContext&					testCtx,
358 															 const std::string&					name,
359 															 const std::string&					description,
360 															 const std::vector<AttachmentInfo>&	attachments,
361 															 const bool							useRenderPass);
362 	virtual								~GranularityCase	(void);
363 
364 	virtual TestInstance*				createInstance		(Context&	context) const;
365 private:
366 	const std::vector<AttachmentInfo>	m_attachments;
367 	const bool							m_useRenderPass;
368 };
369 
GranularityCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const std::vector<AttachmentInfo> & attachments,const bool useRenderPass=false)370 GranularityCase::GranularityCase (tcu::TestContext&						testCtx,
371 								  const std::string&					name,
372 								  const std::string&					description,
373 								  const std::vector<AttachmentInfo>&	attachments,
374 								  const bool							useRenderPass = false)
375 	: vkt::TestCase		(testCtx, name, description)
376 	, m_attachments		(attachments)
377 	, m_useRenderPass	(useRenderPass)
378 {
379 }
380 
~GranularityCase(void)381 GranularityCase::~GranularityCase (void)
382 {
383 }
384 
createInstance(Context & context) const385 TestInstance* GranularityCase::createInstance (Context& context) const
386 {
387 	return new GranularityInstance(context, m_attachments, m_useRenderPass);
388 }
389 
390 } // anonymous
391 
createGranularityQueryTests(tcu::TestContext & testCtx)392 tcu::TestCaseGroup* createGranularityQueryTests (tcu::TestContext& testCtx)
393 {
394 	de::MovePtr<tcu::TestCaseGroup>	group			(new tcu::TestCaseGroup(testCtx, "granularity", "Granularity query tests"));
395 	// Subgroups
396 	de::MovePtr<tcu::TestCaseGroup>	single			(new tcu::TestCaseGroup(testCtx, "single", "Single texture granularity tests."));
397 	de::MovePtr<tcu::TestCaseGroup>	multi			(new tcu::TestCaseGroup(testCtx, "multi", "Multiple textures with same format granularity tests."));
398 	de::MovePtr<tcu::TestCaseGroup>	random			(new tcu::TestCaseGroup(testCtx, "random", "Multiple textures with a guaranteed format occurence."));
399 	de::MovePtr<tcu::TestCaseGroup>	inRenderPass	(new tcu::TestCaseGroup(testCtx, "in_render_pass", "Single texture granularity tests, inside render pass"));
400 
401 	de::Random	rnd(215);
402 	const char*	description	= "Granularity case.";
403 
404 	const VkFormat mandatoryFormats[] =
405 	{
406 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
407 		VK_FORMAT_R5G6B5_UNORM_PACK16,
408 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
409 		VK_FORMAT_R8_UNORM,
410 		VK_FORMAT_R8_SNORM,
411 		VK_FORMAT_R8_UINT,
412 		VK_FORMAT_R8_SINT,
413 		VK_FORMAT_R8G8_UNORM,
414 		VK_FORMAT_R8G8_SNORM,
415 		VK_FORMAT_R8G8_UINT,
416 		VK_FORMAT_R8G8_SINT,
417 		VK_FORMAT_R8G8B8A8_UNORM,
418 		VK_FORMAT_R8G8B8A8_SNORM,
419 		VK_FORMAT_R8G8B8A8_UINT,
420 		VK_FORMAT_R8G8B8A8_SINT,
421 		VK_FORMAT_R8G8B8A8_SRGB,
422 		VK_FORMAT_B8G8R8A8_UNORM,
423 		VK_FORMAT_B8G8R8A8_SRGB,
424 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
425 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
426 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
427 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
428 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
429 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
430 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
431 		VK_FORMAT_R16_UINT,
432 		VK_FORMAT_R16_SINT,
433 		VK_FORMAT_R16_SFLOAT,
434 		VK_FORMAT_R16G16_UINT,
435 		VK_FORMAT_R16G16_SINT,
436 		VK_FORMAT_R16G16_SFLOAT,
437 		VK_FORMAT_R16G16B16A16_UINT,
438 		VK_FORMAT_R16G16B16A16_SINT,
439 		VK_FORMAT_R16G16B16A16_SFLOAT,
440 		VK_FORMAT_R32_UINT,
441 		VK_FORMAT_R32_SINT,
442 		VK_FORMAT_R32_SFLOAT,
443 		VK_FORMAT_R32G32_UINT,
444 		VK_FORMAT_R32G32_SINT,
445 		VK_FORMAT_R32G32_SFLOAT,
446 		VK_FORMAT_R32G32B32A32_UINT,
447 		VK_FORMAT_R32G32B32A32_SINT,
448 		VK_FORMAT_R32G32B32A32_SFLOAT,
449 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
450 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
451 		VK_FORMAT_D16_UNORM,
452 		VK_FORMAT_D32_SFLOAT,
453 	};
454 
455 	const deUint32	maxDimension	= 500;
456 	const deUint32	minIteration	= 2;
457 	const deUint32	maxIteration	= 10;
458 
459 	for (deUint32 formatIdx = 1; formatIdx <= VK_FORMAT_D32_SFLOAT_S8_UINT; ++formatIdx)
460 	{
461 		VkFormat	format		= VkFormat(formatIdx);
462 		std::string name		= de::toLower(getFormatName(format)).substr(10);
463 
464 		{
465 			std::vector<AttachmentInfo>	attachments;
466 			const int					i0				= rnd.getInt(1, maxDimension);
467 			const int					i1				= rnd.getInt(1, maxDimension);
468 			attachments.push_back(AttachmentInfo(format, i0, i1, 1));
469 			single->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
470 		}
471 
472 		{
473 			std::vector<AttachmentInfo>	attachments;
474 			const deUint32				iterations		= rnd.getInt(minIteration, maxIteration);
475 			const int					i0				= rnd.getInt(1, maxDimension);
476 			const int					i1				= rnd.getInt(1, maxDimension);
477 			for (deUint32 idx = 0; idx < iterations; ++idx)
478 				attachments.push_back(AttachmentInfo(VkFormat(formatIdx), i0, i1, 1));
479 			multi->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
480 		}
481 
482 		{
483 			std::vector<AttachmentInfo>	attachments;
484 			const deUint32				iterations		= rnd.getInt(minIteration, maxIteration);
485 			const int					i0				= rnd.getInt(1, maxDimension);
486 			const int					i1				= rnd.getInt(1, maxDimension);
487 			attachments.push_back(AttachmentInfo(VkFormat(formatIdx), i0, i1, 1));
488 			for (deUint32 idx = 0; idx < iterations; ++idx)
489 			{
490 				const int	i2	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(mandatoryFormats) - 1);
491 				const int	i3	= rnd.getInt(1, maxDimension);
492 				const int	i4	= rnd.getInt(1, maxDimension);
493 				attachments.push_back(AttachmentInfo(mandatoryFormats[i2], i3, i4, 1));
494 			}
495 			random->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
496 		}
497 
498 		{
499 			std::vector<AttachmentInfo>	attachments;
500 			const int					i0				= rnd.getInt(1, maxDimension);
501 			const int					i1				= rnd.getInt(1, maxDimension);
502 			attachments.push_back(AttachmentInfo(format, i0, i1, 1));
503 			inRenderPass->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments, true));
504 		}
505 	}
506 
507 	group->addChild(single.release());
508 	group->addChild(multi.release());
509 	group->addChild(random.release());
510 	group->addChild(inRenderPass.release());
511 
512 	return group.release();
513 }
514 
515 } // api
516 } // vkt
517