1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group 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 fragment density map extension ( VK_EXT_fragment_density_map )
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRenderPassFragmentDensityMapTests.hpp"
25 #include "pipeline/vktPipelineImageUtil.hpp"
26 #include "deMath.h"
27 #include "vktTestCase.hpp"
28 #include "vktTestGroupUtil.hpp"
29 #include "vktCustomInstancesDevices.hpp"
30 #include "vktRenderPassTestsUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "tcuCommandLine.hpp"
39 #include "tcuStringTemplate.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuTestLog.hpp"
42 #include <sstream>
43 #include <vector>
44 #include <set>
45 
46 // Each test generates an image with a color gradient where all colors should be unique when rendered without density map
47 // ( and for multi_view tests - the quantity of each color in a histogram should be 2 instead of 1 ).
48 // The whole density map has the same values defined by input fragment area ( one of the test input parameters ).
49 // With density map enabled - the number of each color in a histogram should be [ fragmentArea.x * fragmentArea.y ]
50 // ( that value will be doubled for multi_view case ).
51 //
52 // Additionally test checks if gl_FragSizeEXT shader variable has proper value ( as defined by fragmentArea input parameter ).
53 //
54 // Test variations:
55 // - multi_view tests check if density map also works when VK_KHR_multiview extension is in use
56 // - render_copy tests check if it's possible to copy results using input attachment descriptor ( this simulates deferred rendering behaviour )
57 // - non_divisible_density_size tests check if subsampled images work when its dimension is not divisible by minFragmentDensityTexelSize
58 // - N_samples tests check if multisampling works with VK_EXT_fragment_density_map extension
59 // - static_* tests use density map loaded from CPU during vkCmdBeginRenderPass.
60 // - dynamic_* tests use density map rendered on a GPU in a separate render pass
61 // - deffered_* tests use density map loaded from CPU during VkEndCommandBuffer.
62 // - *_nonsubsampled tests check if it's possible to use nonsubsampled images instead of subsampled ones
63 
64 // There are 3 render passes performed during most of the tests:
65 //  - render pass that produces density map ( this rp is skipped when density map is static )
66 //  - render pass that produces subsampled image using density map and eventually copies results to different image ( render_copy )
67 //  - render pass that copies subsampled image to traditional image using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT flag.
68 //    ( because subsampled images cannot be retrieved to CPU in any other way ).
69 // There are few tests that use additional subpass that resamples subsampled image using diferent density map.
70 
71 // Code of FragmentDensityMapTestInstance is also used to test subsampledLoads, subsampledCoarseReconstructionEarlyAccess,
72 // maxDescriptorSetSubsampledSamplers properties.
73 
74 namespace vkt
75 {
76 
77 namespace renderpass
78 {
79 
80 using namespace vk;
81 
82 namespace
83 {
84 
85 struct TestParams
86 {
87     bool dynamicDensityMap;
88     bool deferredDensityMap;
89     bool nonSubsampledImages;
90     bool subsampledLoads;
91     bool coarseReconstruction;
92     bool imagelessFramebuffer;
93     bool useMemoryAccess;
94     bool useMaintenance5;
95     uint32_t samplersCount;
96     uint32_t viewCount;
97     bool multiViewport;
98     bool makeCopy;
99     float renderMultiplier;
100     VkSampleCountFlagBits colorSamples;
101     tcu::UVec2 fragmentArea;
102     tcu::UVec2 densityMapSize;
103     VkFormat densityMapFormat;
104     const SharedGroupParams groupParams;
105 };
106 
107 struct Vertex4RGBA
108 {
109     tcu::Vec4 position;
110     tcu::Vec4 uv;
111     tcu::Vec4 color;
112 };
113 
114 de::SharedPtr<Move<vk::VkDevice>> g_singletonDevice;
115 
getDevice(Context & context)116 VkDevice getDevice(Context &context)
117 {
118     if (!g_singletonDevice)
119     {
120         const float queuePriority = 1.0f;
121 
122         // Create a universal queue that supports graphics and compute
123         const VkDeviceQueueCreateInfo queueParams{
124             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
125             DE_NULL,                                    // const void* pNext;
126             0u,                                         // VkDeviceQueueCreateFlags flags;
127             context.getUniversalQueueFamilyIndex(),     // uint32_t queueFamilyIndex;
128             1u,                                         // uint32_t queueCount;
129             &queuePriority                              // const float* pQueuePriorities;
130         };
131 
132         // \note Extensions in core are not explicitly enabled even though
133         //         they are in the extension list advertised to tests.
134         const auto &extensionPtrs = context.getDeviceCreationExtensions();
135 
136         VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilitySubsetFeatures                 = initVulkanStructure();
137         VkPhysicalDeviceMultiviewFeatures multiviewFeatures                                    = initVulkanStructure();
138         VkPhysicalDeviceImagelessFramebufferFeatures imagelessFramebufferFeatures              = initVulkanStructure();
139         VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures                      = initVulkanStructure();
140         VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR dynamicRenderingLocalReadFeatures = initVulkanStructure();
141         VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features             = initVulkanStructure();
142         VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures               = initVulkanStructure();
143         VkPhysicalDeviceFeatures2 features2                                                    = initVulkanStructure();
144 
145         const auto addFeatures = makeStructChainAdder(&features2);
146 
147         if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
148             addFeatures(&portabilitySubsetFeatures);
149 
150         if (context.isDeviceFunctionalitySupported("VK_KHR_multiview"))
151             addFeatures(&multiviewFeatures);
152 
153         if (context.isDeviceFunctionalitySupported("VK_KHR_imageless_framebuffer"))
154             addFeatures(&imagelessFramebufferFeatures);
155 
156         if (context.isDeviceFunctionalitySupported("VK_KHR_dynamic_rendering"))
157             addFeatures(&dynamicRenderingFeatures);
158 
159         if (context.isDeviceFunctionalitySupported("VK_KHR_dynamic_rendering_local_read"))
160             addFeatures(&dynamicRenderingLocalReadFeatures);
161 
162         if (context.isDeviceFunctionalitySupported("VK_EXT_fragment_density_map2"))
163             addFeatures(&fragmentDensityMap2Features);
164 
165         addFeatures(&fragmentDensityMapFeatures);
166 
167         context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
168         features2.features.robustBufferAccess = VK_FALSE;
169 
170         const VkDeviceCreateInfo deviceCreateInfo{
171             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
172             &features2,                           //pNext;
173             0u,                                   //flags
174             1,                                    //queueRecordCount;
175             &queueParams,                         //pRequestedQueues;
176             0u,                                   //layerCount;
177             nullptr,                              //ppEnabledLayerNames;
178             de::sizeU32(extensionPtrs),           // uint32_t enabledExtensionCount;
179             de::dataOrNull(extensionPtrs),        // const char* const* ppEnabledExtensionNames;
180             nullptr,                              //pEnabledFeatures;
181         };
182 
183         Move<VkDevice> device = createCustomDevice(
184             context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
185             context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceCreateInfo);
186         g_singletonDevice = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
187     }
188 
189     return g_singletonDevice->get();
190 }
191 
createFullscreenMesh(uint32_t viewCount,tcu::Vec2 redGradient,tcu::Vec2 greenGradient)192 std::vector<Vertex4RGBA> createFullscreenMesh(uint32_t viewCount, tcu::Vec2 redGradient, tcu::Vec2 greenGradient)
193 {
194     DE_ASSERT(viewCount > 0);
195 
196     const auto &r    = redGradient;
197     const auto &g    = greenGradient;
198     const float step = 2.0f / static_cast<float>(viewCount);
199     float xStart     = -1.0f;
200 
201     std::vector<Vertex4RGBA> resultMesh;
202     for (uint32_t viewIndex = 0; viewIndex < viewCount; ++viewIndex)
203     {
204         const float fIndex       = static_cast<float>(viewIndex);
205         const uint32_t nextIndex = viewIndex + 1;
206         const float xEnd         = (nextIndex == viewCount) ? 1.0f : (-1.0f + step * static_cast<float>(nextIndex));
207 
208         // quad vertex                            position                        uv                                color
209         const Vertex4RGBA lowerLeftVertex = {
210             {xStart, 1.0f, 0.0f, 1.0f}, {0.0f, 1.0f, fIndex, 1.0f}, {r.x(), g.y(), 0.0f, 1.0f}};
211         const Vertex4RGBA upperLeftVertex = {
212             {xStart, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, fIndex, 1.0f}, {r.x(), g.x(), 0.0f, 1.0f}};
213         const Vertex4RGBA lowerRightVertex = {
214             {xEnd, 1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, fIndex, 1.0f}, {r.y(), g.y(), 0.0f, 1.0f}};
215         const Vertex4RGBA upperRightVertex = {
216             {xEnd, -1.0f, 0.0f, 1.0f}, {1.0f, 0.0f, fIndex, 1.0f}, {r.y(), g.x(), 0.0f, 1.0f}};
217 
218         const std::vector<Vertex4RGBA> viewData{lowerLeftVertex, lowerRightVertex, upperLeftVertex,
219                                                 upperLeftVertex, lowerRightVertex, upperRightVertex};
220 
221         resultMesh.insert(resultMesh.end(), viewData.begin(), viewData.end());
222         xStart = xEnd;
223     }
224 
225     return resultMesh;
226 }
227 
228 template <typename T>
createVertexBuffer(const DeviceInterface & vk,VkDevice vkDevice,const uint32_t & queueFamilyIndex,SimpleAllocator & memAlloc,const std::vector<T> & vertices,Move<VkBuffer> & vertexBuffer,de::MovePtr<Allocation> & vertexAlloc)229 void createVertexBuffer(const DeviceInterface &vk, VkDevice vkDevice, const uint32_t &queueFamilyIndex,
230                         SimpleAllocator &memAlloc, const std::vector<T> &vertices, Move<VkBuffer> &vertexBuffer,
231                         de::MovePtr<Allocation> &vertexAlloc)
232 {
233     const VkBufferCreateInfo vertexBufferParams = {
234         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,        // VkStructureType sType;
235         DE_NULL,                                     // const void* pNext;
236         0u,                                          // VkBufferCreateFlags flags;
237         (VkDeviceSize)(sizeof(T) * vertices.size()), // VkDeviceSize size;
238         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,           // VkBufferUsageFlags usage;
239         VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode sharingMode;
240         1u,                                          // uint32_t queueFamilyIndexCount;
241         &queueFamilyIndex                            // const uint32_t* pQueueFamilyIndices;
242     };
243 
244     vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
245     vertexAlloc =
246         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
247     VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
248 
249     // Upload vertex data
250     deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(T));
251     flushAlloc(vk, vkDevice, *vertexAlloc);
252 }
253 
prepareImageAndImageView(const DeviceInterface & vk,VkDevice vkDevice,SimpleAllocator & memAlloc,VkImageCreateFlags imageCreateFlags,VkFormat format,VkExtent3D extent,uint32_t arrayLayers,VkSampleCountFlagBits samples,VkImageUsageFlags usage,uint32_t queueFamilyIndex,VkImageViewCreateFlags viewFlags,VkImageViewType viewType,const VkComponentMapping & channels,const VkImageSubresourceRange & subresourceRange,Move<VkImage> & image,de::MovePtr<Allocation> & imageAlloc,Move<VkImageView> & imageView)254 void prepareImageAndImageView(const DeviceInterface &vk, VkDevice vkDevice, SimpleAllocator &memAlloc,
255                               VkImageCreateFlags imageCreateFlags, VkFormat format, VkExtent3D extent,
256                               uint32_t arrayLayers, VkSampleCountFlagBits samples, VkImageUsageFlags usage,
257                               uint32_t queueFamilyIndex, VkImageViewCreateFlags viewFlags, VkImageViewType viewType,
258                               const VkComponentMapping &channels, const VkImageSubresourceRange &subresourceRange,
259                               Move<VkImage> &image, de::MovePtr<Allocation> &imageAlloc, Move<VkImageView> &imageView)
260 {
261     const VkImageCreateInfo imageCreateInfo{
262         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
263         DE_NULL,                             // const void* pNext;
264         imageCreateFlags,                    // VkImageCreateFlags flags;
265         VK_IMAGE_TYPE_2D,                    // VkImageType imageType;
266         format,                              // VkFormat format;
267         extent,                              // VkExtent3D extent;
268         1u,                                  // uint32_t mipLevels;
269         arrayLayers,                         // uint32_t arrayLayers;
270         samples,                             // VkSampleCountFlagBits samples;
271         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
272         usage,                               // VkImageUsageFlags usage;
273         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
274         1u,                                  // uint32_t queueFamilyIndexCount;
275         &queueFamilyIndex,                   // const uint32_t* pQueueFamilyIndices;
276         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
277     };
278 
279     image = createImage(vk, vkDevice, &imageCreateInfo);
280 
281     // Allocate and bind color image memory
282     imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
283     VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
284 
285     // create image view for subsampled image
286     const VkImageViewCreateInfo imageViewCreateInfo = {
287         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
288         DE_NULL,                                  // const void* pNext;
289         viewFlags,                                // VkImageViewCreateFlags flags;
290         *image,                                   // VkImage image;
291         viewType,                                 // VkImageViewType viewType;
292         format,                                   // VkFormat format;
293         channels,                                 // VkChannelMapping channels;
294         subresourceRange                          // VkImageSubresourceRange subresourceRange;
295     };
296 
297     imageView = createImageView(vk, vkDevice, &imageViewCreateInfo);
298 }
299 
300 // Class that provides abstraction over renderpass and renderpass2.
301 class RenderPassWrapperBase
302 {
303 public:
304     RenderPassWrapperBase()          = default;
305     virtual ~RenderPassWrapperBase() = default;
306 
307     virtual Move<VkRenderPass> createRenderPassProduceDynamicDensityMap(uint32_t viewMask) const     = 0;
308     virtual Move<VkRenderPass> createRenderPassProduceSubsampledImage(uint32_t viewMask, bool makeCopySubpass,
309                                                                       bool resampleSubsampled) const = 0;
310     virtual Move<VkRenderPass> createRenderPassOutputSubsampledImage() const                         = 0;
311 
312     virtual void cmdBeginRenderPass(VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo *pRenderPassBegin) const = 0;
313     virtual void cmdNextSubpass(VkCommandBuffer cmdBuffer) const                                                    = 0;
314     virtual void cmdEndRenderPass(VkCommandBuffer cmdBuffer) const                                                  = 0;
315 };
316 
317 // Helper template that lets us define all used types basing on single enum value.
318 template <RenderingType>
319 struct RenderPassTraits;
320 
321 template <>
322 struct RenderPassTraits<RENDERING_TYPE_RENDERPASS_LEGACY>
323 {
324     typedef AttachmentDescription1 AttachmentDesc;
325     typedef AttachmentReference1 AttachmentRef;
326     typedef SubpassDescription1 SubpassDesc;
327     typedef SubpassDependency1 SubpassDep;
328     typedef RenderPassCreateInfo1 RenderPassCreateInfo;
329     typedef RenderpassSubpass1 RenderpassSubpass;
330 };
331 
332 template <>
333 struct RenderPassTraits<RENDERING_TYPE_RENDERPASS2>
334 {
335     typedef AttachmentDescription2 AttachmentDesc;
336     typedef AttachmentReference2 AttachmentRef;
337     typedef SubpassDescription2 SubpassDesc;
338     typedef SubpassDependency2 SubpassDep;
339     typedef RenderPassCreateInfo2 RenderPassCreateInfo;
340     typedef RenderpassSubpass2 RenderpassSubpass;
341 };
342 
343 // Template that can be used to construct required
344 // renderpasses using legacy renderpass and renderpass2.
345 template <RenderingType RenderingTypeValue>
346 class RenderPassWrapper : public RenderPassWrapperBase
347 {
348     typedef typename RenderPassTraits<RenderingTypeValue>::AttachmentDesc AttachmentDesc;
349     typedef typename RenderPassTraits<RenderingTypeValue>::AttachmentRef AttachmentRef;
350     typedef typename RenderPassTraits<RenderingTypeValue>::SubpassDesc SubpassDesc;
351     typedef typename RenderPassTraits<RenderingTypeValue>::SubpassDep SubpassDep;
352     typedef typename RenderPassTraits<RenderingTypeValue>::RenderPassCreateInfo RenderPassCreateInfo;
353     typedef typename RenderPassTraits<RenderingTypeValue>::RenderpassSubpass RenderpassSubpass;
354 
355 public:
356     RenderPassWrapper(const DeviceInterface &vk, const VkDevice vkDevice, const TestParams &testParams);
357     ~RenderPassWrapper() = default;
358 
359     Move<VkRenderPass> createRenderPassProduceDynamicDensityMap(uint32_t viewMask) const override;
360     Move<VkRenderPass> createRenderPassProduceSubsampledImage(uint32_t viewMask, bool makeCopySubpass,
361                                                               bool resampleSubsampled) const override;
362     Move<VkRenderPass> createRenderPassOutputSubsampledImage() const override;
363 
364     void cmdBeginRenderPass(VkCommandBuffer cmdBufferm, const VkRenderPassBeginInfo *pRenderPassBegin) const override;
365     void cmdNextSubpass(VkCommandBuffer cmdBuffer) const override;
366     void cmdEndRenderPass(VkCommandBuffer cmdBuffer) const override;
367 
368 private:
369     const DeviceInterface &m_vk;
370     const VkDevice m_vkDevice;
371     const TestParams &m_testParams;
372 
373     const typename RenderpassSubpass::SubpassBeginInfo m_subpassBeginInfo;
374     const typename RenderpassSubpass::SubpassEndInfo m_subpassEndInfo;
375 };
376 
377 template <RenderingType RenderingTypeValue>
RenderPassWrapper(const DeviceInterface & vk,const VkDevice vkDevice,const TestParams & testParams)378 RenderPassWrapper<RenderingTypeValue>::RenderPassWrapper(const DeviceInterface &vk, const VkDevice vkDevice,
379                                                          const TestParams &testParams)
380     : RenderPassWrapperBase()
381     , m_vk(vk)
382     , m_vkDevice(vkDevice)
383     , m_testParams(testParams)
384     , m_subpassBeginInfo(DE_NULL, testParams.groupParams->useSecondaryCmdBuffer ?
385                                       VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS :
386                                       VK_SUBPASS_CONTENTS_INLINE)
387     , m_subpassEndInfo(DE_NULL)
388 {
389 }
390 
391 template <RenderingType RenderingTypeValue>
createRenderPassProduceDynamicDensityMap(uint32_t viewMask) const392 Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassProduceDynamicDensityMap(
393     uint32_t viewMask) const
394 {
395     DE_ASSERT(m_testParams.dynamicDensityMap);
396 
397     std::vector<AttachmentDesc> attachmentDescriptions{{
398         DE_NULL,                                         // const void*                        pNext
399         (VkAttachmentDescriptionFlags)0,                 // VkAttachmentDescriptionFlags        flags
400         m_testParams.densityMapFormat,                   // VkFormat                            format
401         VK_SAMPLE_COUNT_1_BIT,                           // VkSampleCountFlagBits            samples
402         VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp                loadOp
403         VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp                storeOp
404         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                 // VkAttachmentLoadOp                stencilLoadOp
405         VK_ATTACHMENT_STORE_OP_DONT_CARE,                // VkAttachmentStoreOp                stencilStoreOp
406         VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout                    initialLayout
407         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT // VkImageLayout                    finalLayout
408     }};
409 
410     std::vector<AttachmentRef> colorAttachmentRefs{
411         {DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT}};
412 
413     std::vector<SubpassDesc> subpassDescriptions{{
414         DE_NULL,
415         (VkSubpassDescriptionFlags)0,                      // VkSubpassDescriptionFlags        flags
416         VK_PIPELINE_BIND_POINT_GRAPHICS,                   // VkPipelineBindPoint                pipelineBindPoint
417         viewMask,                                          // uint32_t                            viewMask
418         0u,                                                // uint32_t                            inputAttachmentCount
419         DE_NULL,                                           // const VkAttachmentReference*        pInputAttachments
420         static_cast<uint32_t>(colorAttachmentRefs.size()), // uint32_t                            colorAttachmentCount
421         colorAttachmentRefs.data(),                        // const VkAttachmentReference*        pColorAttachments
422         DE_NULL,                                           // const VkAttachmentReference*        pResolveAttachments
423         DE_NULL, // const VkAttachmentReference*        pDepthStencilAttachment
424         0u,      // uint32_t                            preserveAttachmentCount
425         DE_NULL  // const uint32_t*                    pPreserveAttachments
426     }};
427 
428     std::vector<SubpassDep> subpassDependencies{{
429         DE_NULL,                                            // const void*                pNext
430         0u,                                                 // uint32_t                    srcSubpass
431         VK_SUBPASS_EXTERNAL,                                // uint32_t                    dstSubpass
432         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,      // VkPipelineStageFlags        srcStageMask
433         VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT, // VkPipelineStageFlags        dstStageMask
434         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,               // VkAccessFlags            srcAccessMask
435         VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,        // VkAccessFlags            dstAccessMask
436         VK_DEPENDENCY_BY_REGION_BIT,                        // VkDependencyFlags        dependencyFlags
437         0u                                                  // int32_t                    viewOffset
438     }};
439 
440     const RenderPassCreateInfo renderPassInfo(
441         DE_NULL,                                              // const void*                        pNext
442         (VkRenderPassCreateFlags)0,                           // VkRenderPassCreateFlags            flags
443         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t                            attachmentCount
444         attachmentDescriptions.data(),                        // const VkAttachmentDescription*    pAttachments
445         static_cast<uint32_t>(subpassDescriptions.size()),    // uint32_t                            subpassCount
446         subpassDescriptions.data(),                           // const VkSubpassDescription*        pSubpasses
447         static_cast<uint32_t>(subpassDependencies.size()),    // uint32_t                            dependencyCount
448         subpassDependencies.empty() ? DE_NULL :
449                                       subpassDependencies.data(), // const VkSubpassDependency*        pDependencies
450         0u,     // uint32_t                            correlatedViewMaskCount
451         DE_NULL // const uint32_t*                    pCorrelatedViewMasks
452     );
453 
454     return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
455 }
456 
457 template <RenderingType RenderingTypeValue>
createRenderPassProduceSubsampledImage(uint32_t viewMask,bool makeCopySubpass,bool resampleSubsampled) const458 Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassProduceSubsampledImage(
459     uint32_t viewMask, bool makeCopySubpass, bool resampleSubsampled) const
460 {
461     const void *constNullPtr            = DE_NULL;
462     uint32_t multisampleAttachmentIndex = 0;
463     uint32_t copyAttachmentIndex        = 0;
464     uint32_t densityMapAttachmentIndex  = 0;
465 
466     // add color image
467     VkAttachmentLoadOp loadOp = resampleSubsampled ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
468     std::vector<AttachmentDesc> attachmentDescriptions{
469         // Output color attachment
470         {
471             DE_NULL,                                 // const void*                        pNext
472             (VkAttachmentDescriptionFlags)0,         // VkAttachmentDescriptionFlags        flags
473             VK_FORMAT_R8G8B8A8_UNORM,                // VkFormat                            format
474             m_testParams.colorSamples,               // VkSampleCountFlagBits            samples
475             loadOp,                                  // VkAttachmentLoadOp                loadOp
476             VK_ATTACHMENT_STORE_OP_STORE,            // VkAttachmentStoreOp                storeOp
477             VK_ATTACHMENT_LOAD_OP_DONT_CARE,         // VkAttachmentLoadOp                stencilLoadOp
478             VK_ATTACHMENT_STORE_OP_DONT_CARE,        // VkAttachmentStoreOp                stencilStoreOp
479             VK_IMAGE_LAYOUT_UNDEFINED,               // VkImageLayout                    initialLayout
480             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout                    finalLayout
481         }};
482 
483     // add resolve image when we use more than one sample per fragment
484     if (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT)
485     {
486         multisampleAttachmentIndex = static_cast<uint32_t>(attachmentDescriptions.size());
487         attachmentDescriptions.emplace_back(
488             constNullPtr,                            // const void*                        pNext
489             (VkAttachmentDescriptionFlags)0,         // VkAttachmentDescriptionFlags        flags
490             VK_FORMAT_R8G8B8A8_UNORM,                // VkFormat                            format
491             VK_SAMPLE_COUNT_1_BIT,                   // VkSampleCountFlagBits            samples
492             VK_ATTACHMENT_LOAD_OP_CLEAR,             // VkAttachmentLoadOp                loadOp
493             VK_ATTACHMENT_STORE_OP_STORE,            // VkAttachmentStoreOp                storeOp
494             VK_ATTACHMENT_LOAD_OP_DONT_CARE,         // VkAttachmentLoadOp                stencilLoadOp
495             VK_ATTACHMENT_STORE_OP_DONT_CARE,        // VkAttachmentStoreOp                stencilStoreOp
496             VK_IMAGE_LAYOUT_UNDEFINED,               // VkImageLayout                    initialLayout
497             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout                    finalLayout
498         );
499     }
500 
501     // add color image copy ( when render_copy is used )
502     if (makeCopySubpass)
503     {
504         copyAttachmentIndex = static_cast<uint32_t>(attachmentDescriptions.size());
505         attachmentDescriptions.emplace_back(
506             constNullPtr,                            // const void*                        pNext
507             (VkAttachmentDescriptionFlags)0,         // VkAttachmentDescriptionFlags        flags
508             VK_FORMAT_R8G8B8A8_UNORM,                // VkFormat                            format
509             m_testParams.colorSamples,               // VkSampleCountFlagBits            samples
510             VK_ATTACHMENT_LOAD_OP_CLEAR,             // VkAttachmentLoadOp                loadOp
511             VK_ATTACHMENT_STORE_OP_STORE,            // VkAttachmentStoreOp                storeOp
512             VK_ATTACHMENT_LOAD_OP_DONT_CARE,         // VkAttachmentLoadOp                stencilLoadOp
513             VK_ATTACHMENT_STORE_OP_DONT_CARE,        // VkAttachmentStoreOp                stencilStoreOp
514             VK_IMAGE_LAYOUT_UNDEFINED,               // VkImageLayout                    initialLayout
515             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout                    finalLayout
516         );
517     }
518 
519     // add density map
520     densityMapAttachmentIndex = static_cast<uint32_t>(attachmentDescriptions.size());
521     attachmentDescriptions.emplace_back(
522         constNullPtr,                                     // const void*                        pNext
523         (VkAttachmentDescriptionFlags)0,                  // VkAttachmentDescriptionFlags        flags
524         m_testParams.densityMapFormat,                    // VkFormat                            format
525         VK_SAMPLE_COUNT_1_BIT,                            // VkSampleCountFlagBits            samples
526         VK_ATTACHMENT_LOAD_OP_LOAD,                       // VkAttachmentLoadOp                loadOp
527         VK_ATTACHMENT_STORE_OP_DONT_CARE,                 // VkAttachmentStoreOp                storeOp
528         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                  // VkAttachmentLoadOp                stencilLoadOp
529         VK_ATTACHMENT_STORE_OP_DONT_CARE,                 // VkAttachmentStoreOp                stencilStoreOp
530         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT, // VkImageLayout                    initialLayout
531         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT  // VkImageLayout                    finalLayout
532     );
533 
534     std::vector<AttachmentRef> colorAttachmentRefs0{
535         {DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT}};
536 
537     // for multisampled scenario we need to add resolve attachment
538     // (for makeCopy scenario it is used in second subpass)
539     AttachmentRef *pResolveAttachments = DE_NULL;
540     AttachmentRef resolveAttachmentRef{DE_NULL, multisampleAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
541                                        VK_IMAGE_ASPECT_COLOR_BIT};
542     if (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT)
543         pResolveAttachments = &resolveAttachmentRef;
544 
545     std::vector<SubpassDesc> subpassDescriptions{{
546         DE_NULL,
547         (VkSubpassDescriptionFlags)0,                       // VkSubpassDescriptionFlags    flags
548         VK_PIPELINE_BIND_POINT_GRAPHICS,                    // VkPipelineBindPoint            pipelineBindPoint
549         viewMask,                                           // uint32_t                        viewMask
550         0u,                                                 // uint32_t                        inputAttachmentCount
551         DE_NULL,                                            // const VkAttachmentReference*    pInputAttachments
552         static_cast<uint32_t>(colorAttachmentRefs0.size()), // uint32_t                        colorAttachmentCount
553         colorAttachmentRefs0.data(),                        // const VkAttachmentReference*    pColorAttachments
554         makeCopySubpass ? DE_NULL : pResolveAttachments,    // const VkAttachmentReference*    pResolveAttachments
555         DE_NULL,                                            // const VkAttachmentReference*    pDepthStencilAttachment
556         0u,                                                 // uint32_t                        preserveAttachmentCount
557         DE_NULL                                             // const uint32_t*                pPreserveAttachments
558     }};
559 
560     std::vector<AttachmentRef> inputAttachmentRefs1{
561         {DE_NULL, 0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT}};
562     std::vector<AttachmentRef> colorAttachmentRefs1{
563         {DE_NULL, copyAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT}};
564     std::vector<SubpassDep> subpassDependencies;
565 
566     if (makeCopySubpass)
567     {
568         subpassDescriptions.push_back({
569             DE_NULL,
570             (VkSubpassDescriptionFlags)0,                       // VkSubpassDescriptionFlags    flags
571             VK_PIPELINE_BIND_POINT_GRAPHICS,                    // VkPipelineBindPoint            pipelineBindPoint
572             viewMask,                                           // uint32_t                        viewMask
573             static_cast<uint32_t>(inputAttachmentRefs1.size()), // uint32_t                        inputAttachmentCount
574             inputAttachmentRefs1.data(),                        // const VkAttachmentReference*    pInputAttachments
575             static_cast<uint32_t>(colorAttachmentRefs1.size()), // uint32_t                        colorAttachmentCount
576             colorAttachmentRefs1.data(),                        // const VkAttachmentReference*    pColorAttachments
577             pResolveAttachments,                                // const VkAttachmentReference*    pResolveAttachments
578             DE_NULL, // const VkAttachmentReference*    pDepthStencilAttachment
579             0u,      // uint32_t                        preserveAttachmentCount
580             DE_NULL  // const uint32_t*                pPreserveAttachments
581         });
582 
583         VkDependencyFlags dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
584         if (m_testParams.viewCount > 1)
585             dependencyFlags |= VK_DEPENDENCY_VIEW_LOCAL_BIT;
586 
587         subpassDependencies.emplace_back(
588             constNullPtr,                                  // const void*                pNext
589             0u,                                            // uint32_t                    srcSubpass
590             1u,                                            // uint32_t                    dstSubpass
591             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags        srcStageMask
592             VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,         // VkPipelineStageFlags        dstStageMask
593             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          // VkAccessFlags            srcAccessMask
594             VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,           // VkAccessFlags            dstAccessMask
595             dependencyFlags,                               // VkDependencyFlags        dependencyFlags
596             0u                                             // int32_t                    viewOffset
597         );
598     }
599 
600     VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
601 
602     // for coarse reconstruction we need to put barrier on vertex stage
603     if (m_testParams.coarseReconstruction)
604         dstStageMask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
605 
606     subpassDependencies.emplace_back(
607         constNullPtr,                                           // const void*                pNext
608         static_cast<uint32_t>(subpassDescriptions.size()) - 1u, // uint32_t                    srcSubpass
609         VK_SUBPASS_EXTERNAL,                                    // uint32_t                    dstSubpass
610         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,          // VkPipelineStageFlags        srcStageMask
611         dstStageMask,                                           // VkPipelineStageFlags        dstStageMask
612         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags            srcAccessMask
613         VK_ACCESS_SHADER_READ_BIT,                              // VkAccessFlags            dstAccessMask
614         VK_DEPENDENCY_BY_REGION_BIT,                            // VkDependencyFlags        dependencyFlags
615         0u                                                      // int32_t                    viewOffset
616     );
617 
618     VkRenderPassFragmentDensityMapCreateInfoEXT renderPassFragmentDensityMap{
619         VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT,
620         DE_NULL,
621         {densityMapAttachmentIndex, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}};
622 
623     void *renderPassInfoPNext = (void *)&renderPassFragmentDensityMap;
624 
625     const RenderPassCreateInfo renderPassInfo(
626         renderPassInfoPNext,                                  // const void*                        pNext
627         (VkRenderPassCreateFlags)0,                           // VkRenderPassCreateFlags            flags
628         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t                            attachmentCount
629         attachmentDescriptions.data(),                        // const VkAttachmentDescription*    pAttachments
630         static_cast<uint32_t>(subpassDescriptions.size()),    // uint32_t                            subpassCount
631         subpassDescriptions.data(),                           // const VkSubpassDescription*        pSubpasses
632         static_cast<uint32_t>(subpassDependencies.size()),    // uint32_t                            dependencyCount
633         subpassDependencies.data(),                           // const VkSubpassDependency*        pDependencies
634         0u,     // uint32_t                            correlatedViewMaskCount
635         DE_NULL // const uint32_t*                    pCorrelatedViewMasks
636     );
637 
638     return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
639 }
640 
641 template <RenderingType RenderingTypeValue>
createRenderPassOutputSubsampledImage() const642 Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassOutputSubsampledImage() const
643 {
644     // copy subsampled image to ordinary image - you cannot retrieve subsampled image to CPU in any way.
645     // You must first convert it into plain image through rendering
646     std::vector<AttachmentDesc> attachmentDescriptions{
647         // output attachment
648         {
649             DE_NULL,                                 // const void*                        pNext
650             (VkAttachmentDescriptionFlags)0,         // VkAttachmentDescriptionFlags        flags
651             VK_FORMAT_R8G8B8A8_UNORM,                // VkFormat                            format
652             VK_SAMPLE_COUNT_1_BIT,                   // VkSampleCountFlagBits            samples
653             VK_ATTACHMENT_LOAD_OP_CLEAR,             // VkAttachmentLoadOp                loadOp
654             VK_ATTACHMENT_STORE_OP_STORE,            // VkAttachmentStoreOp                storeOp
655             VK_ATTACHMENT_LOAD_OP_DONT_CARE,         // VkAttachmentLoadOp                stencilLoadOp
656             VK_ATTACHMENT_STORE_OP_DONT_CARE,        // VkAttachmentStoreOp                stencilStoreOp
657             VK_IMAGE_LAYOUT_UNDEFINED,               // VkImageLayout                    initialLayout
658             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout                    finalLayout
659         },
660     };
661 
662     std::vector<AttachmentRef> colorAttachmentRefs{
663         {DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT}};
664 
665     std::vector<SubpassDesc> subpassDescriptions{{
666         DE_NULL,
667         (VkSubpassDescriptionFlags)0,                      // VkSubpassDescriptionFlags        flags
668         VK_PIPELINE_BIND_POINT_GRAPHICS,                   // VkPipelineBindPoint                pipelineBindPoint
669         0u,                                                // uint32_t                            viewMask
670         0u,                                                // uint32_t                            inputAttachmentCount
671         DE_NULL,                                           // const VkAttachmentReference*        pInputAttachments
672         static_cast<uint32_t>(colorAttachmentRefs.size()), // uint32_t                            colorAttachmentCount
673         colorAttachmentRefs.data(),                        // const VkAttachmentReference*        pColorAttachments
674         DE_NULL,                                           // const VkAttachmentReference*        pResolveAttachments
675         DE_NULL, // const VkAttachmentReference*        pDepthStencilAttachment
676         0u,      // uint32_t                            preserveAttachmentCount
677         DE_NULL  // const uint32_t*                    pPreserveAttachments
678     }};
679 
680     const RenderPassCreateInfo renderPassInfo(
681         DE_NULL,                                              // const void*                        pNext
682         (VkRenderPassCreateFlags)0,                           // VkRenderPassCreateFlags            flags
683         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t                            attachmentCount
684         attachmentDescriptions.data(),                        // const VkAttachmentDescription*    pAttachments
685         static_cast<uint32_t>(subpassDescriptions.size()),    // uint32_t                            subpassCount
686         subpassDescriptions.data(),                           // const VkSubpassDescription*        pSubpasses
687         0,                                                    // uint32_t                            dependencyCount
688         DE_NULL,                                              // const VkSubpassDependency*        pDependencies
689         0u,     // uint32_t                            correlatedViewMaskCount
690         DE_NULL // const uint32_t*                    pCorrelatedViewMasks
691     );
692 
693     return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
694 }
695 
696 template <RenderingType RenderingTypeValue>
cmdBeginRenderPass(VkCommandBuffer cmdBuffer,const VkRenderPassBeginInfo * pRenderPassBegin) const697 void RenderPassWrapper<RenderingTypeValue>::cmdBeginRenderPass(VkCommandBuffer cmdBuffer,
698                                                                const VkRenderPassBeginInfo *pRenderPassBegin) const
699 {
700     RenderpassSubpass::cmdBeginRenderPass(m_vk, cmdBuffer, pRenderPassBegin, &m_subpassBeginInfo);
701 }
702 
703 template <RenderingType RenderingTypeValue>
cmdNextSubpass(VkCommandBuffer cmdBuffer) const704 void RenderPassWrapper<RenderingTypeValue>::cmdNextSubpass(VkCommandBuffer cmdBuffer) const
705 {
706     RenderpassSubpass::cmdNextSubpass(m_vk, cmdBuffer, &m_subpassBeginInfo, &m_subpassEndInfo);
707 }
708 
709 template <RenderingType RenderingTypeValue>
cmdEndRenderPass(VkCommandBuffer cmdBuffer) const710 void RenderPassWrapper<RenderingTypeValue>::cmdEndRenderPass(VkCommandBuffer cmdBuffer) const
711 {
712     RenderpassSubpass::cmdEndRenderPass(m_vk, cmdBuffer, &m_subpassEndInfo);
713 }
714 
createImagelessFrameBuffer(const DeviceInterface & vk,VkDevice vkDevice,VkRenderPass renderPass,VkExtent3D size,const std::vector<VkFramebufferAttachmentImageInfo> & attachmentInfo)715 Move<VkFramebuffer> createImagelessFrameBuffer(const DeviceInterface &vk, VkDevice vkDevice, VkRenderPass renderPass,
716                                                VkExtent3D size,
717                                                const std::vector<VkFramebufferAttachmentImageInfo> &attachmentInfo)
718 {
719     const uint32_t attachmentCount = static_cast<uint32_t>(attachmentInfo.size());
720     const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo{
721         VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, // VkStructureType sType;
722         DE_NULL,                                               // const void* pNext;
723         attachmentCount,                                       // uint32_t attachmentImageInfoCount;
724         &attachmentInfo[0] // const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
725     };
726 
727     const VkFramebufferCreateInfo framebufferParams{
728         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
729         &framebufferAttachmentsCreateInfo,         // const void* pNext;
730         VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,       // VkFramebufferCreateFlags flags;
731         renderPass,                                // VkRenderPass renderPass;
732         attachmentCount,                           // uint32_t attachmentCount;
733         DE_NULL,                                   // const VkImageView* pAttachments;
734         size.width,                                // uint32_t width;
735         size.height,                               // uint32_t height;
736         1u                                         // uint32_t layers;
737     };
738 
739     return createFramebuffer(vk, vkDevice, &framebufferParams);
740 }
741 
createFrameBuffer(const DeviceInterface & vk,VkDevice vkDevice,VkRenderPass renderPass,VkExtent3D size,const std::vector<VkImageView> & imageViews)742 Move<VkFramebuffer> createFrameBuffer(const DeviceInterface &vk, VkDevice vkDevice, VkRenderPass renderPass,
743                                       VkExtent3D size, const std::vector<VkImageView> &imageViews)
744 {
745     return makeFramebuffer(vk, vkDevice, renderPass, static_cast<uint32_t>(imageViews.size()), imageViews.data(),
746                            size.width, size.height);
747 }
748 
copyBufferToImage(const DeviceInterface & vk,VkDevice device,VkQueue queue,uint32_t queueFamilyIndex,const VkBuffer & buffer,VkDeviceSize bufferSize,const VkExtent3D & imageSize,uint32_t arrayLayers,VkImage destImage)749 void copyBufferToImage(const DeviceInterface &vk, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
750                        const VkBuffer &buffer, VkDeviceSize bufferSize, const VkExtent3D &imageSize,
751                        uint32_t arrayLayers, VkImage destImage)
752 {
753     Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
754     Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
755     Move<VkFence> fence             = createFence(vk, device);
756     VkImageLayout destImageLayout   = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
757     VkPipelineStageFlags destImageDstStageFlags = VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT;
758     VkAccessFlags finalAccessMask               = VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT;
759 
760     const VkCommandBufferBeginInfo cmdBufferBeginInfo = {
761         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
762         DE_NULL,                                     // const void* pNext;
763         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
764         (const VkCommandBufferInheritanceInfo *)DE_NULL,
765     };
766 
767     const VkBufferImageCopy copyRegion = {
768         0,                                              // VkDeviceSize                    bufferOffset
769         0,                                              // uint32_t                        bufferRowLength
770         0,                                              // uint32_t                        bufferImageHeight
771         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, arrayLayers}, // VkImageSubresourceLayers        imageSubresource
772         {0, 0, 0},                                      // VkOffset3D                    imageOffset
773         imageSize                                       // VkExtent3D                    imageExtent
774     };
775 
776     // Barriers for copying buffer to image
777     const VkBufferMemoryBarrier preBufferBarrier =
778         makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT,    // VkAccessFlags srcAccessMask;
779                                 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
780                                 buffer,                      // VkBuffer buffer;
781                                 0u,                          // VkDeviceSize offset;
782                                 bufferSize                   // VkDeviceSize size;
783         );
784 
785     const VkImageSubresourceRange subresourceRange{
786         // VkImageSubresourceRange subresourceRange;
787         VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
788         0u,                        // uint32_t baseMipLevel;
789         1u,                        // uint32_t mipLevels;
790         0u,                        // uint32_t baseArraySlice;
791         arrayLayers                // uint32_t arraySize;
792     };
793 
794     const VkImageMemoryBarrier preImageBarrier =
795         makeImageMemoryBarrier(0u,                                   // VkAccessFlags srcAccessMask;
796                                VK_ACCESS_TRANSFER_WRITE_BIT,         // VkAccessFlags dstAccessMask;
797                                VK_IMAGE_LAYOUT_UNDEFINED,            // VkImageLayout oldLayout;
798                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
799                                destImage,                            // VkImage image;
800                                subresourceRange                      // VkImageSubresourceRange subresourceRange;
801         );
802 
803     const VkImageMemoryBarrier postImageBarrier =
804         makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,         // VkAccessFlags srcAccessMask;
805                                finalAccessMask,                      // VkAccessFlags dstAccessMask;
806                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
807                                destImageLayout,                      // VkImageLayout newLayout;
808                                destImage,                            // VkImage image;
809                                subresourceRange                      // VkImageSubresourceRange subresourceRange;
810         );
811 
812     VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
813     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
814                           0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
815     vk.cmdCopyBufferToImage(*cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
816     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0,
817                           (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
818                           &postImageBarrier);
819     VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
820 
821     const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
822 
823     const VkSubmitInfo submitInfo = {
824         VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
825         DE_NULL,                       // const void* pNext;
826         0u,                            // uint32_t waitSemaphoreCount;
827         DE_NULL,                       // const VkSemaphore* pWaitSemaphores;
828         &pipelineStageFlags,           // const VkPipelineStageFlags* pWaitDstStageMask;
829         1u,                            // uint32_t commandBufferCount;
830         &cmdBuffer.get(),              // const VkCommandBuffer* pCommandBuffers;
831         0u,                            // uint32_t signalSemaphoreCount;
832         DE_NULL                        // const VkSemaphore* pSignalSemaphores;
833     };
834 
835     try
836     {
837         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
838         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
839     }
840     catch (...)
841     {
842         VK_CHECK(vk.deviceWaitIdle(device));
843         throw;
844     }
845 }
846 
buildGraphicsPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule vertexShaderModule,const VkShaderModule fragmentShaderModule,const VkRenderPass renderPass,const std::vector<VkViewport> & viewportVect,const std::vector<VkRect2D> & scissorVect,const uint32_t subpass,const VkPipelineMultisampleStateCreateInfo * multisampleStateCreateInfo,const void * pNext,const bool useDensityMapAttachment,const bool useMaintenance5=false)847 Move<VkPipeline> buildGraphicsPipeline(const DeviceInterface &vk, const VkDevice device,
848                                        const VkPipelineLayout pipelineLayout, const VkShaderModule vertexShaderModule,
849                                        const VkShaderModule fragmentShaderModule, const VkRenderPass renderPass,
850                                        const std::vector<VkViewport> &viewportVect,
851                                        const std::vector<VkRect2D> &scissorVect, const uint32_t subpass,
852                                        const VkPipelineMultisampleStateCreateInfo *multisampleStateCreateInfo,
853                                        const void *pNext, const bool useDensityMapAttachment,
854                                        const bool useMaintenance5 = false)
855 {
856     std::vector<VkPipelineShaderStageCreateInfo> pipelineShaderStageParams(
857         2,
858         {
859             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                        sType
860             DE_NULL,                                             // const void*                            pNext
861             0u,                                                  // VkPipelineShaderStageCreateFlags        flags
862             VK_SHADER_STAGE_VERTEX_BIT,                          // VkShaderStageFlagBits                stage
863             vertexShaderModule,                                  // VkShaderModule                        module
864             "main",                                              // const char*                            pName
865             DE_NULL // const VkSpecializationInfo*            pSpecializationInfo
866         });
867     pipelineShaderStageParams[1].stage  = VK_SHADER_STAGE_FRAGMENT_BIT;
868     pipelineShaderStageParams[1].module = fragmentShaderModule;
869 
870     const VkVertexInputBindingDescription vertexInputBindingDescription{
871         0u,                         // uint32_t binding;
872         sizeof(Vertex4RGBA),        // uint32_t strideInBytes;
873         VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
874     };
875 
876     std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions{
877         {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u},
878         {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (uint32_t)(sizeof(float) * 4)},
879         {2u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (uint32_t)(sizeof(float) * 8)}};
880 
881     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo{
882         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
883         DE_NULL,                                                   // const void* pNext;
884         0u,                                                        // VkPipelineVertexInputStateCreateFlags flags;
885         1u,                                                        // uint32_t vertexBindingDescriptionCount;
886         &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
887         static_cast<uint32_t>(vertexInputAttributeDescriptions.size()), // uint32_t vertexAttributeDescriptionCount;
888         vertexInputAttributeDescriptions
889             .data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
890     };
891 
892     const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo{
893         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                            sType
894         DE_NULL,                                                     // const void*                                pNext
895         0u,                                                          // VkPipelineInputAssemblyStateCreateFlags    flags
896         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology                        topology
897         VK_FALSE                             // VkBool32                                    primitiveRestartEnable
898     };
899 
900     const VkPipelineViewportStateCreateInfo viewportStateCreateInfo{
901         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                            sType
902         DE_NULL,                                               // const void*                                pNext
903         (VkPipelineViewportStateCreateFlags)0,                 // VkPipelineViewportStateCreateFlags        flags
904         (uint32_t)viewportVect.size(), // uint32_t                                    viewportCount
905         viewportVect.data(),           // const VkViewport*                        pViewports
906         (uint32_t)scissorVect.size(),  // uint32_t                                    scissorCount
907         scissorVect.data()             // const VkRect2D*                            pScissors
908     };
909 
910     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfoDefault{
911         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType
912         DE_NULL,                                                    // const void*                                pNext
913         0u,                                                         // VkPipelineRasterizationStateCreateFlags    flags
914         VK_FALSE,                        // VkBool32                                    depthClampEnable
915         VK_FALSE,                        // VkBool32                                    rasterizerDiscardEnable
916         VK_POLYGON_MODE_FILL,            // VkPolygonMode                            polygonMode
917         VK_CULL_MODE_NONE,               // VkCullModeFlags                            cullMode
918         VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace                                frontFace
919         VK_FALSE,                        // VkBool32                                    depthBiasEnable
920         0.0f,                            // float                                    depthBiasConstantFactor
921         0.0f,                            // float                                    depthBiasClamp
922         0.0f,                            // float                                    depthBiasSlopeFactor
923         1.0f                             // float                                    lineWidth
924     };
925 
926     const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfoDefault{
927         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                            sType
928         DE_NULL,                                                  // const void*                                pNext
929         0u,                                                       // VkPipelineMultisampleStateCreateFlags    flags
930         VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits                    rasterizationSamples
931         VK_FALSE,              // VkBool32                                    sampleShadingEnable
932         1.0f,                  // float                                    minSampleShading
933         DE_NULL,               // const VkSampleMask*                        pSampleMask
934         VK_FALSE,              // VkBool32                                    alphaToCoverageEnable
935         VK_FALSE               // VkBool32                                    alphaToOneEnable
936     };
937 
938     const VkStencilOpState stencilOpState{
939         VK_STENCIL_OP_KEEP,  // VkStencilOp        failOp
940         VK_STENCIL_OP_KEEP,  // VkStencilOp        passOp
941         VK_STENCIL_OP_KEEP,  // VkStencilOp        depthFailOp
942         VK_COMPARE_OP_NEVER, // VkCompareOp        compareOp
943         0,                   // uint32_t            compareMask
944         0,                   // uint32_t            writeMask
945         0                    // uint32_t            reference
946     };
947 
948     const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault{
949         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                            sType
950         DE_NULL,                                                    // const void*                                pNext
951         0u,                                                         // VkPipelineDepthStencilStateCreateFlags    flags
952         VK_FALSE,                    // VkBool32                                    depthTestEnable
953         VK_FALSE,                    // VkBool32                                    depthWriteEnable
954         VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp                                depthCompareOp
955         VK_FALSE,                    // VkBool32                                    depthBoundsTestEnable
956         VK_FALSE,                    // VkBool32                                    stencilTestEnable
957         stencilOpState,              // VkStencilOpState                            front
958         stencilOpState,              // VkStencilOpState                            back
959         0.0f,                        // float                                    minDepthBounds
960         1.0f,                        // float                                    maxDepthBounds
961     };
962 
963     const std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(
964         2,
965         {VK_FALSE,                // VkBool32                    blendEnable
966          VK_BLEND_FACTOR_ZERO,    // VkBlendFactor            srcColorBlendFactor
967          VK_BLEND_FACTOR_ZERO,    // VkBlendFactor            dstColorBlendFactor
968          VK_BLEND_OP_ADD,         // VkBlendOp                colorBlendOp
969          VK_BLEND_FACTOR_ZERO,    // VkBlendFactor            srcAlphaBlendFactor
970          VK_BLEND_FACTOR_ZERO,    // VkBlendFactor            dstAlphaBlendFactor
971          VK_BLEND_OP_ADD,         // VkBlendOp                alphaBlendOp
972          VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags    colorWriteMask
973              | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT});
974 
975     uint32_t attachmentCount = 1u;
976     if (pNext)
977     {
978         const auto *pipelineRenderingCreateInfo = reinterpret_cast<const VkPipelineRenderingCreateInfoKHR *>(pNext);
979         DE_ASSERT(pipelineRenderingCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR);
980         attachmentCount = pipelineRenderingCreateInfo->colorAttachmentCount;
981         DE_ASSERT(attachmentCount <= colorBlendAttachmentStates.size());
982     }
983 
984     const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoDefault{
985         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
986         DE_NULL,                           // const void*                                    pNext
987         0u,                                // VkPipelineColorBlendStateCreateFlags            flags
988         VK_FALSE,                          // VkBool32                                        logicOpEnable
989         VK_LOGIC_OP_CLEAR,                 // VkLogicOp                                    logicOp
990         attachmentCount,                   // uint32_t                                        attachmentCount
991         colorBlendAttachmentStates.data(), // const VkPipelineColorBlendAttachmentState*    pAttachments
992         {0.0f, 0.0f, 0.0f, 0.0f}           // float                                        blendConstants[4]
993     };
994 
995     VkGraphicsPipelineCreateInfo pipelineCreateInfo{
996         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType                                    sType
997         pNext,                                           // const void*                                        pNext
998         (useDensityMapAttachment ?
999              uint32_t(VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT) :
1000              0u),                                   // VkPipelineCreateFlags                            flags
1001         (uint32_t)pipelineShaderStageParams.size(), // uint32_t                                            stageCount
1002         &pipelineShaderStageParams[0],              // const VkPipelineShaderStageCreateInfo*            pStages
1003         &vertexInputStateCreateInfo,          // const VkPipelineVertexInputStateCreateInfo*        pVertexInputState
1004         &inputAssemblyStateCreateInfo,        // const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState
1005         DE_NULL,                              // const VkPipelineTessellationStateCreateInfo*        pTessellationState
1006         &viewportStateCreateInfo,             // const VkPipelineViewportStateCreateInfo*            pViewportState
1007         &rasterizationStateCreateInfoDefault, // const VkPipelineRasterizationStateCreateInfo*    pRasterizationState
1008         multisampleStateCreateInfo ?
1009             multisampleStateCreateInfo :
1010             &multisampleStateCreateInfoDefault, // const VkPipelineMultisampleStateCreateInfo*        pMultisampleState
1011         &depthStencilStateCreateInfoDefault, // const VkPipelineDepthStencilStateCreateInfo*        pDepthStencilState
1012         &colorBlendStateCreateInfoDefault,   // const VkPipelineColorBlendStateCreateInfo*        pColorBlendState
1013         DE_NULL,                             // const VkPipelineDynamicStateCreateInfo*            pDynamicState
1014         pipelineLayout,                      // VkPipelineLayout                                    layout
1015         renderPass,                          // VkRenderPass                                        renderPass
1016         subpass,                             // uint32_t                                            subpass
1017         DE_NULL,                             // VkPipeline                                        basePipelineHandle
1018         0                                    // int32_t basePipelineIndex;
1019     };
1020 
1021     VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo{};
1022     if (useDensityMapAttachment && useMaintenance5)
1023     {
1024         pipelineFlags2CreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR;
1025         pipelineFlags2CreateInfo.flags = VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
1026         pipelineFlags2CreateInfo.pNext = pipelineCreateInfo.pNext;
1027         pipelineCreateInfo.pNext       = &pipelineFlags2CreateInfo;
1028         pipelineCreateInfo.flags       = 0;
1029     }
1030 
1031     return createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
1032 }
1033 
1034 class FragmentDensityMapTest : public vkt::TestCase
1035 {
1036 public:
1037     FragmentDensityMapTest(tcu::TestContext &testContext, const std::string &name, const TestParams &testParams);
1038     virtual void initPrograms(SourceCollections &sourceCollections) const;
1039     virtual TestInstance *createInstance(Context &context) const;
1040     virtual void checkSupport(Context &context) const;
1041 
1042 private:
1043     const TestParams m_testParams;
1044 };
1045 
1046 class FragmentDensityMapTestInstance : public vkt::TestInstance
1047 {
1048 public:
1049     FragmentDensityMapTestInstance(Context &context, const TestParams &testParams);
1050     virtual tcu::TestStatus iterate(void);
1051 
1052 private:
1053     typedef std::shared_ptr<RenderPassWrapperBase> RenderPassWrapperBasePtr;
1054 
1055     void drawDynamicDensityMap(VkCommandBuffer cmdBuffer);
1056     void drawSubsampledImage(VkCommandBuffer cmdBuffer);
1057     void drawCopySubsampledImage(VkCommandBuffer cmdBuffer);
1058     void drawResampleSubsampledImage(VkCommandBuffer cmdBuffer);
1059     void drawOutputSubsampledImage(VkCommandBuffer cmdBuffer);
1060     void remapingBeforeCopySubsampledImage(VkCommandBuffer cmdBuffer);
1061     void createCommandBufferForRenderpass(RenderPassWrapperBasePtr renderPassWrapper, const VkExtent3D &colorImageSize,
1062                                           const VkRect2D &dynamicDensityMapRenderArea,
1063                                           const VkRect2D &colorImageRenderArea, const VkRect2D &outputRenderArea);
1064     void createCommandBufferForDynamicRendering(const VkRect2D &dynamicDensityMapRenderArea,
1065                                                 const VkRect2D &colorImageRenderArea, const VkRect2D &outputRenderArea,
1066                                                 const VkDevice &vkDevice);
1067     tcu::TestStatus verifyImage(void);
1068 
1069 private:
1070     typedef de::SharedPtr<Unique<VkSampler>> VkSamplerSp;
1071     typedef de::SharedPtr<Unique<VkImage>> VkImageSp;
1072     typedef de::SharedPtr<Allocation> AllocationSp;
1073     typedef de::SharedPtr<Unique<VkImageView>> VkImageViewSp;
1074 
1075     TestParams m_testParams;
1076     tcu::UVec2 m_renderSize;
1077     tcu::Vec2 m_densityValue;
1078     uint32_t m_viewMask;
1079 
1080     Move<VkCommandPool> m_cmdPool;
1081 
1082     std::vector<VkImageSp> m_densityMapImages;
1083     std::vector<AllocationSp> m_densityMapImageAllocs;
1084     std::vector<VkImageViewSp> m_densityMapImageViews;
1085 
1086     Move<VkImage> m_colorImage;
1087     de::MovePtr<Allocation> m_colorImageAlloc;
1088     Move<VkImageView> m_colorImageView;
1089 
1090     Move<VkImage> m_colorCopyImage;
1091     de::MovePtr<Allocation> m_colorCopyImageAlloc;
1092     Move<VkImageView> m_colorCopyImageView;
1093 
1094     Move<VkImage> m_colorResolvedImage;
1095     de::MovePtr<Allocation> m_colorResolvedImageAlloc;
1096     Move<VkImageView> m_colorResolvedImageView;
1097 
1098     Move<VkImage> m_outputImage;
1099     de::MovePtr<Allocation> m_outputImageAlloc;
1100     Move<VkImageView> m_outputImageView;
1101 
1102     std::vector<VkSamplerSp> m_colorSamplers;
1103 
1104     Move<VkRenderPass> m_renderPassProduceDynamicDensityMap;
1105     Move<VkRenderPass> m_renderPassProduceSubsampledImage;
1106     Move<VkRenderPass> m_renderPassUpdateSubsampledImage;
1107     Move<VkRenderPass> m_renderPassOutputSubsampledImage;
1108     Move<VkFramebuffer> m_framebufferProduceDynamicDensityMap;
1109     Move<VkFramebuffer> m_framebufferProduceSubsampledImage;
1110     Move<VkFramebuffer> m_framebufferUpdateSubsampledImage;
1111     Move<VkFramebuffer> m_framebufferOutputSubsampledImage;
1112 
1113     Move<VkDescriptorSetLayout> m_descriptorSetLayoutProduceSubsampled;
1114 
1115     Move<VkDescriptorSetLayout> m_descriptorSetLayoutOperateOnSubsampledImage;
1116     Move<VkDescriptorPool> m_descriptorPoolOperateOnSubsampledImage;
1117     Move<VkDescriptorSet> m_descriptorSetOperateOnSubsampledImage;
1118 
1119     Move<VkDescriptorSetLayout> m_descriptorSetLayoutOutputSubsampledImage;
1120     Move<VkDescriptorPool> m_descriptorPoolOutputSubsampledImage;
1121     Move<VkDescriptorSet> m_descriptorSetOutputSubsampledImage;
1122 
1123     Move<VkShaderModule> m_vertexCommonShaderModule;
1124     Move<VkShaderModule> m_fragmentShaderModuleProduceSubsampledImage;
1125     Move<VkShaderModule> m_fragmentShaderModuleCopySubsampledImage;
1126     Move<VkShaderModule> m_fragmentShaderModuleUpdateSubsampledImage;
1127     Move<VkShaderModule> m_fragmentShaderModuleOutputSubsampledImage;
1128 
1129     std::vector<Vertex4RGBA> m_verticesDDM;
1130     Move<VkBuffer> m_vertexBufferDDM;
1131     de::MovePtr<Allocation> m_vertexBufferAllocDDM;
1132 
1133     std::vector<Vertex4RGBA> m_vertices;
1134     Move<VkBuffer> m_vertexBuffer;
1135     de::MovePtr<Allocation> m_vertexBufferAlloc;
1136 
1137     std::vector<Vertex4RGBA> m_verticesOutput;
1138     Move<VkBuffer> m_vertexBufferOutput;
1139     de::MovePtr<Allocation> m_vertexBufferOutputAlloc;
1140 
1141     Move<VkPipelineLayout> m_pipelineLayoutNoDescriptors;
1142     Move<VkPipelineLayout> m_pipelineLayoutOperateOnSubsampledImage;
1143     Move<VkPipelineLayout> m_pipelineLayoutOutputSubsampledImage;
1144     Move<VkPipeline> m_graphicsPipelineProduceDynamicDensityMap;
1145     Move<VkPipeline> m_graphicsPipelineProduceSubsampledImage;
1146     Move<VkPipeline> m_graphicsPipelineCopySubsampledImage;
1147     Move<VkPipeline> m_graphicsPipelineUpdateSubsampledImage;
1148     Move<VkPipeline> m_graphicsPipelineOutputSubsampledImage;
1149 
1150     Move<VkCommandBuffer> m_cmdBuffer;
1151     Move<VkCommandBuffer> m_dynamicDensityMapSecCmdBuffer;
1152     Move<VkCommandBuffer> m_subsampledImageSecCmdBuffer;
1153     Move<VkCommandBuffer> m_resampleSubsampledImageSecCmdBuffer;
1154     Move<VkCommandBuffer> m_outputSubsampledImageSecCmdBuffer;
1155 };
1156 
FragmentDensityMapTest(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)1157 FragmentDensityMapTest::FragmentDensityMapTest(tcu::TestContext &testContext, const std::string &name,
1158                                                const TestParams &testParams)
1159     : vkt::TestCase(testContext, name)
1160     , m_testParams(testParams)
1161 {
1162     DE_ASSERT(testParams.samplersCount > 0);
1163 }
1164 
initPrograms(SourceCollections & sourceCollections) const1165 void FragmentDensityMapTest::initPrograms(SourceCollections &sourceCollections) const
1166 {
1167     const std::string vertSourceTemplate("#version 450\n"
1168                                          "#extension GL_EXT_multiview : enable\n"
1169                                          "${EXTENSIONS}"
1170                                          "layout(location = 0) in  vec4 inPosition;\n"
1171                                          "layout(location = 1) in  vec4 inUV;\n"
1172                                          "layout(location = 2) in  vec4 inColor;\n"
1173                                          "layout(location = 0) out vec4 outUV;\n"
1174                                          "layout(location = 1) out vec4 outColor;\n"
1175                                          "out gl_PerVertex\n"
1176                                          "{\n"
1177                                          "  vec4 gl_Position;\n"
1178                                          "};\n"
1179                                          "void main(void)\n"
1180                                          "{\n"
1181                                          "    gl_Position = inPosition;\n"
1182                                          "    outUV = inUV;\n"
1183                                          "    outColor = inColor;\n"
1184                                          "    ${OPERATION}"
1185                                          "}\n");
1186 
1187     std::map<std::string, std::string> parameters{{"EXTENSIONS", ""}, {"OPERATION", ""}};
1188     if (m_testParams.multiViewport)
1189     {
1190         parameters["EXTENSIONS"] = "#extension GL_ARB_shader_viewport_layer_array : enable\n";
1191         parameters["OPERATION"]  = "gl_ViewportIndex = gl_ViewIndex;\n";
1192     }
1193     sourceCollections.glslSources.add("vert")
1194         << glu::VertexSource(tcu::StringTemplate(vertSourceTemplate).specialize(parameters));
1195 
1196     sourceCollections.glslSources.add("frag_produce_subsampled") << glu::FragmentSource(
1197         "#version 450\n"
1198         "#extension GL_EXT_fragment_invocation_density : enable\n"
1199         "#extension GL_EXT_multiview : enable\n"
1200         "layout(location = 0) in vec4 inUV;\n"
1201         "layout(location = 1) in vec4 inColor;\n"
1202         "layout(location = 0) out vec4 fragColor;\n"
1203         "void main(void)\n"
1204         "{\n"
1205         "    fragColor = vec4(inColor.x, inColor.y, 1.0/float(gl_FragSizeEXT.x), 1.0/(gl_FragSizeEXT.y));\n"
1206         "}\n");
1207 
1208     sourceCollections.glslSources.add("frag_update_subsampled") << glu::FragmentSource(
1209         "#version 450\n"
1210         "#extension GL_EXT_fragment_invocation_density : enable\n"
1211         "#extension GL_EXT_multiview : enable\n"
1212         "layout(location = 0) in vec4 inUV;\n"
1213         "layout(location = 1) in vec4 inColor;\n"
1214         "layout(location = 0) out vec4 fragColor;\n"
1215         "void main(void)\n"
1216         "{\n"
1217         "    if (gl_FragCoord.y < 0.5)\n"
1218         "        discard;\n"
1219         "    fragColor = vec4(inColor.x, inColor.y, 1.0/float(gl_FragSizeEXT.x), 1.0/(gl_FragSizeEXT.y));\n"
1220         "}\n");
1221 
1222     sourceCollections.glslSources.add("frag_copy_subsampled") << glu::FragmentSource(
1223         "#version 450\n"
1224         "#extension GL_EXT_fragment_invocation_density : enable\n"
1225         "#extension GL_EXT_multiview : enable\n"
1226         "layout(location = 0) in vec4 inUV;\n"
1227         "layout(location = 1) in vec4 inColor;\n"
1228         "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputAtt;\n"
1229         "layout(location = 0) out vec4 fragColor;\n"
1230         "void main(void)\n"
1231         "{\n"
1232         "    fragColor = subpassLoad(inputAtt);\n"
1233         "}\n");
1234 
1235     sourceCollections.glslSources.add("frag_copy_subsampled_ms") << glu::FragmentSource(
1236         "#version 450\n"
1237         "#extension GL_EXT_fragment_invocation_density : enable\n"
1238         "#extension GL_EXT_multiview : enable\n"
1239         "layout(location = 0) in vec4 inUV;\n"
1240         "layout(location = 1) in vec4 inColor;\n"
1241         "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS inputAtt;\n"
1242         "layout(location = 0) out vec4 fragColor;\n"
1243         "void main(void)\n"
1244         "{\n"
1245         "    fragColor = subpassLoad(inputAtt, gl_SampleID);\n"
1246         "}\n");
1247 
1248     const char *samplersDefTemplate = "layout(binding = ${BINDING})  uniform ${SAMPLER} subsampledImage${BINDING};\n";
1249     const char *sumColorsTemplate   = "    fragColor += texture(subsampledImage${BINDING}, inUV.${COMPONENTS});\n";
1250 
1251     const char *densitymapOutputTemplate = "#version 450\n"
1252                                            "layout(location = 0) in vec4 inUV;\n"
1253                                            "layout(location = 1) in vec4 inColor;\n"
1254                                            "${SAMPLERS_DEF}"
1255                                            "layout(location = 0) out vec4 fragColor;\n"
1256                                            "void main(void)\n"
1257                                            "{\n"
1258                                            "    fragColor = vec4(0);\n"
1259                                            "${SUM_COLORS}"
1260                                            "    fragColor /= float(${COUNT});\n"
1261                                            "}\n";
1262 
1263     parameters = {
1264         {"SAMPLER", ""},      {"BINDING", ""},
1265         {"COMPONENTS", ""},   {"COUNT", std::to_string(m_testParams.samplersCount)},
1266         {"SAMPLERS_DEF", ""}, {"SUM_COLORS", ""},
1267     };
1268 
1269     std::string sampler2dDefs;
1270     std::string sampler2dSumColors;
1271     std::string sampler2dArrayDefs;
1272     std::string sampler2dArraySumColors;
1273     for (uint32_t samplerIndex = 0; samplerIndex < m_testParams.samplersCount; ++samplerIndex)
1274     {
1275         parameters["BINDING"] = std::to_string(samplerIndex);
1276 
1277         parameters["COMPONENTS"] = "xy";
1278         parameters["SAMPLER"]    = "sampler2D";
1279         sampler2dDefs += tcu::StringTemplate(samplersDefTemplate).specialize(parameters);
1280         sampler2dSumColors += tcu::StringTemplate(sumColorsTemplate).specialize(parameters);
1281 
1282         parameters["COMPONENTS"] = "xyz";
1283         parameters["SAMPLER"]    = "sampler2DArray";
1284         sampler2dArrayDefs += tcu::StringTemplate(samplersDefTemplate).specialize(parameters);
1285         sampler2dArraySumColors += tcu::StringTemplate(sumColorsTemplate).specialize(parameters);
1286     }
1287 
1288     parameters["SAMPLERS_DEF"] = sampler2dDefs;
1289     parameters["SUM_COLORS"]   = sampler2dSumColors;
1290     sourceCollections.glslSources.add("frag_output_2d")
1291         << glu::FragmentSource(tcu::StringTemplate(densitymapOutputTemplate).specialize(parameters));
1292 
1293     parameters["SAMPLERS_DEF"] = sampler2dArrayDefs;
1294     parameters["SUM_COLORS"]   = sampler2dArraySumColors;
1295     sourceCollections.glslSources.add("frag_output_2darray")
1296         << glu::FragmentSource(tcu::StringTemplate(densitymapOutputTemplate).specialize(parameters));
1297 }
1298 
createInstance(Context & context) const1299 TestInstance *FragmentDensityMapTest::createInstance(Context &context) const
1300 {
1301     return new FragmentDensityMapTestInstance(context, m_testParams);
1302 }
1303 
checkSupport(Context & context) const1304 void FragmentDensityMapTest::checkSupport(Context &context) const
1305 {
1306     const InstanceInterface &vki            = context.getInstanceInterface();
1307     const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
1308 
1309     context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
1310 
1311     if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1312     {
1313         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1314         if (m_testParams.makeCopy)
1315             context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
1316     }
1317 
1318     if (m_testParams.imagelessFramebuffer)
1319         context.requireDeviceFunctionality("VK_KHR_imageless_framebuffer");
1320 
1321     if (m_testParams.useMaintenance5)
1322         context.requireDeviceFunctionality("VK_KHR_maintenance5");
1323 
1324     VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures = initVulkanStructure();
1325     VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features =
1326         initVulkanStructure(&fragmentDensityMapFeatures);
1327     VkPhysicalDeviceFeatures2KHR features2 = initVulkanStructure(&fragmentDensityMap2Features);
1328 
1329     context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
1330 
1331     const auto &fragmentDensityMap2Properties = context.getFragmentDensityMap2PropertiesEXT();
1332 
1333     if (!fragmentDensityMapFeatures.fragmentDensityMap)
1334         TCU_THROW(NotSupportedError, "fragmentDensityMap feature is not supported");
1335     if (m_testParams.dynamicDensityMap && !fragmentDensityMapFeatures.fragmentDensityMapDynamic)
1336         TCU_THROW(NotSupportedError, "fragmentDensityMapDynamic feature is not supported");
1337     if (m_testParams.nonSubsampledImages && !fragmentDensityMapFeatures.fragmentDensityMapNonSubsampledImages)
1338         TCU_THROW(NotSupportedError, "fragmentDensityMapNonSubsampledImages feature is not supported");
1339 
1340     if (m_testParams.deferredDensityMap)
1341     {
1342         context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1343         if (!fragmentDensityMap2Features.fragmentDensityMapDeferred)
1344             TCU_THROW(NotSupportedError, "fragmentDensityMapDeferred feature is not supported");
1345     }
1346     if (m_testParams.subsampledLoads)
1347     {
1348         context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1349         if (!fragmentDensityMap2Properties.subsampledLoads)
1350             TCU_THROW(NotSupportedError, "subsampledLoads property is not supported");
1351     }
1352     if (m_testParams.coarseReconstruction)
1353     {
1354         context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1355         if (!fragmentDensityMap2Properties.subsampledCoarseReconstructionEarlyAccess)
1356             TCU_THROW(NotSupportedError, "subsampledCoarseReconstructionEarlyAccess property is not supported");
1357     }
1358 
1359     if (m_testParams.viewCount > 1)
1360     {
1361         context.requireDeviceFunctionality("VK_KHR_multiview");
1362         if (!context.getMultiviewFeatures().multiview)
1363             TCU_THROW(NotSupportedError, "Implementation does not support multiview feature");
1364 
1365         if (m_testParams.viewCount > 2)
1366         {
1367             context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1368             if (m_testParams.viewCount > fragmentDensityMap2Properties.maxSubsampledArrayLayers)
1369                 TCU_THROW(
1370                     NotSupportedError,
1371                     "Maximum number of VkImageView array layers for usages supporting subsampled samplers is to small");
1372         }
1373     }
1374 
1375     if (m_testParams.multiViewport)
1376     {
1377         context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
1378         if (!context.getDeviceFeatures().multiViewport)
1379             TCU_THROW(NotSupportedError, "multiViewport not supported");
1380     }
1381 
1382     if (!m_testParams.nonSubsampledImages && (m_testParams.samplersCount > 1))
1383     {
1384         context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1385         if (m_testParams.samplersCount > fragmentDensityMap2Properties.maxDescriptorSetSubsampledSamplers)
1386             TCU_THROW(NotSupportedError, "Required number of subsampled samplers is not supported");
1387     }
1388 
1389     vk::VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1390     if (m_testParams.makeCopy)
1391         colorImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1392 
1393     uint32_t colorImageCreateFlags =
1394         m_testParams.nonSubsampledImages ? 0u : (uint32_t)VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
1395     VkImageFormatProperties imageFormatProperties(
1396         getPhysicalDeviceImageFormatProperties(vki, vkPhysicalDevice, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
1397                                                VK_IMAGE_TILING_OPTIMAL, colorImageUsage, colorImageCreateFlags));
1398 
1399     if ((imageFormatProperties.sampleCounts & m_testParams.colorSamples) == 0)
1400         TCU_THROW(NotSupportedError, "Color image type not supported");
1401 
1402     if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1403         !context.getPortabilitySubsetFeatures().multisampleArrayImage &&
1404         (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT) && (m_testParams.viewCount != 1))
1405     {
1406         TCU_THROW(
1407             NotSupportedError,
1408             "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel");
1409     }
1410 
1411     if (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT)
1412         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
1413 }
1414 
FragmentDensityMapTestInstance(Context & context,const TestParams & testParams)1415 FragmentDensityMapTestInstance::FragmentDensityMapTestInstance(Context &context, const TestParams &testParams)
1416     : vkt::TestInstance(context)
1417     , m_testParams(testParams)
1418 {
1419     m_renderSize = tcu::UVec2(
1420         deFloorFloatToInt32(m_testParams.renderMultiplier * static_cast<float>(m_testParams.densityMapSize.x())),
1421         deFloorFloatToInt32(m_testParams.renderMultiplier * static_cast<float>(m_testParams.densityMapSize.y())));
1422     m_densityValue = tcu::Vec2(1.0f / static_cast<float>(m_testParams.fragmentArea.x()),
1423                                1.0f / static_cast<float>(m_testParams.fragmentArea.y()));
1424     m_viewMask     = (m_testParams.viewCount > 1) ? ((1u << m_testParams.viewCount) - 1u) : 0u;
1425 
1426     const DeviceInterface &vk               = m_context.getDeviceInterface();
1427     const VkDevice vkDevice                 = getDevice(m_context);
1428     const VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
1429     const uint32_t queueFamilyIndex         = m_context.getUniversalQueueFamilyIndex();
1430     const VkQueue queue                     = getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
1431     SimpleAllocator memAlloc(vk, vkDevice,
1432                              getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), vkPhysicalDevice));
1433     const VkComponentMapping componentMappingRGBA = makeComponentMappingRGBA();
1434     RenderPassWrapperBasePtr renderPassWrapper;
1435 
1436     // calculate all image sizes, image usage flags, view types etc.
1437     uint32_t densitiMapCount = 1 + m_testParams.subsampledLoads;
1438     VkExtent3D densityMapImageSize{m_testParams.densityMapSize.x(), m_testParams.densityMapSize.y(), 1};
1439     uint32_t densityMapImageLayers = m_testParams.viewCount;
1440     VkImageViewType densityMapImageViewType =
1441         (m_testParams.viewCount > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1442     vk::VkImageUsageFlags densityMapImageUsage =
1443         VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1444     const VkImageSubresourceRange densityMapSubresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,
1445                                                                 densityMapImageLayers};
1446     uint32_t densityMapImageViewFlags                        = 0u;
1447 
1448     const VkFormat colorImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
1449     VkExtent3D colorImageSize{m_renderSize.x() / m_testParams.viewCount, m_renderSize.y(), 1};
1450     uint32_t colorImageLayers             = densityMapImageLayers;
1451     VkImageViewType colorImageViewType    = densityMapImageViewType;
1452     vk::VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1453     uint32_t colorImageCreateFlags =
1454         m_testParams.nonSubsampledImages ? 0u : (uint32_t)VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
1455     const VkImageSubresourceRange colorSubresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, colorImageLayers};
1456     bool isColorImageMultisampled                       = m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
1457     bool isDynamicRendering = m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING;
1458 
1459     VkExtent3D outputImageSize{m_renderSize.x(), m_renderSize.y(), 1};
1460     const VkImageSubresourceRange outputSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
1461 
1462     if (m_testParams.dynamicDensityMap)
1463     {
1464         DE_ASSERT(!m_testParams.subsampledLoads);
1465 
1466         densityMapImageUsage     = VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1467         densityMapImageViewFlags = (uint32_t)VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT;
1468     }
1469     else if (m_testParams.deferredDensityMap)
1470         densityMapImageViewFlags = (uint32_t)VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT;
1471     if (m_testParams.makeCopy)
1472         colorImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1473 
1474     // Create subsampled color image
1475     prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat, colorImageSize,
1476                              colorImageLayers, m_testParams.colorSamples, colorImageUsage, queueFamilyIndex, 0u,
1477                              colorImageViewType, componentMappingRGBA, colorSubresourceRange, m_colorImage,
1478                              m_colorImageAlloc, m_colorImageView);
1479 
1480     // Create subsampled color image for resolve operation ( when multisampling is used )
1481     if (isColorImageMultisampled)
1482     {
1483         prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat, colorImageSize,
1484                                  colorImageLayers, VK_SAMPLE_COUNT_1_BIT,
1485                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, queueFamilyIndex, 0u,
1486                                  colorImageViewType, componentMappingRGBA, colorSubresourceRange, m_colorResolvedImage,
1487                                  m_colorResolvedImageAlloc, m_colorResolvedImageView);
1488     }
1489 
1490     // Create subsampled image copy
1491     if (m_testParams.makeCopy)
1492     {
1493         prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat, colorImageSize,
1494                                  colorImageLayers, m_testParams.colorSamples,
1495                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, queueFamilyIndex, 0u,
1496                                  colorImageViewType, componentMappingRGBA, colorSubresourceRange, m_colorCopyImage,
1497                                  m_colorCopyImageAlloc, m_colorCopyImageView);
1498     }
1499 
1500     // Create output image ( data from subsampled color image will be copied into it using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT )
1501     prepareImageAndImageView(vk, vkDevice, memAlloc, 0u, colorImageFormat, outputImageSize, 1u, VK_SAMPLE_COUNT_1_BIT,
1502                              VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, queueFamilyIndex,
1503                              0u, VK_IMAGE_VIEW_TYPE_2D, componentMappingRGBA, outputSubresourceRange, m_outputImage,
1504                              m_outputImageAlloc, m_outputImageView);
1505 
1506     // Create density map image/images
1507     for (uint32_t mapIndex = 0; mapIndex < densitiMapCount; ++mapIndex)
1508     {
1509         Move<VkImage> densityMapImage;
1510         de::MovePtr<Allocation> densityMapImageAlloc;
1511         Move<VkImageView> densityMapImageView;
1512 
1513         prepareImageAndImageView(vk, vkDevice, memAlloc, 0u, m_testParams.densityMapFormat, densityMapImageSize,
1514                                  densityMapImageLayers, VK_SAMPLE_COUNT_1_BIT, densityMapImageUsage, queueFamilyIndex,
1515                                  densityMapImageViewFlags, densityMapImageViewType, componentMappingRGBA,
1516                                  densityMapSubresourceRange, densityMapImage, densityMapImageAlloc,
1517                                  densityMapImageView);
1518 
1519         m_densityMapImages.push_back(VkImageSp(new Unique<VkImage>(densityMapImage)));
1520         m_densityMapImageAllocs.push_back(AllocationSp(densityMapImageAlloc.release()));
1521         m_densityMapImageViews.push_back(VkImageViewSp(new Unique<VkImageView>(densityMapImageView)));
1522     }
1523 
1524     // Create and fill staging buffer, copy its data to density map image
1525     if (!m_testParams.dynamicDensityMap)
1526     {
1527         tcu::TextureFormat densityMapTextureFormat = vk::mapVkFormat(m_testParams.densityMapFormat);
1528         VkDeviceSize stagingBufferSize = tcu::getPixelSize(densityMapTextureFormat) * densityMapImageSize.width *
1529                                          densityMapImageSize.height * densityMapImageLayers;
1530         const vk::VkBufferCreateInfo stagingBufferCreateInfo{
1531             vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1532             DE_NULL,
1533             0u,                               // flags
1534             stagingBufferSize,                // size
1535             VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
1536             vk::VK_SHARING_MODE_EXCLUSIVE,    // sharingMode
1537             0u,                               // queueFamilyCount
1538             DE_NULL,                          // pQueueFamilyIndices
1539         };
1540         vk::Move<vk::VkBuffer> stagingBuffer = vk::createBuffer(vk, vkDevice, &stagingBufferCreateInfo);
1541         const vk::VkMemoryRequirements stagingRequirements =
1542             vk::getBufferMemoryRequirements(vk, vkDevice, *stagingBuffer);
1543         de::MovePtr<vk::Allocation> stagingAllocation =
1544             memAlloc.allocate(stagingRequirements, MemoryRequirement::HostVisible);
1545         VK_CHECK(vk.bindBufferMemory(vkDevice, *stagingBuffer, stagingAllocation->getMemory(),
1546                                      stagingAllocation->getOffset()));
1547         tcu::PixelBufferAccess stagingBufferAccess(densityMapTextureFormat, densityMapImageSize.width,
1548                                                    densityMapImageSize.height, densityMapImageLayers,
1549                                                    stagingAllocation->getHostPtr());
1550         tcu::Vec4 fragmentArea(m_densityValue.x(), m_densityValue.y(), 0.0f, 1.0f);
1551 
1552         for (uint32_t mapIndex = 0; mapIndex < densitiMapCount; ++mapIndex)
1553         {
1554             // Fill staging buffer with one color
1555             tcu::clear(stagingBufferAccess, fragmentArea);
1556             flushAlloc(vk, vkDevice, *stagingAllocation);
1557 
1558             copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *stagingBuffer, stagingBufferSize,
1559                               densityMapImageSize, densityMapImageLayers, **m_densityMapImages[mapIndex]);
1560 
1561             std::swap(fragmentArea.m_data[0], fragmentArea.m_data[1]);
1562         }
1563     }
1564 
1565     uint32_t samplerCreateFlags = (uint32_t)VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT;
1566     if (m_testParams.coarseReconstruction)
1567         samplerCreateFlags |= (uint32_t)VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT;
1568     if (m_testParams.nonSubsampledImages)
1569         samplerCreateFlags = 0u;
1570 
1571     const struct VkSamplerCreateInfo samplerInfo
1572     {
1573         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,        // sType
1574             DE_NULL,                                  // pNext
1575             (VkSamplerCreateFlags)samplerCreateFlags, // flags
1576             VK_FILTER_NEAREST,                        // magFilter
1577             VK_FILTER_NEAREST,                        // minFilter
1578             VK_SAMPLER_MIPMAP_MODE_NEAREST,           // mipmapMode
1579             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // addressModeU
1580             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // addressModeV
1581             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // addressModeW
1582             0.0f,                                     // mipLodBias
1583             VK_FALSE,                                 // anisotropyEnable
1584             1.0f,                                     // maxAnisotropy
1585             false,                                    // compareEnable
1586             VK_COMPARE_OP_ALWAYS,                     // compareOp
1587             0.0f,                                     // minLod
1588             0.0f,                                     // maxLod
1589             VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,  // borderColor
1590             VK_FALSE,                                 // unnormalizedCoords
1591     };
1592 
1593     // Create a sampler that are able to read from subsampled image
1594     // (more than one sampler is needed only for 4 maxDescriptorSetSubsampledSamplers tests)
1595     for (uint32_t samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1596         m_colorSamplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vk, vkDevice, &samplerInfo))));
1597 
1598     if (!isDynamicRendering)
1599     {
1600         // Create render passes
1601         if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1602             renderPassWrapper = RenderPassWrapperBasePtr(
1603                 new RenderPassWrapper<RENDERING_TYPE_RENDERPASS_LEGACY>(vk, vkDevice, testParams));
1604         else
1605             renderPassWrapper =
1606                 RenderPassWrapperBasePtr(new RenderPassWrapper<RENDERING_TYPE_RENDERPASS2>(vk, vkDevice, testParams));
1607 
1608         if (testParams.dynamicDensityMap)
1609             m_renderPassProduceDynamicDensityMap =
1610                 renderPassWrapper->createRenderPassProduceDynamicDensityMap(m_viewMask);
1611         m_renderPassProduceSubsampledImage =
1612             renderPassWrapper->createRenderPassProduceSubsampledImage(m_viewMask, testParams.makeCopy, false);
1613         if (testParams.subsampledLoads)
1614             m_renderPassUpdateSubsampledImage =
1615                 renderPassWrapper->createRenderPassProduceSubsampledImage(m_viewMask, false, true);
1616         m_renderPassOutputSubsampledImage = renderPassWrapper->createRenderPassOutputSubsampledImage();
1617 
1618         // Create framebuffers
1619         if (!testParams.imagelessFramebuffer)
1620         {
1621             if (testParams.dynamicDensityMap)
1622             {
1623                 m_framebufferProduceDynamicDensityMap =
1624                     createFrameBuffer(vk, vkDevice, *m_renderPassProduceDynamicDensityMap, densityMapImageSize,
1625                                       {**m_densityMapImageViews[0]});
1626             }
1627 
1628             std::vector<VkImageView> imageViewsProduceSubsampledImage = {*m_colorImageView};
1629             if (isColorImageMultisampled)
1630                 imageViewsProduceSubsampledImage.push_back(*m_colorResolvedImageView);
1631             if (testParams.makeCopy)
1632                 imageViewsProduceSubsampledImage.push_back(*m_colorCopyImageView);
1633             imageViewsProduceSubsampledImage.push_back(**m_densityMapImageViews[0]);
1634 
1635             m_framebufferProduceSubsampledImage = createFrameBuffer(vk, vkDevice, *m_renderPassProduceSubsampledImage,
1636                                                                     colorImageSize, imageViewsProduceSubsampledImage);
1637 
1638             if (testParams.subsampledLoads)
1639             {
1640                 m_framebufferUpdateSubsampledImage =
1641                     createFrameBuffer(vk, vkDevice, *m_renderPassUpdateSubsampledImage, colorImageSize,
1642                                       {*m_colorImageView, **m_densityMapImageViews[1]});
1643             }
1644 
1645             m_framebufferOutputSubsampledImage = createFrameBuffer(vk, vkDevice, *m_renderPassOutputSubsampledImage,
1646                                                                    outputImageSize, {*m_outputImageView});
1647         }
1648         else // create same framebuffers as above but with VkFramebufferAttachmentsCreateInfo instead of image views
1649         {
1650             // helper lambda used to create VkFramebufferAttachmentImageInfo structure and reduce code size
1651             auto createFramebufferAttachmentImageInfo = [](VkImageCreateFlags createFlags, VkImageUsageFlags usageFlags,
1652                                                            VkExtent3D &extent, uint32_t layerCount,
1653                                                            const VkFormat *format)
1654             {
1655                 return VkFramebufferAttachmentImageInfo{
1656                     VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1657                     DE_NULL,                                             // const void* pNext;
1658                     createFlags,                                         // VkImageCreateFlags flags;
1659                     usageFlags,                                          // VkImageUsageFlags usage;
1660                     extent.width,                                        // uint32_t width;
1661                     extent.height,                                       // uint32_t height;
1662                     layerCount,                                          // uint32_t layerCount;
1663                     1u,                                                  // uint32_t viewFormatCount;
1664                     format                                               // const VkFormat* pViewFormats;
1665                 };
1666             };
1667 
1668             if (testParams.dynamicDensityMap)
1669             {
1670                 m_framebufferProduceDynamicDensityMap = createImagelessFrameBuffer(
1671                     vk, vkDevice, *m_renderPassProduceDynamicDensityMap, densityMapImageSize,
1672                     {createFramebufferAttachmentImageInfo(0u, densityMapImageUsage, densityMapImageSize,
1673                                                           densityMapImageLayers, &m_testParams.densityMapFormat)});
1674             }
1675 
1676             std::vector<VkFramebufferAttachmentImageInfo> attachmentInfoProduceSubsampledImage;
1677             attachmentInfoProduceSubsampledImage.reserve(4);
1678             attachmentInfoProduceSubsampledImage.push_back(
1679                 createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags, colorImageUsage,
1680                                                      colorImageSize, colorImageLayers, &colorImageFormat));
1681             if (isColorImageMultisampled)
1682             {
1683                 attachmentInfoProduceSubsampledImage.push_back(createFramebufferAttachmentImageInfo(
1684                     (VkImageCreateFlags)colorImageCreateFlags,
1685                     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, colorImageSize, colorImageLayers,
1686                     &colorImageFormat));
1687             }
1688             if (testParams.makeCopy)
1689             {
1690                 attachmentInfoProduceSubsampledImage.push_back(createFramebufferAttachmentImageInfo(
1691                     (VkImageCreateFlags)colorImageCreateFlags,
1692                     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, colorImageSize, colorImageLayers,
1693                     &colorImageFormat));
1694             }
1695             attachmentInfoProduceSubsampledImage.push_back(
1696                 createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags, colorImageUsage,
1697                                                      colorImageSize, colorImageLayers, &colorImageFormat));
1698 
1699             m_framebufferProduceSubsampledImage =
1700                 createImagelessFrameBuffer(vk, vkDevice, *m_renderPassProduceSubsampledImage, colorImageSize,
1701                                            attachmentInfoProduceSubsampledImage);
1702 
1703             if (testParams.subsampledLoads)
1704             {
1705                 m_framebufferUpdateSubsampledImage = createImagelessFrameBuffer(
1706                     vk, vkDevice, *m_renderPassUpdateSubsampledImage, colorImageSize,
1707                     {createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags, colorImageUsage,
1708                                                           colorImageSize, colorImageLayers, &colorImageFormat),
1709                      createFramebufferAttachmentImageInfo(0u, densityMapImageUsage, densityMapImageSize,
1710                                                           densityMapImageLayers, &m_testParams.densityMapFormat)});
1711             }
1712 
1713             m_framebufferOutputSubsampledImage = createImagelessFrameBuffer(
1714                 vk, vkDevice, *m_renderPassOutputSubsampledImage, outputImageSize,
1715                 {createFramebufferAttachmentImageInfo(
1716                     0u, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, outputImageSize, 1u,
1717                     &colorImageFormat)});
1718         }
1719     }
1720 
1721     // Create pipeline layout for subpasses that do not use any descriptors
1722     {
1723         const VkPipelineLayoutCreateInfo pipelineLayoutParams{
1724             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1725             DE_NULL,                                       // const void* pNext;
1726             0u,                                            // VkPipelineLayoutCreateFlags flags;
1727             0u,                                            // uint32_t setLayoutCount;
1728             DE_NULL,                                       // const VkDescriptorSetLayout* pSetLayouts;
1729             0u,                                            // uint32_t pushConstantRangeCount;
1730             DE_NULL                                        // const VkPushConstantRange* pPushConstantRanges;
1731         };
1732 
1733         m_pipelineLayoutNoDescriptors = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1734     }
1735 
1736     // Create pipeline layout for subpass that copies data or resamples subsampled image
1737     if (m_testParams.makeCopy || m_testParams.subsampledLoads)
1738     {
1739         m_descriptorSetLayoutOperateOnSubsampledImage =
1740             DescriptorSetLayoutBuilder()
1741                 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
1742                 .build(vk, vkDevice);
1743 
1744         // Create and bind descriptor set
1745         m_descriptorPoolOperateOnSubsampledImage =
1746             DescriptorPoolBuilder()
1747                 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
1748                 .build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1749 
1750         m_pipelineLayoutOperateOnSubsampledImage =
1751             makePipelineLayout(vk, vkDevice, *m_descriptorSetLayoutOperateOnSubsampledImage);
1752         m_descriptorSetOperateOnSubsampledImage = makeDescriptorSet(
1753             vk, vkDevice, *m_descriptorPoolOperateOnSubsampledImage, *m_descriptorSetLayoutOperateOnSubsampledImage);
1754 
1755         const VkDescriptorImageInfo inputImageInfo = {
1756             DE_NULL,                                 // VkSampleri sampler;
1757             *m_colorImageView,                       // VkImageView imageView;
1758             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
1759         };
1760         DescriptorSetUpdateBuilder()
1761             .writeSingle(*m_descriptorSetOperateOnSubsampledImage, DescriptorSetUpdateBuilder::Location::binding(0u),
1762                          VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &inputImageInfo)
1763             .update(vk, vkDevice);
1764     }
1765 
1766     // Create pipeline layout for last render pass (output subsampled image)
1767     {
1768         DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1769         DescriptorPoolBuilder descriptorPoolBuilder;
1770         for (uint32_t samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1771         {
1772             descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1773                                                                VK_SHADER_STAGE_FRAGMENT_BIT,
1774                                                                &(*m_colorSamplers[samplerIndex]).get());
1775             descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, samplerIndex + 1u);
1776         }
1777 
1778         m_descriptorSetLayoutOutputSubsampledImage = descriptorSetLayoutBuilder.build(vk, vkDevice);
1779         m_descriptorPoolOutputSubsampledImage =
1780             descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1781         m_pipelineLayoutOutputSubsampledImage =
1782             makePipelineLayout(vk, vkDevice, *m_descriptorSetLayoutOutputSubsampledImage);
1783         m_descriptorSetOutputSubsampledImage = makeDescriptorSet(vk, vkDevice, *m_descriptorPoolOutputSubsampledImage,
1784                                                                  *m_descriptorSetLayoutOutputSubsampledImage);
1785 
1786         VkImageView srcImageView = *m_colorImageView;
1787         if (isColorImageMultisampled)
1788             srcImageView = *m_colorResolvedImageView;
1789         else if (m_testParams.makeCopy)
1790             srcImageView = *m_colorCopyImageView;
1791 
1792         const VkDescriptorImageInfo inputImageInfo{
1793             DE_NULL,                                 // VkSampleri sampler;
1794             srcImageView,                            // VkImageView imageView;
1795             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
1796         };
1797 
1798         DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
1799         for (uint32_t samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1800             descriptorSetUpdateBuilder.writeSingle(*m_descriptorSetOutputSubsampledImage,
1801                                                    DescriptorSetUpdateBuilder::Location::binding(samplerIndex),
1802                                                    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &inputImageInfo);
1803         descriptorSetUpdateBuilder.update(vk, vkDevice);
1804     }
1805 
1806     // Load vertex and fragment shaders
1807     auto &bc                   = m_context.getBinaryCollection();
1808     m_vertexCommonShaderModule = createShaderModule(vk, vkDevice, bc.get("vert"), 0);
1809     m_fragmentShaderModuleProduceSubsampledImage =
1810         createShaderModule(vk, vkDevice, bc.get("frag_produce_subsampled"), 0);
1811     if (m_testParams.makeCopy)
1812     {
1813         const char *moduleName = isColorImageMultisampled ? "frag_copy_subsampled_ms" : "frag_copy_subsampled";
1814         m_fragmentShaderModuleCopySubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1815     }
1816     if (m_testParams.subsampledLoads)
1817     {
1818         const char *moduleName                      = "frag_update_subsampled";
1819         m_fragmentShaderModuleUpdateSubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1820     }
1821     const char *moduleName = (m_testParams.viewCount > 1) ? "frag_output_2darray" : "frag_output_2d";
1822     m_fragmentShaderModuleOutputSubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1823 
1824     const std::vector<VkRect2D> dynamicDensityMapRenderArea{
1825         makeRect2D(densityMapImageSize.width, densityMapImageSize.height)};
1826     const std::vector<VkRect2D> outputRenderArea{makeRect2D(outputImageSize.width, outputImageSize.height)};
1827     const VkRect2D colorImageRect = makeRect2D(colorImageSize.width, colorImageSize.height);
1828     std::vector<VkRect2D> colorImageRenderArea((m_testParams.multiViewport ? m_testParams.viewCount : 1u),
1829                                                colorImageRect);
1830 
1831     // Create pipelines
1832     {
1833         const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo{
1834             VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                            sType
1835             DE_NULL,                                   // const void*                                pNext
1836             (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags    flags
1837             (VkSampleCountFlagBits)
1838                 m_testParams.colorSamples, // VkSampleCountFlagBits                    rasterizationSamples
1839             VK_FALSE,                      // VkBool32                                    sampleShadingEnable
1840             1.0f,                          // float                                    minSampleShading
1841             DE_NULL,                       // const VkSampleMask*                        pSampleMask
1842             VK_FALSE,                      // VkBool32                                    alphaToCoverageEnable
1843             VK_FALSE                       // VkBool32                                    alphaToOneEnable
1844         };
1845 
1846         const std::vector<VkViewport> viewportsProduceDynamicDensityMap{
1847             makeViewport(densityMapImageSize.width, densityMapImageSize.height)};
1848         const std::vector<VkViewport> viewportsOutputSubsampledImage{
1849             makeViewport(outputImageSize.width, outputImageSize.height)};
1850         std::vector<VkViewport> viewportsSubsampledImage(colorImageRenderArea.size(),
1851                                                          makeViewport(colorImageSize.width, colorImageSize.height));
1852 
1853         // test multiview in conjunction with multiViewport which specifies a different viewport per view
1854         if (m_testParams.multiViewport)
1855         {
1856             const uint32_t halfWidth    = colorImageSize.width / 2u;
1857             const float halfWidthFloat  = static_cast<float>(halfWidth);
1858             const float halfHeightFloat = static_cast<float>(colorImageSize.height / 2u);
1859             for (uint32_t viewIndex = 0; viewIndex < m_testParams.viewCount; ++viewIndex)
1860             {
1861                 // modify scissors/viewport for every other view
1862                 bool isOdd = viewIndex % 2;
1863 
1864                 auto &rect        = colorImageRenderArea[viewIndex];
1865                 rect.extent.width = halfWidth;
1866                 rect.offset.x     = isOdd * halfWidth;
1867 
1868                 auto &viewport  = viewportsSubsampledImage[viewIndex];
1869                 viewport.width  = halfWidthFloat;
1870                 viewport.height = halfHeightFloat;
1871                 viewport.y      = !isOdd * halfHeightFloat;
1872                 viewport.x      = isOdd * halfWidthFloat;
1873             }
1874         }
1875 
1876         uint32_t colorAttachmentLocations[] = {VK_ATTACHMENT_UNUSED, 0};
1877         VkFormat colorImageFormats[]        = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM};
1878         VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo{
1879             VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR, DE_NULL, 2, colorAttachmentLocations};
1880         std::vector<VkPipelineRenderingCreateInfoKHR> renderingCreateInfo(
1881             5, {VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, DE_NULL, m_viewMask, 1u,
1882                 &m_testParams.densityMapFormat, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED});
1883         renderingCreateInfo[1].pColorAttachmentFormats = &colorImageFormat;
1884         renderingCreateInfo[3].pColorAttachmentFormats = &colorImageFormat;
1885         renderingCreateInfo[4].viewMask                = 0;
1886         renderingCreateInfo[4].pColorAttachmentFormats = &colorImageFormat;
1887 
1888         if (m_testParams.makeCopy)
1889         {
1890             renderingCreateInfo[1].colorAttachmentCount    = 2u;
1891             renderingCreateInfo[1].pColorAttachmentFormats = colorImageFormats;
1892 
1893             renderingCreateInfo[2].pNext                   = &renderingAttachmentLocationInfo;
1894             renderingCreateInfo[2].colorAttachmentCount    = 2u;
1895             renderingCreateInfo[2].pColorAttachmentFormats = colorImageFormats;
1896         }
1897 
1898         const void *pNextForProduceDynamicDensityMap = (isDynamicRendering ? &renderingCreateInfo[0] : DE_NULL);
1899         const void *pNextForProduceSubsampledImage   = (isDynamicRendering ? &renderingCreateInfo[1] : DE_NULL);
1900         const void *pNextForCopySubsampledImage      = (isDynamicRendering ? &renderingCreateInfo[2] : DE_NULL);
1901         const void *pNextForUpdateSubsampledImage    = (isDynamicRendering ? &renderingCreateInfo[3] : DE_NULL);
1902         const void *pNextForOutputSubsampledImage    = (isDynamicRendering ? &renderingCreateInfo[4] : DE_NULL);
1903 
1904         if (testParams.dynamicDensityMap)
1905             m_graphicsPipelineProduceDynamicDensityMap = buildGraphicsPipeline(
1906                 vk,                             // const DeviceInterface&                            vk
1907                 vkDevice,                       // const VkDevice                                    device
1908                 *m_pipelineLayoutNoDescriptors, // const VkPipelineLayout                            pipelineLayout
1909                 *m_vertexCommonShaderModule, // const VkShaderModule                                vertexShaderModule
1910                 *m_fragmentShaderModuleProduceSubsampledImage, // const VkShaderModule                                fragmentShaderModule
1911                 *m_renderPassProduceDynamicDensityMap, // const VkRenderPass                                renderPass
1912                 viewportsProduceDynamicDensityMap,     // const std::vector<VkViewport>&                    viewport
1913                 dynamicDensityMapRenderArea,           // const std::vector<VkRect2D>&                        scissor
1914                 0u,                                    // const uint32_t                                    subpass
1915                 DE_NULL, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1916                 pNextForProduceDynamicDensityMap, // const void*                                        pNext
1917                 isDynamicRendering, // const bool                                        useDensityMapAttachment
1918                 m_testParams.useMaintenance5); // const bool                                        useMaintenance5
1919 
1920         m_graphicsPipelineProduceSubsampledImage = buildGraphicsPipeline(
1921             vk,                             // const DeviceInterface&                            vk
1922             vkDevice,                       // const VkDevice                                    device
1923             *m_pipelineLayoutNoDescriptors, // const VkPipelineLayout                            pipelineLayout
1924             *m_vertexCommonShaderModule,    // const VkShaderModule                                vertexShaderModule
1925             *m_fragmentShaderModuleProduceSubsampledImage, // const VkShaderModule                                fragmentShaderModule
1926             *m_renderPassProduceSubsampledImage, // const VkRenderPass                                renderPass
1927             viewportsSubsampledImage,            // const std::vector<VkViewport>&                    viewport
1928             colorImageRenderArea,                // const std::vector<VkRect2D>&                        scissor
1929             0u,                                  // const uint32_t                                    subpass
1930             &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1931             pNextForProduceSubsampledImage, // const void*                                        pNext
1932             isDynamicRendering,             // const bool                                        useDensityMapAttachment
1933             m_testParams.useMaintenance5);  // const bool                                        useMaintenance5
1934 
1935         if (m_testParams.makeCopy)
1936             m_graphicsPipelineCopySubsampledImage = buildGraphicsPipeline(
1937                 vk,                                        // const DeviceInterface&                            vk
1938                 vkDevice,                                  // const VkDevice                                    device
1939                 *m_pipelineLayoutOperateOnSubsampledImage, // const VkPipelineLayout                            pipelineLayout
1940                 *m_vertexCommonShaderModule, // const VkShaderModule                                vertexShaderModule
1941                 *m_fragmentShaderModuleCopySubsampledImage, // const VkShaderModule                                fragmentShaderModule
1942                 *m_renderPassProduceSubsampledImage, // const VkRenderPass                                renderPass
1943                 viewportsSubsampledImage,            // const std::vector<VkViewport>&                    viewport
1944                 colorImageRenderArea,                // const std::vector<VkRect2D>&                        scissor
1945                 1u,                                  // const uint32_t                                    subpass
1946                 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1947                 pNextForCopySubsampledImage, // const void*                                        pNext
1948                 false); // const bool                                        useDensityMapAttachment
1949         if (m_testParams.subsampledLoads)
1950             m_graphicsPipelineUpdateSubsampledImage = buildGraphicsPipeline(
1951                 vk,                                        // const DeviceInterface&                            vk
1952                 vkDevice,                                  // const VkDevice                                    device
1953                 *m_pipelineLayoutOperateOnSubsampledImage, // const VkPipelineLayout                            pipelineLayout
1954                 *m_vertexCommonShaderModule, // const VkShaderModule                                vertexShaderModule
1955                 *m_fragmentShaderModuleUpdateSubsampledImage, // const VkShaderModule                                fragmentShaderModule
1956                 *m_renderPassUpdateSubsampledImage, // const VkRenderPass                                renderPass
1957                 viewportsSubsampledImage,           // const std::vector<VkViewport>&                    viewport
1958                 colorImageRenderArea,               // const std::vector<VkRect2D>&                        scissor
1959                 0u,                                 // const uint32_t                                    subpass
1960                 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1961                 pNextForUpdateSubsampledImage, // const void*                                        pNext
1962                 isDynamicRendering, // const bool                                        useDensityMapAttachment
1963                 m_testParams.useMaintenance5); // const bool                                        useMaintenance5
1964 
1965         m_graphicsPipelineOutputSubsampledImage = buildGraphicsPipeline(
1966             vk,                                     // const DeviceInterface&                            vk
1967             vkDevice,                               // const VkDevice                                    device
1968             *m_pipelineLayoutOutputSubsampledImage, // const VkPipelineLayout                            pipelineLayout
1969             *m_vertexCommonShaderModule, // const VkShaderModule                                vertexShaderModule
1970             *m_fragmentShaderModuleOutputSubsampledImage, // const VkShaderModule                                fragmentShaderModule
1971             *m_renderPassOutputSubsampledImage, // const VkRenderPass                                renderPass
1972             viewportsOutputSubsampledImage,     // const std::vector<VkViewport>&                    viewport
1973             outputRenderArea,                   // const std::vector<VkRect2D>&                        scissor
1974             0u,                                 // const uint32_t                                    subpass
1975             DE_NULL, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1976             pNextForOutputSubsampledImage, // const void*                                        pNext
1977             false);                        // const bool                                        useDensityMapAttachment
1978     }
1979 
1980     // Create vertex buffers
1981     const tcu::Vec2 densityX(m_densityValue.x());
1982     const tcu::Vec2 densityY(m_densityValue.y());
1983     m_vertices = createFullscreenMesh(1, {0.0f, 1.0f}, {0.0f, 1.0f}); // create fullscreen quad with gradient
1984     if (testParams.dynamicDensityMap)
1985         m_verticesDDM = createFullscreenMesh(1, densityX, densityY); // create fullscreen quad with single color
1986     m_verticesOutput = createFullscreenMesh(m_testParams.viewCount, {0.0f, 0.0f},
1987                                             {0.0f, 0.0f}); // create fullscreen mesh with black color
1988 
1989     createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_vertices, m_vertexBuffer, m_vertexBufferAlloc);
1990     if (testParams.dynamicDensityMap)
1991         createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_verticesDDM, m_vertexBufferDDM,
1992                            m_vertexBufferAllocDDM);
1993     createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_verticesOutput, m_vertexBufferOutput,
1994                        m_vertexBufferOutputAlloc);
1995 
1996     // Create command pool and command buffer
1997     m_cmdPool   = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1998     m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1999 
2000     if (isDynamicRendering)
2001         createCommandBufferForDynamicRendering(dynamicDensityMapRenderArea[0], colorImageRect, outputRenderArea[0],
2002                                                vkDevice);
2003     else
2004         createCommandBufferForRenderpass(renderPassWrapper, colorImageSize, dynamicDensityMapRenderArea[0],
2005                                          colorImageRect, outputRenderArea[0]);
2006 }
2007 
drawDynamicDensityMap(VkCommandBuffer cmdBuffer)2008 void FragmentDensityMapTestInstance::drawDynamicDensityMap(VkCommandBuffer cmdBuffer)
2009 {
2010     const DeviceInterface &vk             = m_context.getDeviceInterface();
2011     const VkDeviceSize vertexBufferOffset = 0;
2012 
2013     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceDynamicDensityMap);
2014     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBufferDDM.get(), &vertexBufferOffset);
2015     vk.cmdDraw(cmdBuffer, (uint32_t)m_verticesDDM.size(), 1, 0, 0);
2016 }
2017 
drawSubsampledImage(VkCommandBuffer cmdBuffer)2018 void FragmentDensityMapTestInstance::drawSubsampledImage(VkCommandBuffer cmdBuffer)
2019 {
2020     const DeviceInterface &vk             = m_context.getDeviceInterface();
2021     const VkDeviceSize vertexBufferOffset = 0;
2022 
2023     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceSubsampledImage);
2024     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2025     vk.cmdDraw(cmdBuffer, (uint32_t)m_vertices.size(), 1, 0, 0);
2026 }
2027 
drawCopySubsampledImage(VkCommandBuffer cmdBuffer)2028 void FragmentDensityMapTestInstance::drawCopySubsampledImage(VkCommandBuffer cmdBuffer)
2029 {
2030     const DeviceInterface &vk             = m_context.getDeviceInterface();
2031     const VkDeviceSize vertexBufferOffset = 0;
2032 
2033     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineCopySubsampledImage);
2034     vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOperateOnSubsampledImage, 0,
2035                              1, &m_descriptorSetOperateOnSubsampledImage.get(), 0, DE_NULL);
2036     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2037     vk.cmdDraw(cmdBuffer, (uint32_t)m_vertices.size(), 1, 0, 0);
2038 }
2039 
drawResampleSubsampledImage(VkCommandBuffer cmdBuffer)2040 void FragmentDensityMapTestInstance::drawResampleSubsampledImage(VkCommandBuffer cmdBuffer)
2041 {
2042     const DeviceInterface &vk             = m_context.getDeviceInterface();
2043     const VkDeviceSize vertexBufferOffset = 0;
2044 
2045     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineUpdateSubsampledImage);
2046     vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOperateOnSubsampledImage, 0,
2047                              1, &m_descriptorSetOperateOnSubsampledImage.get(), 0, DE_NULL);
2048     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2049     vk.cmdDraw(cmdBuffer, (uint32_t)m_vertices.size(), 1, 0, 0);
2050 }
2051 
drawOutputSubsampledImage(VkCommandBuffer cmdBuffer)2052 void FragmentDensityMapTestInstance::drawOutputSubsampledImage(VkCommandBuffer cmdBuffer)
2053 {
2054     const DeviceInterface &vk             = m_context.getDeviceInterface();
2055     const VkDeviceSize vertexBufferOffset = 0;
2056 
2057     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineOutputSubsampledImage);
2058     vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOutputSubsampledImage, 0, 1,
2059                              &m_descriptorSetOutputSubsampledImage.get(), 0, DE_NULL);
2060     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBufferOutput.get(), &vertexBufferOffset);
2061     vk.cmdDraw(cmdBuffer, (uint32_t)m_verticesOutput.size(), 1, 0, 0);
2062 }
2063 
remapingBeforeCopySubsampledImage(VkCommandBuffer cmdBuffer)2064 void FragmentDensityMapTestInstance::remapingBeforeCopySubsampledImage(VkCommandBuffer cmdBuffer)
2065 {
2066     const DeviceInterface &vk = m_context.getDeviceInterface();
2067 
2068     // Barier before next subpass
2069     VkMemoryBarrier memoryBarrier =
2070         makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
2071     vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2072                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &memoryBarrier, 0,
2073                           DE_NULL, 0, DE_NULL);
2074 
2075     // color attachment remaping
2076     uint32_t colorAttachmentLocations[] = {VK_ATTACHMENT_UNUSED, 0};
2077     VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo{
2078         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR, DE_NULL, 2, colorAttachmentLocations};
2079     vk.cmdSetRenderingAttachmentLocationsKHR(cmdBuffer, &renderingAttachmentLocationInfo);
2080 }
2081 
createCommandBufferForRenderpass(RenderPassWrapperBasePtr renderPassWrapper,const VkExtent3D & colorImageSize,const VkRect2D & dynamicDensityMapRenderArea,const VkRect2D & colorImageRenderArea,const VkRect2D & outputRenderArea)2082 void FragmentDensityMapTestInstance::createCommandBufferForRenderpass(RenderPassWrapperBasePtr renderPassWrapper,
2083                                                                       const VkExtent3D &colorImageSize,
2084                                                                       const VkRect2D &dynamicDensityMapRenderArea,
2085                                                                       const VkRect2D &colorImageRenderArea,
2086                                                                       const VkRect2D &outputRenderArea)
2087 {
2088     const DeviceInterface &vk               = m_context.getDeviceInterface();
2089     const VkDevice vkDevice                 = getDevice(m_context);
2090     const bool isColorImageMultisampled     = m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
2091     const VkClearValue attachmentClearValue = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f);
2092     const uint32_t attachmentCount          = 1 + m_testParams.makeCopy + isColorImageMultisampled;
2093     const std::vector<VkClearValue> attachmentClearValues(attachmentCount, attachmentClearValue);
2094 
2095     if (m_testParams.groupParams->useSecondaryCmdBuffer)
2096     {
2097         VkCommandBufferInheritanceInfo bufferInheritanceInfo{
2098             VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
2099             DE_NULL,                                           // const void* pNext;
2100             *m_renderPassProduceDynamicDensityMap,             // VkRenderPass renderPass;
2101             0,                                                 // uint32_t subpass;
2102             *m_framebufferProduceDynamicDensityMap,            // VkFramebuffer framebuffer;
2103             false,                                             // VkBool32 occlusionQueryEnable;
2104             0u,                                                // VkQueryControlFlags queryFlags;
2105             DE_NULL,                                           // VkQueryPipelineStatisticFlags pipelineStatistics;
2106         };
2107         const VkCommandBufferBeginInfo commandBufBeginParams{
2108             VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2109             DE_NULL,                                     // const void* pNext;
2110             VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
2111                 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // VkCommandBufferUsageFlags flags;
2112             &bufferInheritanceInfo};
2113 
2114         if (m_testParams.dynamicDensityMap)
2115         {
2116             m_dynamicDensityMapSecCmdBuffer =
2117                 allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2118             vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2119             drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2120             endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2121         }
2122 
2123         bufferInheritanceInfo.renderPass  = *m_renderPassProduceSubsampledImage;
2124         bufferInheritanceInfo.framebuffer = *m_framebufferProduceSubsampledImage;
2125         m_subsampledImageSecCmdBuffer =
2126             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2127         vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2128         drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2129         if (m_testParams.makeCopy)
2130         {
2131             renderPassWrapper->cmdNextSubpass(*m_subsampledImageSecCmdBuffer);
2132             drawCopySubsampledImage(*m_subsampledImageSecCmdBuffer);
2133         }
2134         endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2135 
2136         if (m_testParams.subsampledLoads)
2137         {
2138             bufferInheritanceInfo.renderPass  = *m_renderPassUpdateSubsampledImage;
2139             bufferInheritanceInfo.framebuffer = *m_framebufferUpdateSubsampledImage;
2140             m_resampleSubsampledImageSecCmdBuffer =
2141                 allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2142             vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2143             drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2144             endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2145         }
2146 
2147         bufferInheritanceInfo.renderPass  = *m_renderPassOutputSubsampledImage;
2148         bufferInheritanceInfo.framebuffer = *m_framebufferOutputSubsampledImage;
2149         m_outputSubsampledImageSecCmdBuffer =
2150             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2151         vk.beginCommandBuffer(*m_outputSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2152         drawOutputSubsampledImage(*m_outputSubsampledImageSecCmdBuffer);
2153         endCommandBuffer(vk, *m_outputSubsampledImageSecCmdBuffer);
2154     }
2155 
2156     beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2157 
2158     // First render pass - render dynamic density map
2159     if (m_testParams.dynamicDensityMap)
2160     {
2161         std::vector<VkClearValue> attachmentClearValuesDDM{makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f)};
2162 
2163         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo{
2164             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2165             DE_NULL,                                             // const void* pNext;
2166             1u,                                                  // uint32_t attachmentCount;
2167             &**m_densityMapImageViews[0]                         // const VkImageView* pAttachments;
2168         };
2169 
2170         const VkRenderPassBeginInfo renderPassBeginInfoProduceDynamicDensityMap{
2171             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                     // VkStructureType sType;
2172             m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL, // const void* pNext;
2173             *m_renderPassProduceDynamicDensityMap,                                        // VkRenderPass renderPass;
2174             *m_framebufferProduceDynamicDensityMap,                                       // VkFramebuffer framebuffer;
2175             dynamicDensityMapRenderArea,                                                  // VkRect2D renderArea;
2176             static_cast<uint32_t>(attachmentClearValuesDDM.size()),                       // uint32_t clearValueCount;
2177             attachmentClearValuesDDM.data() // const VkClearValue* pClearValues;
2178         };
2179 
2180         renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoProduceDynamicDensityMap);
2181 
2182         if (m_testParams.groupParams->useSecondaryCmdBuffer)
2183             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2184         else
2185             drawDynamicDensityMap(*m_cmdBuffer);
2186 
2187         renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2188     }
2189 
2190     // Render subsampled image
2191     {
2192         std::vector<VkImageView> imageViewsProduceSubsampledImage = {*m_colorImageView};
2193         if (isColorImageMultisampled)
2194             imageViewsProduceSubsampledImage.push_back(*m_colorResolvedImageView);
2195         if (m_testParams.makeCopy)
2196             imageViewsProduceSubsampledImage.push_back(*m_colorCopyImageView);
2197         imageViewsProduceSubsampledImage.push_back(**m_densityMapImageViews[0]);
2198 
2199         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo{
2200             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,            // VkStructureType sType;
2201             DE_NULL,                                                        // const void* pNext;
2202             static_cast<uint32_t>(imageViewsProduceSubsampledImage.size()), // uint32_t attachmentCount;
2203             imageViewsProduceSubsampledImage.data()                         // const VkImageView* pAttachments;
2204         };
2205 
2206         const VkRenderPassBeginInfo renderPassBeginInfoProduceSubsampledImage{
2207             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                     // VkStructureType sType;
2208             m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL, // const void* pNext;
2209             *m_renderPassProduceSubsampledImage,                                          // VkRenderPass renderPass;
2210             *m_framebufferProduceSubsampledImage,                                         // VkFramebuffer framebuffer;
2211             colorImageRenderArea,                                                         // VkRect2D renderArea;
2212             static_cast<uint32_t>(attachmentClearValues.size()),                          // uint32_t clearValueCount;
2213             attachmentClearValues.data() // const VkClearValue* pClearValues;
2214         };
2215         renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoProduceSubsampledImage);
2216 
2217         if (m_testParams.groupParams->useSecondaryCmdBuffer)
2218             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2219         else
2220         {
2221             drawSubsampledImage(*m_cmdBuffer);
2222             if (m_testParams.makeCopy)
2223             {
2224                 renderPassWrapper->cmdNextSubpass(*m_cmdBuffer);
2225                 drawCopySubsampledImage(*m_cmdBuffer);
2226             }
2227         }
2228 
2229         renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2230     }
2231 
2232     // Resample subsampled image
2233     if (m_testParams.subsampledLoads)
2234     {
2235         VkImageView pAttachments[] = {*m_colorImageView, **m_densityMapImageViews[1]};
2236         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo{
2237             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2238             DE_NULL,                                             // const void* pNext;
2239             2u,                                                  // uint32_t attachmentCount;
2240             pAttachments                                         // const VkImageView* pAttachments;
2241         };
2242 
2243         const VkRenderPassBeginInfo renderPassBeginInfoUpdateSubsampledImage{
2244             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                     // VkStructureType sType;
2245             m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL, // const void* pNext;
2246             *m_renderPassUpdateSubsampledImage,                                           // VkRenderPass renderPass;
2247             *m_framebufferUpdateSubsampledImage,                                          // VkFramebuffer framebuffer;
2248             makeRect2D(colorImageSize.width, colorImageSize.height),                      // VkRect2D renderArea;
2249             0u,                                                                           // uint32_t clearValueCount;
2250             DE_NULL // const VkClearValue* pClearValues;
2251         };
2252         renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoUpdateSubsampledImage);
2253 
2254         if (m_testParams.groupParams->useSecondaryCmdBuffer)
2255             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2256         else
2257             drawResampleSubsampledImage(*m_cmdBuffer);
2258 
2259         renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2260     }
2261 
2262     // Copy subsampled image to normal image using sampler that is able to read from subsampled images
2263     // (subsampled image cannot be copied using vkCmdCopyImageToBuffer)
2264     const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo{
2265         VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2266         DE_NULL,                                             // const void* pNext;
2267         1u,                                                  // uint32_t attachmentCount;
2268         &*m_outputImageView                                  // const VkImageView* pAttachments;
2269     };
2270 
2271     const VkRenderPassBeginInfo renderPassBeginInfoOutputSubsampledImage{
2272         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                     // VkStructureType sType;
2273         m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL, // const void* pNext;
2274         *m_renderPassOutputSubsampledImage,                                           // VkRenderPass renderPass;
2275         *m_framebufferOutputSubsampledImage,                                          // VkFramebuffer framebuffer;
2276         outputRenderArea,                                                             // VkRect2D renderArea;
2277         static_cast<uint32_t>(attachmentClearValues.size()),                          // uint32_t clearValueCount;
2278         attachmentClearValues.data() // const VkClearValue* pClearValues;
2279     };
2280     renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoOutputSubsampledImage);
2281 
2282     if (m_testParams.groupParams->useSecondaryCmdBuffer)
2283         vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_outputSubsampledImageSecCmdBuffer);
2284     else
2285         drawOutputSubsampledImage(*m_cmdBuffer);
2286 
2287     renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2288 
2289     endCommandBuffer(vk, *m_cmdBuffer);
2290 }
2291 
createCommandBufferForDynamicRendering(const VkRect2D & dynamicDensityMapRenderArea,const VkRect2D & colorImageRenderArea,const VkRect2D & outputRenderArea,const VkDevice & vkDevice)2292 void FragmentDensityMapTestInstance::createCommandBufferForDynamicRendering(const VkRect2D &dynamicDensityMapRenderArea,
2293                                                                             const VkRect2D &colorImageRenderArea,
2294                                                                             const VkRect2D &outputRenderArea,
2295                                                                             const VkDevice &vkDevice)
2296 {
2297     const DeviceInterface &vk           = m_context.getDeviceInterface();
2298     const bool isColorImageMultisampled = m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
2299     std::vector<VkClearValue> attachmentClearValuesDDM{makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f)};
2300     const VkClearValue attachmentClearValue = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f);
2301     const uint32_t attachmentCount          = 1 + m_testParams.makeCopy + isColorImageMultisampled;
2302     const std::vector<VkClearValue> attachmentClearValues(attachmentCount, attachmentClearValue);
2303     const VkImageSubresourceRange dynamicDensitMapSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u,
2304                                                                    m_testParams.viewCount, 0u, 1u};
2305     const VkImageSubresourceRange colorSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_testParams.viewCount};
2306     const VkImageSubresourceRange outputSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
2307 
2308     const VkImageMemoryBarrier dynamicDensitMapBarrier = makeImageMemoryBarrier(
2309         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT :
2310                                        VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT, // VkAccessFlags srcAccessMask;
2311         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT :
2312                                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2313         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,                    // VkImageLayout oldLayout;
2314         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                            // VkImageLayout newLayout;
2315         **m_densityMapImages[0],                                             // VkImage image;
2316         dynamicDensitMapSubresourceRange // VkImageSubresourceRange subresourceRange;
2317     );
2318 
2319     const VkImageMemoryBarrier densityMapImageBarrier = makeImageMemoryBarrier(
2320         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT :
2321                                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
2322         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT :
2323                                        VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT, // VkAccessFlags dstAccessMask;
2324         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                   // VkImageLayout oldLayout;
2325         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,                           // VkImageLayout newLayout;
2326         **m_densityMapImages[0],                                                    // VkImage image;
2327         colorSubresourceRange // VkImageSubresourceRange subresourceRange;
2328     );
2329 
2330     std::vector<VkImageMemoryBarrier> cbImageBarrier(
2331         3, makeImageMemoryBarrier(VK_ACCESS_NONE_KHR, // VkAccessFlags srcAccessMask;
2332                                   m_testParams.useMemoryAccess ?
2333                                       VK_ACCESS_MEMORY_WRITE_BIT :
2334                                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2335                                   VK_IMAGE_LAYOUT_UNDEFINED,                // VkImageLayout oldLayout;
2336                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
2337                                   *m_colorImage,                            // VkImage image;
2338                                   colorSubresourceRange                     // VkImageSubresourceRange subresourceRange;
2339                                   ));
2340     cbImageBarrier[1].image                            = *m_colorResolvedImage;
2341     cbImageBarrier[1 + isColorImageMultisampled].image = *m_colorCopyImage;
2342 
2343     const VkImageMemoryBarrier subsampledImageBarrier = makeImageMemoryBarrier(
2344         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT :
2345                                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
2346         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT :
2347                                        VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
2348         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                 // VkImageLayout oldLayout;
2349         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,                 // VkImageLayout newLayout;
2350         *m_colorImage,                                            // VkImage image;
2351         colorSubresourceRange                                     // VkImageSubresourceRange subresourceRange;
2352     );
2353 
2354     const VkImageMemoryBarrier outputImageBarrier = makeImageMemoryBarrier(
2355         VK_ACCESS_NONE_KHR, // VkAccessFlags srcAccessMask;
2356         m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT :
2357                                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
2358         VK_IMAGE_LAYOUT_UNDEFINED,                                           // VkImageLayout oldLayout;
2359         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                            // VkImageLayout newLayout;
2360         *m_outputImage,                                                      // VkImage image;
2361         outputSubresourceRange // VkImageSubresourceRange subresourceRange;
2362     );
2363 
2364     const VkRenderingFragmentDensityMapAttachmentInfoEXT densityMap0Attachment{
2365         VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT, // VkStructureType sType;
2366         DE_NULL,                                                              // const void* pNext;
2367         **m_densityMapImageViews[0],                                          // VkImageView imageView;
2368         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT                      // VkImageLayout imageLayout;
2369     };
2370 
2371     const VkRenderingFragmentDensityMapAttachmentInfoEXT densityMap1Attachment{
2372         VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT, // VkStructureType sType;
2373         DE_NULL,                                                              // const void* pNext;
2374         m_testParams.subsampledLoads ? **m_densityMapImageViews[1] : DE_NULL, // VkImageView imageView;
2375         VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT                      // VkImageLayout imageLayout;
2376     };
2377 
2378     const VkRenderingAttachmentInfoKHR dynamicDensityMapColorAttachment{
2379         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2380         DE_NULL,                                         // const void* pNext;
2381         **m_densityMapImageViews[0],                     // VkImageView imageView;
2382         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,        // VkImageLayout imageLayout;
2383         VK_RESOLVE_MODE_NONE,                            // VkResolveModeFlagBits resolveMode;
2384         DE_NULL,                                         // VkImageView resolveImageView;
2385         VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout resolveImageLayout;
2386         VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp loadOp;
2387         VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp storeOp;
2388         attachmentClearValuesDDM[0]                      // VkClearValue clearValue;
2389     };
2390 
2391     VkRenderingInfoKHR dynamicDensityMapRenderingInfo{
2392         VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2393         DE_NULL,
2394         0u,                                // VkRenderingFlagsKHR flags;
2395         dynamicDensityMapRenderArea,       // VkRect2D renderArea;
2396         m_testParams.viewCount,            // uint32_t layerCount;
2397         m_viewMask,                        // uint32_t viewMask;
2398         1u,                                // uint32_t colorAttachmentCount;
2399         &dynamicDensityMapColorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2400         DE_NULL,                           // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2401         DE_NULL,                           // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2402     };
2403 
2404     bool resolveFirstAttachment = isColorImageMultisampled && !m_testParams.makeCopy;
2405     const VkRenderingAttachmentInfoKHR subsampledImageColorAttachments[2]{
2406         {
2407             VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2408             DE_NULL,                                         // const void* pNext;
2409             *m_colorImageView,                               // VkImageView imageView;
2410             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,        // VkImageLayout imageLayout;
2411             resolveFirstAttachment ? VK_RESOLVE_MODE_AVERAGE_BIT :
2412                                      VK_RESOLVE_MODE_NONE,                // VkResolveModeFlagBits resolveMode;
2413             resolveFirstAttachment ? *m_colorResolvedImageView : DE_NULL, // VkImageView resolveImageView;
2414             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                     // VkImageLayout resolveImageLayout;
2415             VK_ATTACHMENT_LOAD_OP_CLEAR,                                  // VkAttachmentLoadOp loadOp;
2416             VK_ATTACHMENT_STORE_OP_STORE,                                 // VkAttachmentStoreOp storeOp;
2417             attachmentClearValues[0]                                      // VkClearValue clearValue;
2418         },
2419         {
2420             VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2421             DE_NULL,                                         // const void* pNext;
2422             *m_colorCopyImageView,                           // VkImageView imageView;
2423             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,        // VkImageLayout imageLayout;
2424             isColorImageMultisampled ? VK_RESOLVE_MODE_AVERAGE_BIT :
2425                                        VK_RESOLVE_MODE_NONE,                // VkResolveModeFlagBits resolveMode;
2426             isColorImageMultisampled ? *m_colorResolvedImageView : DE_NULL, // VkImageView resolveImageView;
2427             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout resolveImageLayout;
2428             VK_ATTACHMENT_LOAD_OP_CLEAR,                                    // VkAttachmentLoadOp loadOp;
2429             VK_ATTACHMENT_STORE_OP_STORE,                                   // VkAttachmentStoreOp storeOp;
2430             attachmentClearValues[0]                                        // VkClearValue clearValue;
2431         }};
2432 
2433     VkRenderingInfoKHR subsampledImageRenderingInfo{
2434         VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2435         &densityMap0Attachment,
2436         0u,                              // VkRenderingFlagsKHR flags;
2437         colorImageRenderArea,            // VkRect2D renderArea;
2438         m_testParams.viewCount,          // uint32_t layerCount;
2439         m_viewMask,                      // uint32_t viewMask;
2440         1u + m_testParams.makeCopy,      // uint32_t colorAttachmentCount;
2441         subsampledImageColorAttachments, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2442         DE_NULL,                         // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2443         DE_NULL,                         // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2444     };
2445 
2446     const VkRenderingAttachmentInfoKHR resampleSubsampledImageColorAttachment{
2447         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2448         DE_NULL,                                         // const void* pNext;
2449         *m_colorImageView,                               // VkImageView imageView;
2450         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,        // VkImageLayout imageLayout;
2451         VK_RESOLVE_MODE_NONE,                            // VkResolveModeFlagBits resolveMode;
2452         DE_NULL,                                         // VkImageView resolveImageView;
2453         VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout resolveImageLayout;
2454         VK_ATTACHMENT_LOAD_OP_LOAD,                      // VkAttachmentLoadOp loadOp;
2455         VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp storeOp;
2456         attachmentClearValues[0]                         // VkClearValue clearValue;
2457     };
2458 
2459     VkRenderingInfoKHR resampleSubsampledImageRenderingInfo{
2460         VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2461         &densityMap1Attachment,
2462         0u,                                      // VkRenderingFlagsKHR flags;
2463         colorImageRenderArea,                    // VkRect2D renderArea;
2464         m_testParams.viewCount,                  // uint32_t layerCount;
2465         m_viewMask,                              // uint32_t viewMask;
2466         1u,                                      // uint32_t colorAttachmentCount;
2467         &resampleSubsampledImageColorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2468         DE_NULL,                                 // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2469         DE_NULL,                                 // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2470     };
2471 
2472     const VkRenderingAttachmentInfoKHR copySubsampledColorAttachment{
2473         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2474         DE_NULL,                                         // const void* pNext;
2475         *m_outputImageView,                              // VkImageView imageView;
2476         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,        // VkImageLayout imageLayout;
2477         VK_RESOLVE_MODE_NONE,                            // VkResolveModeFlagBits resolveMode;
2478         DE_NULL,                                         // VkImageView resolveImageView;
2479         VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout resolveImageLayout;
2480         VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp loadOp;
2481         VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp storeOp;
2482         attachmentClearValues[0]                         // VkClearValue clearValue;
2483     };
2484 
2485     VkRenderingInfoKHR copySubsampledRenderingInfo{
2486         VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2487         DE_NULL,
2488         0u,                             // VkRenderingFlagsKHR flags;
2489         outputRenderArea,               // VkRect2D renderArea;
2490         1u,                             // uint32_t layerCount;
2491         0u,                             // uint32_t viewMask;
2492         1u,                             // uint32_t colorAttachmentCount;
2493         &copySubsampledColorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2494         DE_NULL,                        // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2495         DE_NULL,                        // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2496     };
2497 
2498     if (m_testParams.groupParams->useSecondaryCmdBuffer)
2499     {
2500         const VkFormat colorImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
2501         VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
2502             VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
2503             DE_NULL,                                                         // const void* pNext;
2504             0u,                                                              // VkRenderingFlagsKHR flags;
2505             m_viewMask,                                                      // uint32_t viewMask;
2506             1u,                                                              // uint32_t colorAttachmentCount;
2507             &m_testParams.densityMapFormat,                                  // const VkFormat* pColorAttachmentFormats;
2508             VK_FORMAT_UNDEFINED,                                             // VkFormat depthAttachmentFormat;
2509             VK_FORMAT_UNDEFINED,                                             // VkFormat stencilAttachmentFormat;
2510             VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits rasterizationSamples;
2511         };
2512 
2513         const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
2514         VkCommandBufferBeginInfo commandBufBeginParams{
2515             VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2516             DE_NULL,                                     // const void* pNext;
2517             VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
2518             &bufferInheritanceInfo};
2519 
2520         m_dynamicDensityMapSecCmdBuffer =
2521             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2522         m_subsampledImageSecCmdBuffer =
2523             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2524         m_resampleSubsampledImageSecCmdBuffer =
2525             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2526         m_outputSubsampledImageSecCmdBuffer =
2527             allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2528 
2529         // Record secondary command buffers
2530         if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2531         {
2532             if (m_testParams.dynamicDensityMap)
2533             {
2534                 vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2535                 vk.cmdBeginRendering(*m_dynamicDensityMapSecCmdBuffer, &dynamicDensityMapRenderingInfo);
2536                 drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2537                 vk.cmdEndRendering(*m_dynamicDensityMapSecCmdBuffer);
2538                 endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2539             }
2540 
2541             inheritanceRenderingInfo.pColorAttachmentFormats = &colorImageFormat;
2542             inheritanceRenderingInfo.rasterizationSamples    = m_testParams.colorSamples;
2543             vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2544             vk.cmdBeginRendering(*m_subsampledImageSecCmdBuffer, &subsampledImageRenderingInfo);
2545             drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2546             if (m_testParams.makeCopy)
2547             {
2548                 remapingBeforeCopySubsampledImage(*m_subsampledImageSecCmdBuffer);
2549                 drawCopySubsampledImage(*m_subsampledImageSecCmdBuffer);
2550             }
2551             vk.cmdEndRendering(*m_subsampledImageSecCmdBuffer);
2552             endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2553 
2554             if (m_testParams.subsampledLoads)
2555             {
2556                 vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2557                 vk.cmdBeginRendering(*m_resampleSubsampledImageSecCmdBuffer, &resampleSubsampledImageRenderingInfo);
2558                 drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2559                 vk.cmdEndRendering(*m_resampleSubsampledImageSecCmdBuffer);
2560                 endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2561             }
2562 
2563             inheritanceRenderingInfo.viewMask             = 0u;
2564             inheritanceRenderingInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2565             vk.beginCommandBuffer(*m_outputSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2566             vk.cmdBeginRendering(*m_outputSubsampledImageSecCmdBuffer, &copySubsampledRenderingInfo);
2567             drawOutputSubsampledImage(*m_outputSubsampledImageSecCmdBuffer);
2568             vk.cmdEndRendering(*m_outputSubsampledImageSecCmdBuffer);
2569             endCommandBuffer(vk, *m_outputSubsampledImageSecCmdBuffer);
2570         }
2571         else
2572         {
2573             commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2574 
2575             if (m_testParams.dynamicDensityMap)
2576             {
2577                 vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2578                 drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2579                 endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2580             }
2581 
2582             inheritanceRenderingInfo.pColorAttachmentFormats = &colorImageFormat;
2583             inheritanceRenderingInfo.rasterizationSamples    = m_testParams.colorSamples;
2584             vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2585             drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2586             if (m_testParams.makeCopy)
2587             {
2588                 remapingBeforeCopySubsampledImage(*m_subsampledImageSecCmdBuffer);
2589                 drawCopySubsampledImage(*m_subsampledImageSecCmdBuffer);
2590             }
2591             endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2592 
2593             if (m_testParams.subsampledLoads)
2594             {
2595                 vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2596                 drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2597                 endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2598             }
2599 
2600             inheritanceRenderingInfo.viewMask             = 0u;
2601             inheritanceRenderingInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2602             vk.beginCommandBuffer(*m_outputSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2603             drawOutputSubsampledImage(*m_outputSubsampledImageSecCmdBuffer);
2604             endCommandBuffer(vk, *m_outputSubsampledImageSecCmdBuffer);
2605         }
2606 
2607         // Record primary command buffer
2608         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2609 
2610         // Render dynamic density map
2611         if (m_testParams.dynamicDensityMap)
2612         {
2613             // change layout of density map - after filling it layout was changed
2614             // to density map optimal but here we want to render values to it
2615             vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR,
2616                                   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1,
2617                                   &dynamicDensitMapBarrier);
2618 
2619             if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2620                 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2621             else
2622             {
2623                 dynamicDensityMapRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2624                 vk.cmdBeginRendering(*m_cmdBuffer, &dynamicDensityMapRenderingInfo);
2625                 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2626                 vk.cmdEndRendering(*m_cmdBuffer);
2627             }
2628 
2629             // barrier that will change layout of density map
2630             vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2631                                   VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT, 0, 0, DE_NULL, 0, DE_NULL, 1,
2632                                   &densityMapImageBarrier);
2633         }
2634 
2635         // barrier that will change layout of color and resolve attachments
2636         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2637                               0, 0, DE_NULL, 0, DE_NULL, 1 + isColorImageMultisampled, cbImageBarrier.data());
2638 
2639         // Render subsampled image
2640         if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2641             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2642         else
2643         {
2644             subsampledImageRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2645             vk.cmdBeginRendering(*m_cmdBuffer, &subsampledImageRenderingInfo);
2646             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2647             vk.cmdEndRendering(*m_cmdBuffer);
2648         }
2649 
2650         // Resample subsampled image
2651         if (m_testParams.subsampledLoads)
2652         {
2653             if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2654                 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2655             else
2656             {
2657                 resampleSubsampledImageRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2658                 vk.cmdBeginRendering(*m_cmdBuffer, &resampleSubsampledImageRenderingInfo);
2659                 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2660                 vk.cmdEndRendering(*m_cmdBuffer);
2661             }
2662         }
2663 
2664         // barrier that ensures writing to colour image has completed.
2665         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2666                               VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u,
2667                               &subsampledImageBarrier);
2668 
2669         // barrier that will change layout of output image
2670         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2671                               0, 0, DE_NULL, 0, DE_NULL, 1, &outputImageBarrier);
2672 
2673         if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2674             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_outputSubsampledImageSecCmdBuffer);
2675         else
2676         {
2677             copySubsampledRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2678             vk.cmdBeginRendering(*m_cmdBuffer, &copySubsampledRenderingInfo);
2679             vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_outputSubsampledImageSecCmdBuffer);
2680             vk.cmdEndRendering(*m_cmdBuffer);
2681         }
2682 
2683         endCommandBuffer(vk, *m_cmdBuffer);
2684     }
2685     else
2686     {
2687         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2688 
2689         // First render pass - render dynamic density map
2690         if (m_testParams.dynamicDensityMap)
2691         {
2692             // change layout of density map - after filling it layout was changed
2693             // to density map optimal but here we want to render values to it
2694             vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR,
2695                                   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1,
2696                                   &dynamicDensitMapBarrier);
2697 
2698             vk.cmdBeginRendering(*m_cmdBuffer, &dynamicDensityMapRenderingInfo);
2699             drawDynamicDensityMap(*m_cmdBuffer);
2700             vk.cmdEndRendering(*m_cmdBuffer);
2701 
2702             // barrier that will change layout of density map
2703             vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2704                                   VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT, 0, 0, DE_NULL, 0, DE_NULL, 1,
2705                                   &densityMapImageBarrier);
2706         }
2707 
2708         // barrier that will change layout of color and resolve attachments
2709         if (m_testParams.makeCopy)
2710             cbImageBarrier[0].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2711         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2712                               0, 0, DE_NULL, 0, DE_NULL, 1 + isColorImageMultisampled + m_testParams.makeCopy,
2713                               cbImageBarrier.data());
2714 
2715         // Render subsampled image
2716         vk.cmdBeginRendering(*m_cmdBuffer, &subsampledImageRenderingInfo);
2717         drawSubsampledImage(*m_cmdBuffer);
2718         if (m_testParams.makeCopy)
2719         {
2720             remapingBeforeCopySubsampledImage(*m_cmdBuffer);
2721             drawCopySubsampledImage(*m_cmdBuffer);
2722         }
2723         vk.cmdEndRendering(*m_cmdBuffer);
2724 
2725         // Resample subsampled image
2726         if (m_testParams.subsampledLoads)
2727         {
2728             vk.cmdBeginRendering(*m_cmdBuffer, &resampleSubsampledImageRenderingInfo);
2729             drawResampleSubsampledImage(*m_cmdBuffer);
2730             vk.cmdEndRendering(*m_cmdBuffer);
2731         }
2732 
2733         // barrier that ensures writing to colour image has completed.
2734         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2735                               VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1u,
2736                               &subsampledImageBarrier);
2737 
2738         // barrier that will change layout of output image
2739         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2740                               0, 0, DE_NULL, 0, DE_NULL, 1, &outputImageBarrier);
2741 
2742         vk.cmdBeginRendering(*m_cmdBuffer, &copySubsampledRenderingInfo);
2743         drawOutputSubsampledImage(*m_cmdBuffer);
2744         vk.cmdEndRendering(*m_cmdBuffer);
2745 
2746         endCommandBuffer(vk, *m_cmdBuffer);
2747     }
2748 }
2749 
iterate(void)2750 tcu::TestStatus FragmentDensityMapTestInstance::iterate(void)
2751 {
2752     const DeviceInterface &vk = m_context.getDeviceInterface();
2753     const VkDevice vkDevice   = getDevice(m_context);
2754     const VkQueue queue       = getDeviceQueue(vk, vkDevice, m_context.getUniversalQueueFamilyIndex(), 0);
2755 
2756     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
2757 
2758     // approximations used when coarse reconstruction is specified are implementation defined
2759     if (m_testParams.coarseReconstruction)
2760         return tcu::TestStatus::pass("Pass");
2761 
2762     return verifyImage();
2763 }
2764 
2765 struct Vec4Sorter
2766 {
operator ()vkt::renderpass::__anond89f12cc0111::Vec4Sorter2767     bool operator()(const tcu::Vec4 &lhs, const tcu::Vec4 &rhs) const
2768     {
2769         if (lhs.x() != rhs.x())
2770             return lhs.x() < rhs.x();
2771         if (lhs.y() != rhs.y())
2772             return lhs.y() < rhs.y();
2773         if (lhs.z() != rhs.z())
2774             return lhs.z() < rhs.z();
2775         return lhs.w() < rhs.w();
2776     }
2777 };
2778 
verifyImage(void)2779 tcu::TestStatus FragmentDensityMapTestInstance::verifyImage(void)
2780 {
2781     const DeviceInterface &vk       = m_context.getDeviceInterface();
2782     const VkDevice vkDevice         = getDevice(m_context);
2783     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2784     const VkQueue queue             = getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
2785     SimpleAllocator memAlloc(
2786         vk, vkDevice,
2787         getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
2788     tcu::UVec2 renderSize(m_renderSize.x(), m_renderSize.y());
2789     de::UniquePtr<tcu::TextureLevel> outputImage(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex,
2790                                                                                memAlloc, *m_outputImage,
2791                                                                                VK_FORMAT_R8G8B8A8_UNORM, renderSize)
2792                                                      .release());
2793     const tcu::ConstPixelBufferAccess &outputAccess(outputImage->getAccess());
2794     tcu::TestLog &log(m_context.getTestContext().getLog());
2795 
2796     // Log images
2797     log << tcu::TestLog::ImageSet("Result", "Result images")
2798         << tcu::TestLog::Image("Rendered", "Rendered output image", outputAccess) << tcu::TestLog::EndImageSet;
2799 
2800     int32_t noColorCount = 0;
2801     uint32_t estimatedColorCount =
2802         m_testParams.viewCount * m_testParams.fragmentArea.x() * m_testParams.fragmentArea.y();
2803     float densityMult = m_densityValue.x() * m_densityValue.y();
2804 
2805     // Create histogram of all image colors, check the value of inverted FragSizeEXT
2806     std::map<tcu::Vec4, uint32_t, Vec4Sorter> colorCount;
2807     for (int y = 0; y < outputAccess.getHeight(); y++)
2808     {
2809         for (int x = 0; x < outputAccess.getWidth(); x++)
2810         {
2811             tcu::Vec4 outputColor = outputAccess.getPixel(x, y);
2812             float densityClamped  = outputColor.z() * outputColor.w();
2813 
2814             // for multiviewport cases we check only pixels to which we render
2815             if (m_testParams.multiViewport && outputColor.x() < 0.01f)
2816             {
2817                 ++noColorCount;
2818                 continue;
2819             }
2820 
2821             if ((densityClamped + 0.01) < densityMult)
2822                 return tcu::TestStatus::fail("Wrong value of FragSizeEXT variable");
2823 
2824             auto it = colorCount.find(outputColor);
2825             if (it == end(colorCount))
2826                 it = colorCount.insert({outputColor, 0u}).first;
2827             it->second++;
2828         }
2829     }
2830 
2831     // Check if color count is the same as estimated one
2832     for (const auto &color : colorCount)
2833     {
2834         if (color.second > estimatedColorCount)
2835             return tcu::TestStatus::fail("Wrong color count");
2836     }
2837 
2838     // For multiviewport cases ~75% of fragments should be black;
2839     // The margin of 100 fragments is used to compensate cases where
2840     // we can't fit all views in a same way to final 64x64 image
2841     // (64 can't be evenly divide for 6 views)
2842     int32_t estimatedNoColorCount = m_renderSize.x() * m_renderSize.y() * 3 / 4;
2843     if (m_testParams.multiViewport && std::abs(noColorCount - estimatedNoColorCount) > 100)
2844         return tcu::TestStatus::fail("Wrong number of fragments with black color");
2845 
2846     return tcu::TestStatus::pass("Pass");
2847 }
2848 
2849 } // namespace
2850 
createChildren(tcu::TestCaseGroup * fdmTests,const SharedGroupParams groupParams)2851 static void createChildren(tcu::TestCaseGroup *fdmTests, const SharedGroupParams groupParams)
2852 {
2853     tcu::TestContext &testCtx = fdmTests->getTestContext();
2854 
2855     const struct
2856     {
2857         std::string name;
2858         uint32_t viewCount;
2859     } views[] = {
2860         {"1_view", 1},
2861         {"2_views", 2},
2862         {"4_views", 4},
2863         {"6_views", 6},
2864     };
2865 
2866     const struct
2867     {
2868         std::string name;
2869         bool makeCopy;
2870     } renders[] = {{"render", false}, {"render_copy", true}};
2871 
2872     const struct
2873     {
2874         std::string name;
2875         float renderSizeToDensitySize;
2876     } sizes[] = {{"divisible_density_size", 4.0f}, {"non_divisible_density_size", 3.75f}};
2877 
2878     const struct
2879     {
2880         std::string name;
2881         VkSampleCountFlagBits samples;
2882     } samples[] = {{"1_sample", VK_SAMPLE_COUNT_1_BIT},
2883                    {"2_samples", VK_SAMPLE_COUNT_2_BIT},
2884                    {"4_samples", VK_SAMPLE_COUNT_4_BIT},
2885                    {"8_samples", VK_SAMPLE_COUNT_8_BIT}};
2886 
2887     std::vector<tcu::UVec2> fragmentArea{{1, 2}, {2, 1}, {2, 2}};
2888 
2889     for (const auto &view : views)
2890     {
2891         if ((groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY) && view.viewCount > 1)
2892             continue;
2893 
2894         // Reduce number of tests for secondary command buffers in dynamic rendering to 1 and 2 views
2895         if (groupParams->useSecondaryCmdBuffer && (view.viewCount > 2))
2896             continue;
2897 
2898         de::MovePtr<tcu::TestCaseGroup> viewGroup(new tcu::TestCaseGroup(testCtx, view.name.c_str()));
2899         for (const auto &render : renders)
2900         {
2901             de::MovePtr<tcu::TestCaseGroup> renderGroup(new tcu::TestCaseGroup(testCtx, render.name.c_str()));
2902             for (const auto &size : sizes)
2903             {
2904                 de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, size.name.c_str()));
2905                 for (const auto &sample : samples)
2906                 {
2907                     // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
2908                     if (groupParams->useSecondaryCmdBuffer && (sample.samples > VK_SAMPLE_COUNT_2_BIT))
2909                         break;
2910 
2911                     de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sample.name.c_str()));
2912                     for (const auto &area : fragmentArea)
2913                     {
2914                         std::stringstream str;
2915                         str << "_" << area.x() << "_" << area.y();
2916 
2917                         TestParams params{
2918                             false,                        // bool dynamicDensityMap;
2919                             false,                        // bool deferredDensityMap;
2920                             false,                        // bool nonSubsampledImages;
2921                             false,                        // bool subsampledLoads;
2922                             false,                        // bool coarseReconstruction;
2923                             false,                        // bool imagelessFramebuffer;
2924                             false,                        // bool useMemoryAccess;
2925                             false,                        // bool useMaintenance5;
2926                             1,                            // uint32_t samplersCount;
2927                             view.viewCount,               // uint32_t viewCount;
2928                             false,                        // bool multiViewport;
2929                             render.makeCopy,              // bool makeCopy;
2930                             size.renderSizeToDensitySize, // float renderMultiplier;
2931                             sample.samples,               // VkSampleCountFlagBits colorSamples;
2932                             area,                         // tcu::UVec2 fragmentArea;
2933                             {16, 16},                     // tcu::UVec2 densityMapSize;
2934                             VK_FORMAT_R8G8_UNORM,         // VkFormat densityMapFormat;
2935                             groupParams                   // SharedGroupParams groupParams;
2936                         };
2937 
2938                         sampleGroup->addChild(
2939                             new FragmentDensityMapTest(testCtx, std::string("static_subsampled") + str.str(), params));
2940                         params.deferredDensityMap = true;
2941                         sampleGroup->addChild(new FragmentDensityMapTest(
2942                             testCtx, std::string("deferred_subsampled") + str.str(), params));
2943                         params.deferredDensityMap = false;
2944                         params.dynamicDensityMap  = true;
2945                         sampleGroup->addChild(
2946                             new FragmentDensityMapTest(testCtx, std::string("dynamic_subsampled") + str.str(), params));
2947 
2948                         // generate nonsubsampled tests just for single view and double view cases
2949                         if (view.viewCount < 3)
2950                         {
2951                             params.nonSubsampledImages = true;
2952                             params.dynamicDensityMap   = false;
2953                             sampleGroup->addChild(new FragmentDensityMapTest(
2954                                 testCtx, std::string("static_nonsubsampled") + str.str(), params));
2955                             params.deferredDensityMap = true;
2956                             sampleGroup->addChild(new FragmentDensityMapTest(
2957                                 testCtx, std::string("deferred_nonsubsampled") + str.str(), params));
2958                             params.deferredDensityMap = false;
2959                             params.dynamicDensityMap  = true;
2960                             sampleGroup->addChild(new FragmentDensityMapTest(
2961                                 testCtx, std::string("dynamic_nonsubsampled") + str.str(), params));
2962                         }
2963 
2964                         // test multiviewport - each of views uses different viewport; limit number of cases to 2 samples
2965                         if ((groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) && (!render.makeCopy) &&
2966                             (view.viewCount > 1) && (sample.samples == VK_SAMPLE_COUNT_2_BIT))
2967                         {
2968                             params.nonSubsampledImages = false;
2969                             params.dynamicDensityMap   = false;
2970                             params.deferredDensityMap  = false;
2971                             params.multiViewport       = true;
2972                             sampleGroup->addChild(new FragmentDensityMapTest(
2973                                 testCtx, std::string("static_subsampled") + str.str() + "_multiviewport", params));
2974                         }
2975                     }
2976                     sizeGroup->addChild(sampleGroup.release());
2977                 }
2978                 renderGroup->addChild(sizeGroup.release());
2979             }
2980             viewGroup->addChild(renderGroup.release());
2981         }
2982         fdmTests->addChild(viewGroup.release());
2983     }
2984 
2985     const struct
2986     {
2987         std::string name;
2988         uint32_t count;
2989     } subsampledSamplers[] = {{"2_subsampled_samplers", 2},
2990                               {"4_subsampled_samplers", 4},
2991                               {"6_subsampled_samplers", 6},
2992                               {"8_subsampled_samplers", 8}};
2993 
2994     de::MovePtr<tcu::TestCaseGroup> propertiesGroup(new tcu::TestCaseGroup(testCtx, "properties"));
2995     for (const auto &sampler : subsampledSamplers)
2996     {
2997         TestParams params{
2998             false,                 // bool dynamicDensityMap;
2999             false,                 // bool deferredDensityMap;
3000             false,                 // bool nonSubsampledImages;
3001             false,                 // bool subsampledLoads;
3002             false,                 // bool coarseReconstruction;
3003             false,                 // bool imagelessFramebuffer;
3004             false,                 // bool useMemoryAccess;
3005             false,                 // bool useMaintenance5;
3006             sampler.count,         // uint32_t samplersCount;
3007             1,                     // uint32_t viewCount;
3008             false,                 // bool multiViewport;
3009             false,                 // bool makeCopy;
3010             4.0f,                  // float renderMultiplier;
3011             VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits colorSamples;
3012             {2, 2},                // tcu::UVec2 fragmentArea;
3013             {16, 16},              // tcu::UVec2 densityMapSize;
3014             VK_FORMAT_R8G8_UNORM,  // VkFormat densityMapFormat;
3015             groupParams            // SharedGroupParams groupParams;
3016         };
3017         propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, sampler.name, params));
3018 
3019         // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3020         if (groupParams->useSecondaryCmdBuffer)
3021             break;
3022     }
3023 
3024     if ((groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) &&
3025         (groupParams->useSecondaryCmdBuffer == false))
3026     {
3027         TestParams params{
3028             false,                 // bool dynamicDensityMap;
3029             false,                 // bool deferredDensityMap;
3030             false,                 // bool nonSubsampledImages;
3031             false,                 // bool subsampledLoads;
3032             false,                 // bool coarseReconstruction;
3033             false,                 // bool imagelessFramebuffer;
3034             false,                 // bool useMemoryAccess;
3035             true,                  // bool useMaintenance5;
3036             1,                     // uint32_t samplersCount;
3037             1,                     // uint32_t viewCount;
3038             false,                 // bool multiViewport;
3039             false,                 // bool makeCopy;
3040             4.0f,                  // float renderMultiplier;
3041             VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits colorSamples;
3042             {2, 2},                // tcu::UVec2 fragmentArea;
3043             {16, 16},              // tcu::UVec2 densityMapSize;
3044             VK_FORMAT_R8G8_UNORM,  // VkFormat densityMapFormat;
3045             groupParams            // SharedGroupParams groupParams;
3046         };
3047         propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "maintenance5", params));
3048     }
3049 
3050     if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3051     {
3052         // interaction between fragment density map and imageless framebuffer
3053 
3054         const struct
3055         {
3056             std::string name;
3057             bool useSecondaryCmdBuffer;
3058         } commandBufferType[] = {{"", false}, {"secondary_cmd_buff_", true}};
3059 
3060         for (const auto &cmdBuffType : commandBufferType)
3061         {
3062             TestParams params{
3063                 false,                            // bool dynamicDensityMap;
3064                 false,                            // bool deferredDensityMap;
3065                 false,                            // bool nonSubsampledImages;
3066                 false,                            // bool subsampledLoads;
3067                 false,                            // bool coarseReconstruction;
3068                 true,                             // bool imagelessFramebuffer;
3069                 false,                            // bool useMemoryAccess;
3070                 false,                            // bool useMaintenance5;
3071                 1,                                // uint32_t samplersCount;
3072                 1,                                // uint32_t viewCount;
3073                 false,                            // bool multiViewport;
3074                 false,                            // bool makeCopy;
3075                 4.0f,                             // float renderMultiplier;
3076                 VK_SAMPLE_COUNT_1_BIT,            // VkSampleCountFlagBits colorSamples;
3077                 {2, 2},                           // tcu::UVec2 fragmentArea;
3078                 {16, 16},                         // tcu::UVec2 densityMapSize;
3079                 VK_FORMAT_R8G8_UNORM,             // VkFormat densityMapFormat;
3080                 SharedGroupParams(new GroupParams // SharedGroupParams groupParams;
3081                                   {
3082                                       groupParams->renderingType,        // RenderingType renderingType;
3083                                       cmdBuffType.useSecondaryCmdBuffer, // bool useSecondaryCmdBuffer;
3084                                       false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
3085                                       PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // bool useGraphicsPipelineLibrary;
3086                                   })};
3087             std::string namePrefix = cmdBuffType.name;
3088 
3089             params.deferredDensityMap = false;
3090             params.dynamicDensityMap  = false;
3091             propertiesGroup->addChild(
3092                 new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_static_subsampled", params));
3093             params.deferredDensityMap = true;
3094             propertiesGroup->addChild(
3095                 new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_deferred_subsampled", params));
3096             params.deferredDensityMap = false;
3097             params.dynamicDensityMap  = true;
3098             propertiesGroup->addChild(
3099                 new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_dynamic_subsampled", params));
3100         }
3101     }
3102 
3103     if (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
3104     {
3105         TestParams params{
3106             false,                 // bool dynamicDensityMap;
3107             false,                 // bool deferredDensityMap;
3108             false,                 // bool nonSubsampledImages;
3109             true,                  // bool subsampledLoads;
3110             false,                 // bool coarseReconstruction;
3111             false,                 // bool imagelessFramebuffer;
3112             false,                 // bool useMemoryAccess;
3113             false,                 // bool useMaintenance5;
3114             1,                     // uint32_t samplersCount;
3115             2,                     // uint32_t viewCount;
3116             false,                 // bool multiViewport;
3117             false,                 // bool makeCopy;
3118             4.0f,                  // float renderMultiplier;
3119             VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits colorSamples;
3120             {1, 2},                // tcu::UVec2 fragmentArea;
3121             {16, 16},              // tcu::UVec2 densityMapSize;
3122             VK_FORMAT_R8G8_UNORM,  // VkFormat densityMapFormat;
3123             groupParams            // SharedGroupParams groupParams;
3124         };
3125         propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "subsampled_loads", params));
3126         params.subsampledLoads      = false;
3127         params.coarseReconstruction = true;
3128         propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "subsampled_coarse_reconstruction", params));
3129         params.useMemoryAccess = true;
3130         propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "memory_access", params));
3131     }
3132 
3133     fdmTests->addChild(propertiesGroup.release());
3134 }
3135 
cleanupGroup(tcu::TestCaseGroup * group,const SharedGroupParams)3136 static void cleanupGroup(tcu::TestCaseGroup *group, const SharedGroupParams)
3137 {
3138     DE_UNREF(group);
3139     // Destroy singleton objects.
3140     g_singletonDevice.clear();
3141 }
3142 
createFragmentDensityMapTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)3143 tcu::TestCaseGroup *createFragmentDensityMapTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
3144 {
3145     // VK_EXT_fragment_density_map and VK_EXT_fragment_density_map2 extensions tests
3146     return createTestGroup(testCtx, "fragment_density_map", createChildren, groupParams, cleanupGroup);
3147 }
3148 
3149 } // namespace renderpass
3150 
3151 } // namespace vkt
3152