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, ©Region);
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 ©SubsampledColorAttachment, // 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, ©SubsampledRenderingInfo);
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, ©SubsampledRenderingInfo);
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, ©SubsampledRenderingInfo);
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