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