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