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