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