1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2018 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 VK_KHR_depth_stencil_resolve tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktRenderPassDepthStencilResolveTests.hpp" 25 #include "vktRenderPassTestsUtil.hpp" 26 27 #include "vktTestCaseUtil.hpp" 28 #include "vktTestGroupUtil.hpp" 29 30 #include "vkDefs.hpp" 31 #include "vkDeviceUtil.hpp" 32 #include "vkImageUtil.hpp" 33 #include "vkMemUtil.hpp" 34 #include "vkPlatform.hpp" 35 #include "vkPrograms.hpp" 36 #include "vkQueryUtil.hpp" 37 #include "vkRef.hpp" 38 #include "vkRefUtil.hpp" 39 #include "vkTypeUtil.hpp" 40 #include "vkCmdUtil.hpp" 41 #include "vkObjUtil.hpp" 42 43 #include "tcuImageCompare.hpp" 44 #include "tcuFormatUtil.hpp" 45 #include "tcuResultCollector.hpp" 46 #include "tcuTestLog.hpp" 47 #include "tcuTextureUtil.hpp" 48 49 #include "deUniquePtr.hpp" 50 #include "deSharedPtr.hpp" 51 #include "deMath.h" 52 #include <limits> 53 54 using namespace vk; 55 56 using tcu::Vec4; 57 using tcu::TestLog; 58 59 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp; 60 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp; 61 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp; 62 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp; 63 typedef de::SharedPtr<Allocation> AllocationSp; 64 65 namespace vkt 66 { 67 namespace 68 { 69 70 using namespace renderpass; 71 72 template<typename T> 73 de::SharedPtr<T> safeSharedPtr (T* ptr) 74 { 75 try 76 { 77 return de::SharedPtr<T>(ptr); 78 } 79 catch (...) 80 { 81 delete ptr; 82 throw; 83 } 84 } 85 86 enum VerifyBuffer 87 { 88 VB_DEPTH = 0, 89 VB_STENCIL 90 }; 91 92 struct TestConfig 93 { 94 VkFormat format; 95 deUint32 width; 96 deUint32 height; 97 deUint32 imageLayers; 98 deUint32 viewLayers; 99 deUint32 resolveBaseLayer; 100 VkRect2D renderArea; 101 VkImageAspectFlags aspectFlag; 102 deUint32 sampleCount; 103 VkResolveModeFlagBitsKHR depthResolveMode; 104 VkResolveModeFlagBitsKHR stencilResolveMode; 105 VerifyBuffer verifyBuffer; 106 VkClearDepthStencilValue clearValue; 107 float depthExpectedValue; 108 deUint8 stencilExpectedValue; 109 }; 110 111 float get16bitDepthComponent(deUint8* pixelPtr) 112 { 113 deUint16* value = reinterpret_cast<deUint16*>(pixelPtr); 114 return static_cast<float>(*value) / 65535.0f; 115 } 116 117 float get24bitDepthComponent(deUint8* pixelPtr) 118 { 119 const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN); 120 deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) | 121 (((deUint32)pixelPtr[1]) << 8u) | 122 (((deUint32)pixelPtr[2]) << ( littleEndian * 16u)); 123 return static_cast<float>(value) / 16777215.0f; 124 } 125 126 float get32bitDepthComponent(deUint8* pixelPtr) 127 { 128 return *(reinterpret_cast<float*>(pixelPtr)); 129 } 130 131 class DepthStencilResolveTest : public TestInstance 132 { 133 public: 134 DepthStencilResolveTest (Context& context, TestConfig config); 135 virtual ~DepthStencilResolveTest (void); 136 137 virtual tcu::TestStatus iterate (void); 138 139 protected: 140 bool isFeaturesSupported (void); 141 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const; 142 143 VkImageSp createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u); 144 AllocationSp createImageMemory (VkImageSp image); 145 VkImageViewSp createImageView (VkImageSp image, deUint32 baseArrayLayer); 146 AllocationSp createBufferMemory (void); 147 VkBufferSp createBuffer (void); 148 149 Move<VkRenderPass> createRenderPass (void); 150 Move<VkFramebuffer> createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView); 151 Move<VkPipelineLayout> createRenderPipelineLayout (void); 152 Move<VkPipeline> createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout); 153 154 void submit (void); 155 bool verifyDepth (void); 156 bool verifyStencil (void); 157 158 protected: 159 const TestConfig m_config; 160 const bool m_featureSupported; 161 162 const InstanceInterface& m_vki; 163 const DeviceInterface& m_vkd; 164 VkDevice m_device; 165 VkPhysicalDevice m_physicalDevice; 166 167 VkImageSp m_multisampleImage; 168 AllocationSp m_multisampleImageMemory; 169 VkImageViewSp m_multisampleImageView; 170 VkImageSp m_singlesampleImage; 171 AllocationSp m_singlesampleImageMemory; 172 VkImageViewSp m_singlesampleImageView; 173 VkBufferSp m_buffer; 174 AllocationSp m_bufferMemory; 175 176 Unique<VkRenderPass> m_renderPass; 177 Unique<VkFramebuffer> m_framebuffer; 178 Unique<VkPipelineLayout> m_renderPipelineLayout; 179 Unique<VkPipeline> m_renderPipeline; 180 181 const Unique<VkCommandPool> m_commandPool; 182 }; 183 184 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config) 185 : TestInstance (context) 186 , m_config (config) 187 , m_featureSupported (isFeaturesSupported()) 188 , m_vki (context.getInstanceInterface()) 189 , m_vkd (context.getDeviceInterface()) 190 , m_device (context.getDevice()) 191 , m_physicalDevice (context.getPhysicalDevice()) 192 193 , m_multisampleImage (createImage(m_config.sampleCount)) 194 , m_multisampleImageMemory (createImageMemory(m_multisampleImage)) 195 , m_multisampleImageView (createImageView(m_multisampleImage, 0u)) 196 197 , m_singlesampleImage (createImage(1, VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) 198 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImage)) 199 , m_singlesampleImageView (createImageView(m_singlesampleImage, m_config.resolveBaseLayer)) 200 201 , m_buffer (createBuffer()) 202 , m_bufferMemory (createBufferMemory()) 203 204 , m_renderPass (createRenderPass()) 205 , m_framebuffer (createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView)) 206 , m_renderPipelineLayout (createRenderPipelineLayout()) 207 , m_renderPipeline (createRenderPipeline(*m_renderPass, *m_renderPipelineLayout)) 208 209 210 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex())) 211 { 212 } 213 214 DepthStencilResolveTest::~DepthStencilResolveTest (void) 215 { 216 } 217 218 bool DepthStencilResolveTest::isFeaturesSupported() 219 { 220 m_context.requireDeviceExtension("VK_KHR_depth_stencil_resolve"); 221 if (m_config.imageLayers > 1) 222 m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER); 223 224 VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties; 225 deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)); 226 dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR; 227 dsResolveProperties.pNext = DE_NULL; 228 229 VkPhysicalDeviceProperties2 deviceProperties; 230 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 231 deviceProperties.pNext = &dsResolveProperties; 232 233 // perform query to get supported float control properties 234 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 235 const vk::InstanceInterface& instanceInterface = m_context.getInstanceInterface(); 236 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties); 237 238 // check if both modes are supported 239 VkResolveModeFlagBitsKHR depthResolveMode = m_config.depthResolveMode; 240 VkResolveModeFlagBitsKHR stencilResolveMode = m_config.stencilResolveMode; 241 if ((depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) && 242 !(depthResolveMode & dsResolveProperties.supportedDepthResolveModes)) 243 TCU_THROW(NotSupportedError, "Depth resolve mode not supported"); 244 if ((stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR) && 245 !(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes)) 246 TCU_THROW(NotSupportedError, "Stencil resolve mode not supported"); 247 248 // check if the implementation supports setting the depth and stencil resolve 249 // modes to different values when one of those modes is VK_RESOLVE_MODE_NONE_KHR 250 if (dsResolveProperties.independentResolveNone) 251 { 252 if ((!dsResolveProperties.independentResolve) && 253 (depthResolveMode != stencilResolveMode) && 254 (depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) && 255 (stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR)) 256 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes"); 257 } 258 else if (depthResolveMode != stencilResolveMode) 259 { 260 // when independentResolveNone is VK_FALSE then both modes must be the same 261 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes"); 262 } 263 264 // check if the implementation supports all combinations of the supported depth and stencil resolve modes 265 if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode)) 266 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes"); 267 268 return true; 269 } 270 271 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const 272 { 273 switch (count) 274 { 275 case 1: return VK_SAMPLE_COUNT_1_BIT; 276 case 2: return VK_SAMPLE_COUNT_2_BIT; 277 case 4: return VK_SAMPLE_COUNT_4_BIT; 278 case 8: return VK_SAMPLE_COUNT_8_BIT; 279 case 16: return VK_SAMPLE_COUNT_16_BIT; 280 case 32: return VK_SAMPLE_COUNT_32_BIT; 281 case 64: return VK_SAMPLE_COUNT_64_BIT; 282 283 default: 284 DE_FATAL("Invalid sample count"); 285 return (VkSampleCountFlagBits)0x0; 286 } 287 } 288 289 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage) 290 { 291 const tcu::TextureFormat format(mapVkFormat(m_config.format)); 292 const VkImageTiling imageTiling(VK_IMAGE_TILING_OPTIMAL); 293 VkSampleCountFlagBits sampleCountBit(sampleCountBitFromSampleCount(sampleCount)); 294 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage; 295 296 VkImageFormatProperties imageFormatProperties; 297 if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling, 298 usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED) 299 { 300 TCU_THROW(NotSupportedError, "Format not supported"); 301 } 302 if (imageFormatProperties.sampleCounts < sampleCount) 303 { 304 TCU_THROW(NotSupportedError, "Sample count not supported"); 305 } 306 if (imageFormatProperties.maxArrayLayers < m_config.imageLayers) 307 { 308 TCU_THROW(NotSupportedError, "Layers count not supported"); 309 } 310 311 const VkExtent3D imageExtent = 312 { 313 m_config.width, 314 m_config.height, 315 1u 316 }; 317 318 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))) 319 TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment"); 320 321 if (imageFormatProperties.maxExtent.width < imageExtent.width 322 || imageFormatProperties.maxExtent.height < imageExtent.height 323 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0) 324 || imageFormatProperties.maxArrayLayers < m_config.imageLayers) 325 { 326 TCU_THROW(NotSupportedError, "Image type not supported"); 327 } 328 329 const VkImageCreateInfo pCreateInfo = 330 { 331 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 332 DE_NULL, 333 0u, 334 VK_IMAGE_TYPE_2D, 335 m_config.format, 336 imageExtent, 337 1u, 338 m_config.imageLayers, 339 sampleCountBit, 340 imageTiling, 341 usage, 342 VK_SHARING_MODE_EXCLUSIVE, 343 0u, 344 DE_NULL, 345 VK_IMAGE_LAYOUT_UNDEFINED 346 }; 347 348 return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo))); 349 } 350 351 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image) 352 { 353 Allocator& allocator = m_context.getDefaultAllocator(); 354 355 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any)); 356 VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset())); 357 return safeSharedPtr(allocation.release()); 358 } 359 360 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer) 361 { 362 const VkImageSubresourceRange range = 363 { 364 m_config.aspectFlag, 365 0u, 366 1u, 367 baseArrayLayer, 368 m_config.viewLayers 369 }; 370 371 const VkImageViewCreateInfo pCreateInfo = 372 { 373 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 374 DE_NULL, 375 0u, 376 **image, 377 (m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, 378 m_config.format, 379 makeComponentMappingRGBA(), 380 range, 381 }; 382 return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo))); 383 } 384 385 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void) 386 { 387 const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount)); 388 389 const AttachmentDescription2 multisampleAttachment // VkAttachmentDescription2KHR 390 ( 391 // VkStructureType sType; 392 DE_NULL, // const void* pNext; 393 0u, // VkAttachmentDescriptionFlags flags; 394 m_config.format, // VkFormat format; 395 samples, // VkSampleCountFlagBits samples; 396 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 397 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 398 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 399 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 400 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 401 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; 402 ); 403 const AttachmentReference2 multisampleAttachmentRef // VkAttachmentReference2KHR 404 ( 405 // VkStructureType sType; 406 DE_NULL, // const void* pNext; 407 0u, // deUint32 attachment; 408 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout layout; 409 0u // VkImageAspectFlags aspectMask; 410 ); 411 412 const AttachmentDescription2 singlesampleAttachment // VkAttachmentDescription2KHR 413 ( 414 // VkStructureType sType; 415 DE_NULL, // const void* pNext; 416 0u, // VkAttachmentDescriptionFlags flags; 417 m_config.format, // VkFormat format; 418 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 419 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 420 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 421 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 422 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 423 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 424 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; 425 ); 426 AttachmentReference2 singlesampleAttachmentRef // VkAttachmentReference2KHR 427 ( 428 // VkStructureType sType; 429 DE_NULL, // const void* pNext; 430 1u, // deUint32 attachment; 431 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout layout; 432 0u // VkImageAspectFlags aspectMask; 433 ); 434 435 std::vector<AttachmentDescription2> attachments; 436 attachments.push_back(multisampleAttachment); 437 attachments.push_back(singlesampleAttachment); 438 439 VkSubpassDescriptionDepthStencilResolveKHR dsResolveDescription = 440 { 441 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR, 442 DE_NULL, // const void* pNext; 443 m_config.depthResolveMode, // VkResolveModeFlagBitsKHR depthResolveMode; 444 m_config.stencilResolveMode, // VkResolveModeFlagBitsKHR stencilResolveMode; 445 &singlesampleAttachmentRef // VkAttachmentReference2KHR pDepthStencilResolveAttachment; 446 }; 447 448 const SubpassDescription2 subpass // VkSubpassDescription2KHR 449 ( 450 // VkStructureType sType; 451 &dsResolveDescription, // const void* pNext; 452 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 453 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 454 0u, // deUint32 viewMask; 455 0u, // deUint32 inputAttachmentCount; 456 DE_NULL, // const VkAttachmentReference2KHR* pInputAttachments; 457 0u, // deUint32 colorAttachmentCount; 458 DE_NULL, // const VkAttachmentReference2KHR* pColorAttachments; 459 DE_NULL, // const VkAttachmentReference2KHR* pResolveAttachments; 460 &multisampleAttachmentRef, // const VkAttachmentReference2KHR* pDepthStencilAttachment; 461 0u, // deUint32 preserveAttachmentCount; 462 DE_NULL // const deUint32* pPreserveAttachments; 463 ); 464 465 const RenderPassCreateInfo2 renderPassCreator // VkRenderPassCreateInfo2KHR 466 ( 467 // VkStructureType sType; 468 DE_NULL, // const void* pNext; 469 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; 470 (deUint32)attachments.size(), // deUint32 attachmentCount; 471 &attachments[0], // const VkAttachmentDescription2KHR* pAttachments; 472 1u, // deUint32 subpassCount; 473 &subpass, // const VkSubpassDescription2KHR* pSubpasses; 474 0u, // deUint32 dependencyCount; 475 DE_NULL, // const VkSubpassDependency2KHR* pDependencies; 476 0u, // deUint32 correlatedViewMaskCount; 477 DE_NULL // const deUint32* pCorrelatedViewMasks; 478 ); 479 480 return renderPassCreator.createRenderPass(m_vkd, m_device); 481 } 482 483 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView) 484 { 485 std::vector<VkImageView> attachments; 486 attachments.push_back(**multisampleImageView); 487 attachments.push_back(**singlesampleImageView); 488 489 const VkFramebufferCreateInfo createInfo = 490 { 491 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 492 DE_NULL, 493 0u, 494 495 renderPass, 496 (deUint32)attachments.size(), 497 &attachments[0], 498 499 m_config.width, 500 m_config.height, 501 m_config.viewLayers 502 }; 503 504 return vk::createFramebuffer(m_vkd, m_device, &createInfo); 505 } 506 507 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void) 508 { 509 VkPushConstantRange pushConstant = 510 { 511 VK_SHADER_STAGE_FRAGMENT_BIT, 512 0u, 513 4u 514 }; 515 516 deUint32 pushConstantRangeCount = 0u; 517 VkPushConstantRange* pPushConstantRanges = DE_NULL; 518 if (m_config.verifyBuffer == VB_STENCIL) 519 { 520 pushConstantRangeCount = 1u; 521 pPushConstantRanges = &pushConstant; 522 } 523 524 const VkPipelineLayoutCreateInfo createInfo = 525 { 526 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 527 DE_NULL, 528 (vk::VkPipelineLayoutCreateFlags)0, 529 530 0u, 531 DE_NULL, 532 533 pushConstantRangeCount, 534 pPushConstantRanges 535 }; 536 537 return vk::createPipelineLayout(m_vkd, m_device, &createInfo); 538 } 539 540 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout) 541 { 542 const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL); 543 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection(); 544 545 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u)); 546 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u)); 547 const Move<VkShaderModule> geometryShaderModule (m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u)); 548 549 const VkPipelineVertexInputStateCreateInfo vertexInputState = 550 { 551 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 552 DE_NULL, 553 (VkPipelineVertexInputStateCreateFlags)0u, 554 555 0u, 556 DE_NULL, 557 558 0u, 559 DE_NULL 560 }; 561 const tcu::UVec2 view (m_config.width, m_config.height); 562 const std::vector<VkViewport> viewports (1, makeViewport(view)); 563 const std::vector<VkRect2D> scissors (1, m_config.renderArea); 564 565 const VkPipelineMultisampleStateCreateInfo multisampleState = 566 { 567 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 568 DE_NULL, 569 (VkPipelineMultisampleStateCreateFlags)0u, 570 571 sampleCountBitFromSampleCount(m_config.sampleCount), 572 VK_FALSE, 573 0.0f, 574 DE_NULL, 575 VK_FALSE, 576 VK_FALSE, 577 }; 578 const VkPipelineDepthStencilStateCreateInfo depthStencilState = 579 { 580 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 581 DE_NULL, 582 (VkPipelineDepthStencilStateCreateFlags)0u, 583 584 VK_TRUE, // depthTestEnable 585 VK_TRUE, 586 VK_COMPARE_OP_ALWAYS, 587 VK_FALSE, 588 testingStencil, // stencilTestEnable 589 { 590 VK_STENCIL_OP_REPLACE, // failOp 591 VK_STENCIL_OP_REPLACE, // passOp 592 VK_STENCIL_OP_REPLACE, // depthFailOp 593 VK_COMPARE_OP_ALWAYS, // compareOp 594 0xFFu, // compareMask 595 0xFFu, // writeMask 596 1 // reference 597 }, 598 { 599 VK_STENCIL_OP_REPLACE, 600 VK_STENCIL_OP_REPLACE, 601 VK_STENCIL_OP_REPLACE, 602 VK_COMPARE_OP_ALWAYS, 603 0xFFu, 604 0xFFu, 605 1 606 }, 607 0.0f, 608 1.0f 609 }; 610 611 std::vector<VkDynamicState> dynamicState; 612 dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE); 613 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = 614 { 615 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 616 DE_NULL, // const void* pNext; 617 (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags; 618 static_cast<deUint32>(dynamicState.size()), // deUint32 dynamicStateCount; 619 &dynamicState[0] // const VkDynamicState* pDynamicStates; 620 }; 621 622 return makeGraphicsPipeline(m_vkd, // const DeviceInterface& vk 623 m_device, // const VkDevice device 624 renderPipelineLayout, // const VkPipelineLayout pipelineLayout 625 *vertexShaderModule, // const VkShaderModule vertexShaderModule 626 DE_NULL, // const VkShaderModule tessellationControlShaderModule 627 DE_NULL, // const VkShaderModule tessellationEvalShaderModule 628 m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule, // const VkShaderModule geometryShaderModule 629 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule 630 renderPass, // const VkRenderPass renderPass 631 viewports, // const std::vector<VkViewport>& viewports 632 scissors, // const std::vector<VkRect2D>& scissors 633 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology 634 0u, // const deUint32 subpass 635 0u, // const deUint32 patchControlPoints 636 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 637 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 638 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 639 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo 640 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo 641 testingStencil ? &dynamicStateCreateInfo : DE_NULL); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo 642 } 643 644 AllocationSp DepthStencilResolveTest::createBufferMemory (void) 645 { 646 Allocator& allocator = m_context.getDefaultAllocator(); 647 de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible)); 648 VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset())); 649 return safeSharedPtr(allocation.release()); 650 } 651 652 VkBufferSp DepthStencilResolveTest::createBuffer (void) 653 { 654 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 655 const tcu::TextureFormat textureFormat (mapVkFormat(m_config.format)); 656 const VkDeviceSize pixelSize (textureFormat.getPixelSize()); 657 const VkBufferCreateInfo createInfo = 658 { 659 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 660 DE_NULL, 661 0u, 662 663 m_config.width * m_config.height * m_config.imageLayers * pixelSize, 664 bufferUsage, 665 666 VK_SHARING_MODE_EXCLUSIVE, 667 0u, 668 DE_NULL 669 }; 670 return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo))); 671 } 672 673 void DepthStencilResolveTest::submit (void) 674 { 675 const DeviceInterface& vkd (m_context.getDeviceInterface()); 676 const VkDevice device (m_context.getDevice()); 677 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 678 const RenderpassSubpass2::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE); 679 const RenderpassSubpass2::SubpassEndInfo subpassEndInfo (DE_NULL); 680 681 beginCommandBuffer(vkd, *commandBuffer); 682 683 { 684 VkClearValue clearValues[2]; 685 clearValues[0].depthStencil = m_config.clearValue; 686 clearValues[1].depthStencil = m_config.clearValue; 687 688 const VkRenderPassBeginInfo beginInfo = 689 { 690 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 691 DE_NULL, 692 693 *m_renderPass, 694 *m_framebuffer, 695 696 { 697 { 0u, 0u }, 698 { m_config.width, m_config.height } 699 }, 700 701 2u, 702 clearValues 703 }; 704 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo); 705 } 706 707 // Render 708 bool testingDepth = (m_config.verifyBuffer == VB_DEPTH); 709 if (testingDepth) 710 { 711 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline); 712 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u); 713 } 714 else 715 { 716 // For stencil we can set reference value for just one sample at a time 717 // so we need to do as many passes as there are samples, first half 718 // of samples is initialized with 1 and second half with 255 719 const deUint32 halfOfSamples = m_config.sampleCount >> 1; 720 for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++) 721 { 722 deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples); 723 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline); 724 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass); 725 vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference); 726 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u); 727 } 728 } 729 730 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo); 731 732 // Memory barriers between rendering and copying 733 { 734 const VkImageMemoryBarrier barrier = 735 { 736 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 737 DE_NULL, 738 739 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 740 VK_ACCESS_TRANSFER_READ_BIT, 741 742 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 743 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 744 745 VK_QUEUE_FAMILY_IGNORED, 746 VK_QUEUE_FAMILY_IGNORED, 747 748 **m_singlesampleImage, 749 { 750 m_config.aspectFlag, 751 0u, 752 1u, 753 0u, 754 m_config.viewLayers 755 } 756 }; 757 758 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier); 759 } 760 761 // Copy image memory to buffers 762 const VkBufferImageCopy region = 763 { 764 0u, 765 0u, 766 0u, 767 { 768 testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT, 769 0u, 770 0u, 771 m_config.viewLayers, 772 }, 773 { 0u, 0u, 0u }, 774 { m_config.width, m_config.height, 1u } 775 }; 776 777 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, ®ion); 778 779 // Memory barriers between copies and host access 780 { 781 const VkBufferMemoryBarrier barrier = 782 { 783 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 784 DE_NULL, 785 786 VK_ACCESS_TRANSFER_WRITE_BIT, 787 VK_ACCESS_HOST_READ_BIT, 788 789 VK_QUEUE_FAMILY_IGNORED, 790 VK_QUEUE_FAMILY_IGNORED, 791 792 **m_buffer, 793 0u, 794 VK_WHOLE_SIZE 795 }; 796 797 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL); 798 } 799 800 endCommandBuffer(vkd, *commandBuffer); 801 802 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer); 803 } 804 805 bool DepthStencilResolveTest::verifyDepth (void) 806 { 807 deUint32 layerSize = m_config.width * m_config.height; 808 deUint32 valuesCount = layerSize * m_config.viewLayers; 809 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr()); 810 811 float expectedValue = m_config.depthExpectedValue; 812 if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE_KHR) 813 expectedValue = m_config.clearValue.depth; 814 815 // depth data in buffer is tightly packed, ConstPixelBufferAccess 816 // coludn't be used for depth value extraction as it cant interpret 817 // formats containing just depth component 818 819 typedef float (*DepthComponentGetterFn)(deUint8*); 820 VkFormat format = m_config.format; 821 DepthComponentGetterFn getDepthComponent = &get16bitDepthComponent; 822 deUint32 pixelStep = 2; 823 float epsilon = 0.002f; 824 825 if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) || 826 (format == VK_FORMAT_D24_UNORM_S8_UINT)) 827 { 828 getDepthComponent = &get24bitDepthComponent; 829 pixelStep = 4; 830 } 831 else if ((format == VK_FORMAT_D32_SFLOAT) || 832 (format == VK_FORMAT_D32_SFLOAT_S8_UINT)) 833 { 834 getDepthComponent = &get32bitDepthComponent; 835 pixelStep = 4; 836 } 837 838 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++) 839 { 840 float depth = (*getDepthComponent)(pixelPtr); 841 pixelPtr += pixelStep; 842 843 // check if pixel data is outside of render area 844 deInt32 layerIndex = valueIndex / layerSize; 845 deInt32 inLayerIndex = valueIndex % layerSize; 846 deInt32 x = inLayerIndex % m_config.width; 847 deInt32 y = (inLayerIndex - x) / m_config.width; 848 deInt32 x1 = m_config.renderArea.offset.x; 849 deInt32 y1 = m_config.renderArea.offset.y; 850 deInt32 x2 = x1 + m_config.renderArea.extent.width; 851 deInt32 y2 = y1 + m_config.renderArea.extent.height; 852 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2)) 853 { 854 // verify that outside of render area there are clear values 855 float error = deFloatAbs(depth - m_config.clearValue.depth); 856 if (error > epsilon) 857 { 858 m_context.getTestContext().getLog() 859 << TestLog::Message << "(" << x << ", " << y 860 << ", layer: " << layerIndex << ") is outside of render area but depth value is: " 861 << depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage; 862 return false; 863 } 864 865 // value is correct, go to next one 866 continue; 867 } 868 869 float error = deFloatAbs(depth - expectedValue); 870 if (error > epsilon) 871 { 872 m_context.getTestContext().getLog() << TestLog::Message 873 << "At (" << x << ", " << y << ", layer: " << layerIndex 874 << ") depth value is: " << depth << " expected: " 875 << expectedValue << TestLog::EndMessage; 876 return false; 877 } 878 } 879 m_context.getTestContext().getLog() << TestLog::Message 880 << "Depth value is " << expectedValue 881 << TestLog::EndMessage; 882 883 return true; 884 } 885 886 bool DepthStencilResolveTest::verifyStencil (void) 887 { 888 deUint32 layerSize = m_config.width * m_config.height; 889 deUint32 valuesCount = layerSize * m_config.viewLayers; 890 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr()); 891 892 // when stencil is tested we are discarding invocations and 893 // because of that depth and stencil need to be tested separately 894 895 deUint8 expectedValue = m_config.stencilExpectedValue; 896 if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE_KHR) 897 expectedValue = static_cast<deUint8>(m_config.clearValue.stencil); 898 899 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++) 900 { 901 deUint8 stencil = *pixelPtr++; 902 deInt32 layerIndex = valueIndex / layerSize; 903 deInt32 inLayerIndex = valueIndex % layerSize; 904 deInt32 x = inLayerIndex % m_config.width; 905 deInt32 y = (inLayerIndex - x) / m_config.width; 906 deInt32 x1 = m_config.renderArea.offset.x; 907 deInt32 y1 = m_config.renderArea.offset.y; 908 deInt32 x2 = x1 + m_config.renderArea.extent.width; 909 deInt32 y2 = y1 + m_config.renderArea.extent.height; 910 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2)) 911 { 912 if (stencil != m_config.clearValue.stencil) 913 { 914 m_context.getTestContext().getLog() 915 << TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex 916 << ") is outside of render area but stencil value is: " 917 << stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage; 918 return false; 919 } 920 921 // value is correct, go to next one 922 continue; 923 } 924 925 if (stencil != expectedValue) 926 { 927 m_context.getTestContext().getLog() << TestLog::Message 928 << "At (" << x << ", " << y << ", layer: " << layerIndex 929 << ") stencil value is: " << static_cast<deUint32>(stencil) 930 << " expected: " << static_cast<deUint32>(expectedValue) 931 << TestLog::EndMessage; 932 return false; 933 } 934 } 935 m_context.getTestContext().getLog() << TestLog::Message 936 << "Stencil value is " 937 << static_cast<deUint32>(expectedValue) 938 << TestLog::EndMessage; 939 940 return true; 941 } 942 943 tcu::TestStatus DepthStencilResolveTest::iterate (void) 944 { 945 submit(); 946 947 bool result = false; 948 if (m_config.verifyBuffer == VB_DEPTH) 949 result = verifyDepth(); 950 else 951 result = verifyStencil(); 952 953 if (result) 954 return tcu::TestStatus::pass("Pass"); 955 return tcu::TestStatus::fail("Fail"); 956 } 957 958 struct Programs 959 { 960 void init (vk::SourceCollections& dst, TestConfig config) const 961 { 962 // geometry shader is only needed in multi-layer framebuffer resolve tests 963 if (config.imageLayers > 1) 964 { 965 const deUint32 layerCount = 3; 966 967 std::ostringstream src; 968 src << "#version 450\n" 969 << "highp float;\n" 970 << "\n" 971 << "layout(triangles) in;\n" 972 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n" 973 << "\n" 974 << "in gl_PerVertex {\n" 975 << " vec4 gl_Position;\n" 976 << "} gl_in[];\n" 977 << "\n" 978 << "out gl_PerVertex {\n" 979 << " vec4 gl_Position;\n" 980 << "};\n" 981 << "\n" 982 << "void main (void) {\n" 983 << " for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n" 984 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n" 985 << " gl_Position = gl_in[vertexNdx].gl_Position;\n" 986 << " gl_Layer = layerNdx;\n" 987 << " EmitVertex();\n" 988 << " };\n" 989 << " EndPrimitive();\n" 990 << " };\n" 991 << "}\n"; 992 993 dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str()); 994 } 995 996 dst.glslSources.add("quad-vert") << glu::VertexSource( 997 "#version 450\n" 998 "out gl_PerVertex {\n" 999 "\tvec4 gl_Position;\n" 1000 "};\n" 1001 "highp float;\n" 1002 "void main (void) {\n" 1003 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n" 1004 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n" 1005 "}\n"); 1006 1007 if (config.verifyBuffer == VB_DEPTH) 1008 { 1009 dst.glslSources.add("quad-frag") << glu::FragmentSource( 1010 "#version 450\n" 1011 "precision highp float;\n" 1012 "precision highp int;\n" 1013 "void main (void)\n" 1014 "{\n" 1015 " float sampleIndex = float(gl_SampleID);\n" // sampleIndex is integer in range <0, 63> 1016 " float valueIndex = round(mod(sampleIndex, 4.0));\n" // limit possible depth values - count to 4 1017 " float value = valueIndex + 2.0;\n" // value is one of [2, 3, 4, 5] 1018 " value = round(exp2(value));\n" // value is one of [4, 8, 16, 32] 1019 " bool condition = (int(value) == 8);\n" // select second sample value (to make it smallest) 1020 " value = round(value - float(condition) * 6.0);\n" // value is one of [4, 2, 16, 32] 1021 " gl_FragDepth = value / 100.0;\n" // sample depth is one of [0.04, 0.02, 0.16, 0.32] 1022 "}\n"); 1023 } 1024 else 1025 { 1026 dst.glslSources.add("quad-frag") << glu::FragmentSource( 1027 "#version 450\n" 1028 "precision highp float;\n" 1029 "precision highp int;\n" 1030 "layout(push_constant) uniform PushConstant {\n" 1031 " highp int sampleID;\n" 1032 "} pushConstants;\n" 1033 "void main (void)\n" 1034 "{\n" 1035 " if(gl_SampleID != pushConstants.sampleID)\n" 1036 " discard;\n" 1037 " gl_FragDepth = 0.5;\n" 1038 "}\n"); 1039 } 1040 } 1041 }; 1042 1043 void initTests (tcu::TestCaseGroup* group) 1044 { 1045 typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance; 1046 1047 struct FormatData 1048 { 1049 VkFormat format; 1050 const char* name; 1051 bool hasDepth; 1052 bool hasStencil; 1053 }; 1054 FormatData formats[] = 1055 { 1056 { VK_FORMAT_D16_UNORM, "d16_unorm", true, false }, 1057 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32", true, false }, 1058 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", true, false }, 1059 { VK_FORMAT_S8_UINT, "s8_uint", false, true }, 1060 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint", true, true }, 1061 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint", true, true }, 1062 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", true, true }, 1063 }; 1064 1065 struct ResolveModeData 1066 { 1067 VkResolveModeFlagBitsKHR flag; 1068 std::string name; 1069 }; 1070 ResolveModeData resolveModes[] = 1071 { 1072 { VK_RESOLVE_MODE_NONE_KHR, "none" }, 1073 { VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR, "zero" }, 1074 { VK_RESOLVE_MODE_AVERAGE_BIT_KHR, "average" }, 1075 { VK_RESOLVE_MODE_MIN_BIT_KHR, "min" }, 1076 { VK_RESOLVE_MODE_MAX_BIT_KHR, "max" }, 1077 }; 1078 1079 struct ImageTestData 1080 { 1081 const char* groupName; 1082 deUint32 width; 1083 deUint32 height; 1084 deUint32 imageLayers; 1085 VkRect2D renderArea; 1086 VkClearDepthStencilValue clearValue; 1087 }; 1088 1089 // NOTE: tests cant be executed for 1D and 3D images: 1090 // 1D images are not tested because acording to specyfication sampleCounts 1091 // will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D 1092 // 3D images are not tested because VkFramebufferCreateInfo specification 1093 // states that: each element of pAttachments that is a 2D or 2D array image 1094 // view taken from a 3D image must not be a depth/stencil format 1095 ImageTestData imagesTestData[] = 1096 { 1097 { "image_2d_32_32", 32, 32, 1, {{ 0, 0}, {32, 32}}, {0.000f, 0x00} }, 1098 { "image_2d_8_32", 8, 32, 1, {{ 1, 1}, { 6, 30}}, {0.123f, 0x01} }, 1099 { "image_2d_49_13", 49, 13, 1, {{10, 5}, {20, 8}}, {1.000f, 0x05} }, 1100 { "image_2d_5_1", 5, 1, 1, {{ 0, 0}, { 5, 1}}, {0.500f, 0x00} }, 1101 { "image_2d_17_1", 17, 1, 1, {{ 1, 0}, {15, 1}}, {0.789f, 0xfa} }, 1102 }; 1103 const deUint32 sampleCounts[] = 1104 { 1105 2u, 4u, 8u, 16u, 32u, 64u 1106 }; 1107 const float depthExpectedValue[][6] = 1108 { 1109 // 2 samples 4 8 16 32 64 1110 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // RESOLVE_MODE_NONE - expect clear value 1111 { 0.04f, 0.04f, 0.04f, 0.04f, 0.04f, 0.04f }, // RESOLVE_MODE_SAMPLE_ZERO_BIT 1112 { 0.03f, 0.135f, 0.135f, 0.135f, 0.135f, 0.135f }, // RESOLVE_MODE_AVERAGE_BIT 1113 { 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f }, // RESOLVE_MODE_MIN_BIT 1114 { 0.04f, 0.32f, 0.32f, 0.32f, 0.32f, 0.32f }, // RESOLVE_MODE_MAX_BIT 1115 }; 1116 const deUint8 stencilExpectedValue[][6] = 1117 { 1118 // 2 samples 4 8 16 32 64 1119 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_NONE - expect clear value 1120 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_SAMPLE_ZERO_BIT 1121 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_AVERAGE_BIT - not supported 1122 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_MIN_BIT 1123 { 255u, 255u, 255u, 255u, 255u, 255u }, // RESOLVE_MODE_MAX_BIT 1124 }; 1125 1126 tcu::TestContext& testCtx(group->getTestContext()); 1127 1128 // iterate over image data 1129 for (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++) 1130 { 1131 ImageTestData imageData = imagesTestData[imageDataNdx]; 1132 1133 // create test group for image data 1134 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName)); 1135 1136 // iterate over sampleCounts 1137 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++) 1138 { 1139 const deUint32 sampleCount (sampleCounts[sampleCountNdx]); 1140 const std::string sampleName ("samples_" + de::toString(sampleCount)); 1141 1142 // create test group for sample count 1143 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str())); 1144 1145 // iterate over depth/stencil formats 1146 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++) 1147 { 1148 const FormatData& formatData = formats[formatNdx]; 1149 VkFormat format = formatData.format; 1150 const char* formatName = formatData.name; 1151 const bool hasDepth = formatData.hasDepth; 1152 const bool hasStencil = formatData.hasStencil; 1153 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) | 1154 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT); 1155 1156 // create test group for format 1157 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName)); 1158 1159 // iterate over depth resolve modes 1160 for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++) 1161 { 1162 // iterate over stencil resolve modes 1163 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++) 1164 { 1165 // there is no average resolve mode for stencil - go to next iteration 1166 ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx]; 1167 if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR) 1168 continue; 1169 1170 // if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED, 1171 // depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR 1172 ResolveModeData& dResolve = resolveModes[depthResolveModeNdx]; 1173 if ((dResolve.flag == VK_RESOLVE_MODE_NONE_KHR) && (sResolve.flag == VK_RESOLVE_MODE_NONE_KHR)) 1174 continue; 1175 1176 // If there is no depth, the depth resolve mode should be NONE, or 1177 // match the stencil resolve mode. 1178 if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE_KHR) && 1179 (dResolve.flag != sResolve.flag)) 1180 continue; 1181 1182 // If there is no stencil, the stencil resmove mode should be NONE, or 1183 // match the depth resolve mode. 1184 if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE_KHR) && 1185 (dResolve.flag != sResolve.flag)) 1186 continue; 1187 1188 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name; 1189 1190 if (hasDepth) 1191 { 1192 std::string name = baseName + "_testing_depth"; 1193 const char* testName = name.c_str(); 1194 float expectedValue = depthExpectedValue[depthResolveModeNdx][sampleCountNdx]; 1195 1196 const TestConfig testConfig = 1197 { 1198 format, 1199 imageData.width, 1200 imageData.height, 1201 1u, 1202 1u, 1203 0u, 1204 imageData.renderArea, 1205 aspectFlags, 1206 sampleCount, 1207 dResolve.flag, 1208 sResolve.flag, 1209 VB_DEPTH, 1210 imageData.clearValue, 1211 expectedValue, 1212 0u 1213 }; 1214 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig)); 1215 } 1216 if (hasStencil) 1217 { 1218 std::string name = baseName + "_testing_stencil"; 1219 const char* testName = name.c_str(); 1220 deUint8 expectedValue = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx]; 1221 1222 const TestConfig testConfig = 1223 { 1224 format, 1225 imageData.width, 1226 imageData.height, 1227 1u, 1228 1u, 1229 0u, 1230 imageData.renderArea, 1231 aspectFlags, 1232 sampleCount, 1233 dResolve.flag, 1234 sResolve.flag, 1235 VB_STENCIL, 1236 imageData.clearValue, 1237 0.0f, 1238 expectedValue 1239 }; 1240 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig)); 1241 } 1242 } 1243 } 1244 1245 sampleGroup->addChild(formatGroup.release()); 1246 } 1247 1248 imageGroup->addChild(sampleGroup.release()); 1249 } 1250 1251 group->addChild(imageGroup.release()); 1252 } 1253 1254 { 1255 // layered texture tests are done for all stencil modes and depth modes - not all combinations 1256 // Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer 1257 // which starts at a layer other than zero. Both parts are tested together by rendering to layers 1258 // 4-6 and resolving to layers 1-3. 1259 ImageTestData layeredTextureTestData = 1260 { 1261 "image_2d_16_64_6", 16, 64, 6, {{ 10, 10}, {6, 54}}, {1.0f, 0x0} 1262 }; 1263 1264 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName)); 1265 1266 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++) 1267 { 1268 const deUint32 sampleCount (sampleCounts[sampleCountNdx]); 1269 const std::string sampleName ("samples_" + de::toString(sampleCount)); 1270 1271 // create test group for sample count 1272 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str())); 1273 1274 // iterate over depth/stencil formats 1275 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++) 1276 { 1277 const FormatData& formatData = formats[formatNdx]; 1278 VkFormat format = formatData.format; 1279 const char* formatName = formatData.name; 1280 const bool hasDepth = formatData.hasDepth; 1281 const bool hasStencil = formatData.hasStencil; 1282 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) | 1283 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT); 1284 1285 // create test group for format 1286 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName)); 1287 1288 for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++) 1289 { 1290 ResolveModeData& mode = resolveModes[resolveModeNdx]; 1291 1292 if (hasDepth) 1293 { 1294 std::string name = "depth_" + mode.name; 1295 const char* testName = name.c_str(); 1296 float expectedValue = depthExpectedValue[resolveModeNdx][sampleCountNdx]; 1297 const TestConfig testConfig = 1298 { 1299 format, 1300 layeredTextureTestData.width, 1301 layeredTextureTestData.height, 1302 layeredTextureTestData.imageLayers, 1303 3u, 1304 0u, 1305 layeredTextureTestData.renderArea, 1306 aspectFlags, 1307 sampleCount, 1308 mode.flag, 1309 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR, 1310 VB_DEPTH, 1311 layeredTextureTestData.clearValue, 1312 expectedValue, 1313 0u 1314 }; 1315 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig)); 1316 } 1317 1318 // there is no average resolve mode for stencil - go to next iteration 1319 if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR) 1320 continue; 1321 1322 if (hasStencil) 1323 { 1324 std::string name = "stencil_" + mode.name; 1325 const char* testName = name.c_str(); 1326 deUint8 expectedValue = stencilExpectedValue[resolveModeNdx][sampleCountNdx]; 1327 const TestConfig testConfig = 1328 { 1329 format, 1330 layeredTextureTestData.width, 1331 layeredTextureTestData.height, 1332 layeredTextureTestData.imageLayers, 1333 3u, 1334 0u, 1335 layeredTextureTestData.renderArea, 1336 aspectFlags, 1337 sampleCount, 1338 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR, 1339 mode.flag, 1340 VB_STENCIL, 1341 layeredTextureTestData.clearValue, 1342 0.0f, 1343 expectedValue 1344 }; 1345 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig)); 1346 } 1347 } 1348 sampleGroup->addChild(formatGroup.release()); 1349 } 1350 imageGroup->addChild(sampleGroup.release()); 1351 } 1352 1353 group->addChild(imageGroup.release()); 1354 } 1355 } 1356 1357 } // anonymous 1358 1359 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx) 1360 { 1361 return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests); 1362 } 1363 1364 } // vkt 1365