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