1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies Ltd. 7 * Copyright (c) 2023 LunarG, Inc. 8 * Copyright (c) 2023 Nintendo 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 *//*! 23 * \file 24 * \brief Depth Tests 25 *//*--------------------------------------------------------------------*/ 26 27#include "vktPipelineDepthTests.hpp" 28#include "vktPipelineClearUtil.hpp" 29#include "vktPipelineImageUtil.hpp" 30#include "vktPipelineVertexUtil.hpp" 31#include "vktPipelineReferenceRenderer.hpp" 32#include "vktTestCase.hpp" 33#include "vktTestCaseUtil.hpp" 34#include "vkImageUtil.hpp" 35#include "vkMemUtil.hpp" 36#include "vkPrograms.hpp" 37#include "vkQueryUtil.hpp" 38#include "vkRef.hpp" 39#include "vkRefUtil.hpp" 40#include "vkTypeUtil.hpp" 41#include "vkCmdUtil.hpp" 42#include "vkObjUtil.hpp" 43#include "tcuImageCompare.hpp" 44#include "deUniquePtr.hpp" 45#include "deStringUtil.hpp" 46#include "deMemory.h" 47 48#include <sstream> 49#include <vector> 50 51namespace vkt 52{ 53namespace pipeline 54{ 55 56using namespace vk; 57 58namespace 59{ 60 61enum class DepthClipControlCase 62{ 63 DISABLED = 0, // No depth clip control. 64 NORMAL = 1, // Depth clip control with static viewport. 65 NORMAL_W = 2, // Depth clip control with static viewport and .w different from 1.0f 66 BEFORE_STATIC = 3, // Set dynamic viewport state, then bind a static pipeline. 67 BEFORE_DYNAMIC = 4, // Set dynamic viewport state, bind dynamic pipeline. 68 BEFORE_TWO_DYNAMICS = 5, // Set dynamic viewport state, bind dynamic pipeline with [0,1] view volume, then bind dynamic pipeline with [-1,1] view volume. 69 AFTER_DYNAMIC = 6, // Bind dynamic pipeline, then set dynamic viewport state. 70}; 71 72bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 73{ 74 VkFormatProperties formatProps; 75 76 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 77 78 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u; 79} 80 81tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format) 82{ 83 DE_ASSERT(vk::isDepthStencilFormat(format)); 84 85 if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format)) 86 return tcu::TestStatus::pass("Format can be used in depth/stencil attachment"); 87 else 88 return tcu::TestStatus::fail("Unsupported depth/stencil attachment format"); 89} 90 91tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats) 92{ 93 std::ostringstream supportedFormatsMsg; 94 bool pass = false; 95 96 DE_ASSERT(!formats.empty()); 97 98 for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++) 99 { 100 const VkFormat format = formats[formatNdx]; 101 102 DE_ASSERT(vk::isDepthStencilFormat(format)); 103 104 if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format)) 105 { 106 pass = true; 107 supportedFormatsMsg << vk::getFormatName(format); 108 109 if (formatNdx < formats.size() - 1) 110 supportedFormatsMsg << ", "; 111 } 112 } 113 114 if (pass) 115 return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str()); 116 else 117 return tcu::TestStatus::fail("All depth/stencil formats are unsupported"); 118} 119 120class DepthTest : public vkt::TestCase 121{ 122public: 123 enum 124 { 125 QUAD_COUNT = 4 126 }; 127 128 static const float quadDepths[QUAD_COUNT]; 129 static const float quadDepthsMinusOneToOne[QUAD_COUNT]; 130 static const float quadWs[QUAD_COUNT]; 131 132 DepthTest (tcu::TestContext& testContext, 133 const std::string& name, 134 const PipelineConstructionType pipelineConstructionType, 135 const VkFormat depthFormat, 136 const VkCompareOp depthCompareOps[QUAD_COUNT], 137 const bool separateDepthStencilLayouts, 138 const VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 139 const bool depthBoundsTestEnable = false, 140 const float depthBoundsMin = 0.0f, 141 const float depthBoundsMax = 1.0f, 142 const bool depthTestEnable = true, 143 const bool stencilTestEnable = false, 144 const bool colorAttachmentEnable = true, 145 const bool hostVisible = false, 146 const tcu::UVec2 renderSize = tcu::UVec2(32, 32), 147 const DepthClipControlCase depthClipControl = DepthClipControlCase::DISABLED); 148 virtual ~DepthTest (void); 149 virtual void initPrograms (SourceCollections& programCollection) const; 150 virtual void checkSupport (Context& context) const; 151 virtual TestInstance* createInstance (Context& context) const; 152 153private: 154 const PipelineConstructionType m_pipelineConstructionType; 155 const VkFormat m_depthFormat; 156 const bool m_separateDepthStencilLayouts; 157 VkPrimitiveTopology m_primitiveTopology; 158 const bool m_depthBoundsTestEnable; 159 const float m_depthBoundsMin; 160 const float m_depthBoundsMax; 161 const bool m_depthTestEnable; 162 const bool m_stencilTestEnable; 163 const bool m_colorAttachmentEnable; 164 const bool m_hostVisible; 165 const tcu::UVec2 m_renderSize; 166 const DepthClipControlCase m_depthClipControl; 167 VkCompareOp m_depthCompareOps[QUAD_COUNT]; 168}; 169 170class DepthTestInstance : public vkt::TestInstance 171{ 172public: 173 DepthTestInstance (Context& context, 174 const PipelineConstructionType pipelineConstructionType, 175 const VkFormat depthFormat, 176 const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT], 177 const bool separateDepthStencilLayouts, 178 const VkPrimitiveTopology primitiveTopology, 179 const bool depthBoundsTestEnable, 180 const float depthBoundsMin, 181 const float depthBoundsMax, 182 const bool depthTestEnable, 183 const bool stencilTestEnable, 184 const bool colorAttachmentEnable, 185 const bool hostVisible, 186 const tcu::UVec2 renderSize, 187 const DepthClipControlCase depthClipControl); 188 189 virtual ~DepthTestInstance (void); 190 virtual tcu::TestStatus iterate (void); 191 192private: 193 tcu::TestStatus verifyImage (void); 194 195private: 196 VkCompareOp m_depthCompareOps[DepthTest::QUAD_COUNT]; 197 const tcu::UVec2 m_renderSize; 198 const VkFormat m_colorFormat; 199 const VkFormat m_depthFormat; 200 const bool m_separateDepthStencilLayouts; 201 VkPrimitiveTopology m_primitiveTopology; 202 const bool m_depthBoundsTestEnable; 203 const float m_depthBoundsMin; 204 const float m_depthBoundsMax; 205 const bool m_depthTestEnable; 206 const bool m_stencilTestEnable; 207 const bool m_colorAttachmentEnable; 208 const bool m_hostVisible; 209 const DepthClipControlCase m_depthClipControl; 210 VkImageSubresourceRange m_depthImageSubresourceRange; 211 212 Move<VkImage> m_colorImage; 213 de::MovePtr<Allocation> m_colorImageAlloc; 214 Move<VkImage> m_depthImage; 215 de::MovePtr<Allocation> m_depthImageAlloc; 216 Move<VkImageView> m_colorAttachmentView; 217 Move<VkImageView> m_depthAttachmentView; 218 RenderPassWrapper m_renderPass; 219 Move<VkFramebuffer> m_framebuffer; 220 221 ShaderWrapper m_vertexShaderModule; 222 ShaderWrapper m_fragmentShaderModule; 223 224 Move<VkBuffer> m_vertexBuffer; 225 std::vector<Vertex4RGBA> m_vertices; 226 de::MovePtr<Allocation> m_vertexBufferAlloc; 227 228 Move<VkBuffer> m_altVertexBuffer; 229 std::vector<Vertex4RGBA> m_altVertices; 230 de::MovePtr<Allocation> m_altVertexBufferAlloc; 231 232 PipelineLayoutWrapper m_pipelineLayout; 233 GraphicsPipelineWrapper m_graphicsPipelines[DepthTest::QUAD_COUNT]; 234 GraphicsPipelineWrapper m_altGraphicsPipelines[DepthTest::QUAD_COUNT]; 235 236 Move<VkCommandPool> m_cmdPool; 237 Move<VkCommandBuffer> m_cmdBuffer; 238}; 239 240const float DepthTest::quadDepths[QUAD_COUNT] = 241{ 242 0.1f, 243 0.0f, 244 0.3f, 245 0.2f 246}; 247 248// Depth values suitable for the depth range of -1..1. 249const float DepthTest::quadDepthsMinusOneToOne[QUAD_COUNT] = 250{ 251 -0.8f, 252 -1.0f, 253 0.6f, 254 0.2f 255}; 256 257const float DepthTest::quadWs[QUAD_COUNT] = 258{ 259 2.0f, 260 1.25f, 261 0.5f, 262 0.25f 263}; 264 265DepthTest::DepthTest (tcu::TestContext& testContext, 266 const std::string& name, 267 const PipelineConstructionType pipelineConstructionType, 268 const VkFormat depthFormat, 269 const VkCompareOp depthCompareOps[QUAD_COUNT], 270 const bool separateDepthStencilLayouts, 271 const VkPrimitiveTopology primitiveTopology, 272 const bool depthBoundsTestEnable, 273 const float depthBoundsMin, 274 const float depthBoundsMax, 275 const bool depthTestEnable, 276 const bool stencilTestEnable, 277 const bool colorAttachmentEnable, 278 const bool hostVisible, 279 const tcu::UVec2 renderSize, 280 const DepthClipControlCase depthClipControl) 281 : vkt::TestCase (testContext, name) 282 , m_pipelineConstructionType (pipelineConstructionType) 283 , m_depthFormat (depthFormat) 284 , m_separateDepthStencilLayouts (separateDepthStencilLayouts) 285 , m_primitiveTopology (primitiveTopology) 286 , m_depthBoundsTestEnable (depthBoundsTestEnable) 287 , m_depthBoundsMin (depthBoundsMin) 288 , m_depthBoundsMax (depthBoundsMax) 289 , m_depthTestEnable (depthTestEnable) 290 , m_stencilTestEnable (stencilTestEnable) 291 , m_colorAttachmentEnable (colorAttachmentEnable) 292 , m_hostVisible (hostVisible) 293 , m_renderSize (renderSize) 294 , m_depthClipControl (depthClipControl) 295{ 296 deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT); 297} 298 299DepthTest::~DepthTest (void) 300{ 301} 302 303void DepthTest::checkSupport (Context& context) const 304{ 305 if (m_depthBoundsTestEnable) 306 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS); 307 308 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat)) 309 throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat)); 310 311 if (m_separateDepthStencilLayouts && !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts")) 312 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported"); 313 314 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 315 316#ifndef CTS_USES_VULKANSC 317 if (m_depthClipControl != DepthClipControlCase::DISABLED && !context.isDeviceFunctionalitySupported("VK_EXT_depth_clip_control")) 318 TCU_THROW(NotSupportedError, "VK_EXT_depth_clip_control is not supported"); 319#endif // CTS_USES_VULKANSC 320} 321 322TestInstance* DepthTest::createInstance (Context& context) const 323{ 324 return new DepthTestInstance(context, m_pipelineConstructionType, m_depthFormat, m_depthCompareOps, m_separateDepthStencilLayouts, m_primitiveTopology, m_depthBoundsTestEnable, m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable, m_colorAttachmentEnable, m_hostVisible, m_renderSize, m_depthClipControl); 325} 326 327void DepthTest::initPrograms (SourceCollections& programCollection) const 328{ 329 if (m_colorAttachmentEnable) 330 { 331 programCollection.glslSources.add("color_vert") << glu::VertexSource( 332 "#version 310 es\n" 333 "layout(location = 0) in vec4 position;\n" 334 "layout(location = 1) in vec4 color;\n" 335 "layout(location = 0) out highp vec4 vtxColor;\n" 336 "void main (void)\n" 337 "{\n" 338 " gl_Position = position;\n" 339 " gl_PointSize = 1.0f;\n" 340 " vtxColor = color;\n" 341 "}\n"); 342 343 programCollection.glslSources.add("color_frag") << glu::FragmentSource( 344 "#version 310 es\n" 345 "layout(location = 0) in highp vec4 vtxColor;\n" 346 "layout(location = 0) out highp vec4 fragColor;\n" 347 "void main (void)\n" 348 "{\n" 349 " fragColor = vtxColor;\n" 350 "}\n"); 351 } 352 else 353 { 354 programCollection.glslSources.add("color_vert") << glu::VertexSource( 355 "#version 310 es\n" 356 "layout(location = 0) in vec4 position;\n" 357 "layout(location = 1) in vec4 color;\n" 358 "void main (void)\n" 359 "{\n" 360 " gl_Position = position;\n" 361 " gl_PointSize = 1.0f;\n" 362 "}\n"); 363 } 364} 365 366DepthTestInstance::DepthTestInstance (Context& context, 367 const PipelineConstructionType pipelineConstructionType, 368 const VkFormat depthFormat, 369 const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT], 370 const bool separateDepthStencilLayouts, 371 const VkPrimitiveTopology primitiveTopology, 372 const bool depthBoundsTestEnable, 373 const float depthBoundsMin, 374 const float depthBoundsMax, 375 const bool depthTestEnable, 376 const bool stencilTestEnable, 377 const bool colorAttachmentEnable, 378 const bool hostVisible, 379 const tcu::UVec2 renderSize, 380 const DepthClipControlCase depthClipControl) 381 : vkt::TestInstance (context) 382 , m_renderSize (renderSize) 383 , m_colorFormat (colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED) 384 , m_depthFormat (depthFormat) 385 , m_separateDepthStencilLayouts (separateDepthStencilLayouts) 386 , m_primitiveTopology (primitiveTopology) 387 , m_depthBoundsTestEnable (depthBoundsTestEnable) 388 , m_depthBoundsMin (depthBoundsMin) 389 , m_depthBoundsMax (depthBoundsMax) 390 , m_depthTestEnable (depthTestEnable) 391 , m_stencilTestEnable (stencilTestEnable) 392 , m_colorAttachmentEnable (colorAttachmentEnable) 393 , m_hostVisible (hostVisible) 394 , m_depthClipControl (depthClipControl) 395 , m_graphicsPipelines 396 { 397 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType }, 398 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType }, 399 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType }, 400 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType } 401 } 402 , m_altGraphicsPipelines 403 { 404 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType }, 405 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType }, 406 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType }, 407 { context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType } 408 } 409{ 410 const DeviceInterface& vk = context.getDeviceInterface(); 411 const VkDevice vkDevice = context.getDevice(); 412 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 413 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 414 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 415 const bool hasDepthClipControl = (m_depthClipControl != DepthClipControlCase::DISABLED); 416 const bool useAltGraphicsPipelines = (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS || 417 m_depthClipControl == DepthClipControlCase::NORMAL_W); 418 const bool useAltVertices = m_depthClipControl == DepthClipControlCase::NORMAL_W; 419 420 // Copy depth operators 421 deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT); 422 423 // Create color image 424 if (m_colorAttachmentEnable) 425 { 426 const VkImageCreateInfo colorImageParams = 427 { 428 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 429 DE_NULL, // const void* pNext; 430 0u, // VkImageCreateFlags flags; 431 VK_IMAGE_TYPE_2D, // VkImageType imageType; 432 m_colorFormat, // VkFormat format; 433 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 434 1u, // deUint32 mipLevels; 435 1u, // deUint32 arrayLayers; 436 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 437 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 438 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 439 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 440 1u, // deUint32 queueFamilyIndexCount; 441 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 442 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 443 }; 444 445 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 446 447 // Allocate and bind color image memory 448 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 449 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 450 } 451 452 // Create depth image 453 { 454 const VkImageCreateInfo depthImageParams = 455 { 456 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 457 DE_NULL, // const void* pNext; 458 0u, // VkImageCreateFlags flags; 459 VK_IMAGE_TYPE_2D, // VkImageType imageType; 460 m_depthFormat, // VkFormat format; 461 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 462 1u, // deUint32 mipLevels; 463 1u, // deUint32 arrayLayers; 464 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 465 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 466 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | 467 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 468 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 469 1u, // deUint32 queueFamilyIndexCount; 470 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 471 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 472 }; 473 474 m_depthImage = createImage(vk, vkDevice, &depthImageParams); 475 476 // Allocate and bind depth image memory 477 auto memReqs = MemoryRequirement::Local | MemoryRequirement::HostVisible; 478 m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), m_hostVisible ? memReqs : MemoryRequirement::Any); 479 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset())); 480 481 const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT 482 : VK_IMAGE_ASPECT_DEPTH_BIT); 483 m_depthImageSubresourceRange = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers); 484 } 485 486 // Create color attachment view 487 if (m_colorAttachmentEnable) 488 { 489 const VkImageViewCreateInfo colorAttachmentViewParams = 490 { 491 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 492 DE_NULL, // const void* pNext; 493 0u, // VkImageViewCreateFlags flags; 494 *m_colorImage, // VkImage image; 495 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 496 m_colorFormat, // VkFormat format; 497 componentMappingRGBA, // VkComponentMapping components; 498 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 499 }; 500 501 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 502 } 503 504 // Create depth attachment view 505 { 506 const VkImageViewCreateInfo depthAttachmentViewParams = 507 { 508 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 509 DE_NULL, // const void* pNext; 510 0u, // VkImageViewCreateFlags flags; 511 *m_depthImage, // VkImage image; 512 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 513 m_depthFormat, // VkFormat format; 514 componentMappingRGBA, // VkComponentMapping components; 515 m_depthImageSubresourceRange, // VkImageSubresourceRange subresourceRange; 516 }; 517 518 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams); 519 } 520 521 // Create render pass 522 m_renderPass = RenderPassWrapper(pipelineConstructionType, vk, vkDevice, m_colorFormat, m_depthFormat); 523 524 // Create framebuffer 525 { 526 std::vector<VkImage> images; 527 std::vector<VkImageView> attachmentBindInfos; 528 529 if (m_colorAttachmentEnable) 530 { 531 images.push_back(*m_colorImage); 532 attachmentBindInfos.push_back(*m_colorAttachmentView); 533 } 534 535 images.push_back(*m_depthImage); 536 attachmentBindInfos.push_back(*m_depthAttachmentView); 537 538 const VkFramebufferCreateInfo framebufferParams = 539 { 540 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 541 DE_NULL, // const void* pNext; 542 0u, // VkFramebufferCreateFlags flags; 543 *m_renderPass, // VkRenderPass renderPass; 544 (deUint32)attachmentBindInfos.size(), // deUint32 attachmentCount; 545 attachmentBindInfos.data(), // const VkImageView* pAttachments; 546 (deUint32)m_renderSize.x(), // deUint32 width; 547 (deUint32)m_renderSize.y(), // deUint32 height; 548 1u // deUint32 layers; 549 }; 550 551 m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images); 552 } 553 554 // Create pipeline layout 555 { 556 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 557 { 558 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 559 DE_NULL, // const void* pNext; 560 0u, // VkPipelineLayoutCreateFlags flags; 561 0u, // deUint32 setLayoutCount; 562 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 563 0u, // deUint32 pushConstantRangeCount; 564 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 565 }; 566 567 m_pipelineLayout = PipelineLayoutWrapper(pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams); 568 } 569 570 // Shader modules 571 m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 572 if (m_colorAttachmentEnable) 573 m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 574 575 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) }; 576 const std::vector<VkViewport> badViewports { makeViewport(0.0f, 0.0f, static_cast<float>(m_renderSize.x()) / 2.0f, static_cast<float>(m_renderSize.y()) / 2.0f, 1.0f, 0.0f) }; 577 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) }; 578 const bool dynamicViewport = (static_cast<int>(m_depthClipControl) > static_cast<int>(DepthClipControlCase::BEFORE_STATIC)); 579 580 // Create pipeline 581 { 582 const VkVertexInputBindingDescription vertexInputBindingDescription 583 { 584 0u, // deUint32 binding; 585 sizeof(Vertex4RGBA), // deUint32 strideInBytes; 586 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate; 587 }; 588 589 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] 590 { 591 { 592 0u, // deUint32 location; 593 0u, // deUint32 binding; 594 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 595 0u // deUint32 offset; 596 }, 597 { 598 1u, // deUint32 location; 599 0u, // deUint32 binding; 600 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 601 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset; 602 } 603 }; 604 605 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams 606 { 607 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 608 DE_NULL, // const void* pNext; 609 0u, // VkPipelineVertexInputStateCreateFlags flags; 610 1u, // deUint32 vertexBindingDescriptionCount; 611 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 612 2u, // deUint32 vertexAttributeDescriptionCount; 613 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 614 }; 615 616 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams 617 { 618 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType 619 DE_NULL, // const void* pNext 620 0u, // VkPipelineInputAssemblyStateCreateFlags flags 621 m_primitiveTopology, // VkPrimitiveTopology topology 622 VK_FALSE // VkBool32 primitiveRestartEnable 623 }; 624 625 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams 626 { 627 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 628 DE_NULL, // const void* pNext; 629 0u, // VkPipelineDepthStencilStateCreateFlags flags; 630 m_depthTestEnable, // VkBool32 depthTestEnable; 631 true, // VkBool32 depthWriteEnable; 632 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 633 m_depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable; 634 m_stencilTestEnable, // VkBool32 stencilTestEnable; 635 // VkStencilOpState front; 636 { 637 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 638 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 639 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 640 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 641 0u, // deUint32 compareMask; 642 0u, // deUint32 writeMask; 643 0u, // deUint32 reference; 644 }, 645 // VkStencilOpState back; 646 { 647 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 648 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 649 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 650 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 651 0u, // deUint32 compareMask; 652 0u, // deUint32 writeMask; 653 0u, // deUint32 reference; 654 }, 655 m_depthBoundsMin, // float minDepthBounds; 656 m_depthBoundsMax, // float maxDepthBounds; 657 }; 658 659 // Make sure rasterization is not disabled when the fragment shader is missing. 660 const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateParams 661 { 662 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 663 nullptr, // const void* pNext; 664 0u, // VkPipelineRasterizationStateCreateFlags flags; 665 VK_FALSE, // VkBool32 depthClampEnable; 666 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 667 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 668 vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 669 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 670 VK_FALSE, // VkBool32 depthBiasEnable; 671 0.0f, // float depthBiasConstantFactor; 672 0.0f, // float depthBiasClamp; 673 0.0f, // float depthBiasSlopeFactor; 674 1.0f, // float lineWidth; 675 }; 676 677 PipelineViewportDepthClipControlCreateInfoWrapper depthClipControlWrapper; 678 PipelineViewportDepthClipControlCreateInfoWrapper depthClipControl01Wrapper; 679 680#ifndef CTS_USES_VULKANSC 681 VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo 682 { 683 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType; 684 DE_NULL, // const void* pNext; 685 VK_TRUE, // VkBool32 negativeOneToOne; 686 }; 687 if (hasDepthClipControl) 688 depthClipControlWrapper.ptr = &depthClipControlCreateInfo; 689 690 // Using the range 0,1 in the structure. 691 VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo01 692 { 693 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType; 694 DE_NULL, // const void* pNext; 695 VK_FALSE, // VkBool32 negativeOneToOne; 696 }; 697 depthClipControl01Wrapper.ptr = &depthClipControlCreateInfo01; 698#endif // CTS_USES_VULKANSC 699 700 // Dynamic viewport if needed. 701 std::vector<VkDynamicState> dynamicStates; 702 703 if (m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC 704 || m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS 705 || m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC) 706 { 707 dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT); 708 } 709 710 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = 711 { 712 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 713 nullptr, // const void* pNext; 714 0u, // VkPipelineDynamicStateCreateFlags flags; 715 static_cast<uint32_t>(dynamicStates.size()), // uint32_t dynamicStateCount; 716 de::dataOrNull(dynamicStates), // const VkDynamicState* pDynamicStates; 717 }; 718 719 const vk::VkPipelineColorBlendAttachmentState blendState 720 { 721 VK_FALSE, 722 VK_BLEND_FACTOR_ONE, 723 VK_BLEND_FACTOR_ONE, 724 VK_BLEND_OP_ADD, 725 VK_BLEND_FACTOR_ONE, 726 VK_BLEND_FACTOR_ONE, 727 VK_BLEND_OP_ADD, 728 VK_COLOR_COMPONENT_R_BIT | 729 VK_COLOR_COMPONENT_G_BIT | 730 VK_COLOR_COMPONENT_B_BIT | 731 VK_COLOR_COMPONENT_A_BIT, 732 }; 733 734 deUint32 colorAttachmentCount = (m_colorFormat != VK_FORMAT_UNDEFINED) ? 1u : 0u; 735 736 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo 737 { 738 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType 739 DE_NULL, // const void* pNext 740 0u, // VkPipelineColorBlendStateCreateFlags flags 741 VK_FALSE, // VkBool32 logicOpEnable 742 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp 743 colorAttachmentCount, // deUint32 attachmentCount 744 &blendState, // const VkPipelineColorBlendAttachmentState* pAttachments 745 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4] 746 }; 747 748 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++) 749 { 750 depthStencilStateParams.depthCompareOp = depthCompareOps[quadNdx]; 751 752 m_graphicsPipelines[quadNdx].setDefaultMultisampleState() 753 .setDefaultColorBlendState() 754 .setViewportStatePnext(depthClipControlWrapper.ptr) 755 .setDynamicState(&dynamicStateCreateInfo) 756 .setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams) 757 .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), 758 scissors, 759 m_pipelineLayout, 760 *m_renderPass, 761 0u, 762 m_vertexShaderModule, 763 &rasterizationStateParams) 764 .setupFragmentShaderState(m_pipelineLayout, 765 *m_renderPass, 766 0u, 767 m_fragmentShaderModule, 768 &depthStencilStateParams) 769 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo) 770 .setMonolithicPipelineLayout(m_pipelineLayout) 771 .buildPipeline(); 772 773 if (useAltGraphicsPipelines) 774 { 775 if (m_depthClipControl == DepthClipControlCase::NORMAL_W) 776 { 777 m_altGraphicsPipelines[quadNdx].setDefaultMultisampleState() 778 .setDefaultColorBlendState() 779 .setViewportStatePnext(depthClipControl01Wrapper.ptr) 780 .setDynamicState(&dynamicStateCreateInfo) 781 .setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams) 782 .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), 783 scissors, 784 m_pipelineLayout, 785 *m_renderPass, 786 0u, 787 m_vertexShaderModule, 788 &rasterizationStateParams) 789 .setupFragmentShaderState(m_pipelineLayout, 790 *m_renderPass, 791 0u, 792 m_fragmentShaderModule, 793 &depthStencilStateParams) 794 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo) 795 .setMonolithicPipelineLayout(m_pipelineLayout) 796 .buildPipeline(); 797 } 798 else 799 { 800 m_altGraphicsPipelines[quadNdx].setDefaultMultisampleState() 801 .setDefaultColorBlendState() 802 .setViewportStatePnext(depthClipControl01Wrapper.ptr) 803 .setDynamicState(&dynamicStateCreateInfo) 804 .setupVertexInputState(&vertexInputStateParams) 805 .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), 806 scissors, 807 m_pipelineLayout, 808 *m_renderPass, 809 0u, 810 m_vertexShaderModule, 811 &rasterizationStateParams) 812 .setupFragmentShaderState(m_pipelineLayout, 813 *m_renderPass, 814 0u, 815 m_fragmentShaderModule, 816 &depthStencilStateParams) 817 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo) 818 .setMonolithicPipelineLayout(m_pipelineLayout) 819 .buildPipeline(); 820 } 821 } 822 } 823 } 824 825 // Create vertex buffer 826 { 827 const VkBufferCreateInfo vertexBufferParams = 828 { 829 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 830 DE_NULL, // const void* pNext; 831 0u, // VkBufferCreateFlags flags; 832 1024u, // VkDeviceSize size; 833 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 834 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 835 1u, // deUint32 queueFamilyIndexCount; 836 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 837 }; 838 839 m_vertices = createOverlappingQuads(); 840 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 841 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 842 843 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 844 845 if (useAltVertices) { 846 m_altVertices = createOverlappingQuads(); 847 m_altVertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 848 m_altVertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_altVertexBuffer), MemoryRequirement::HostVisible); 849 850 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_altVertexBuffer, m_altVertexBufferAlloc->getMemory(), m_altVertexBufferAlloc->getOffset())); 851 } 852 853 // Adjust depths 854 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++) 855 for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++) 856 { 857 m_vertices[quadNdx * 6 + vertexNdx].position.z() = (hasDepthClipControl ? DepthTest::quadDepthsMinusOneToOne[quadNdx] : DepthTest::quadDepths[quadNdx]); 858 if (m_depthClipControl == DepthClipControlCase::NORMAL_W) 859 { 860 const float w = DepthTest::quadWs[quadNdx]; 861 m_vertices[quadNdx * 6 + vertexNdx].position.x() *= w; 862 m_vertices[quadNdx * 6 + vertexNdx].position.y() *= w; 863 m_vertices[quadNdx * 6 + vertexNdx].position.z() *= w; 864 m_vertices[quadNdx * 6 + vertexNdx].position.w() = w; 865 } 866 if (useAltVertices) 867 { 868 m_altVertices[quadNdx * 6 + vertexNdx].position = m_vertices[quadNdx * 6 + vertexNdx].position; 869 float z = m_altVertices[quadNdx * 6 + vertexNdx].position.z(); 870 float w = m_altVertices[quadNdx * 6 + vertexNdx].position.w(); 871 if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_NOT_EQUAL || 872 depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS || 873 depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS_OR_EQUAL) 874 { 875 z += 0.01f; 876 } 877 else if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER || 878 depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER_OR_EQUAL) 879 { 880 z -= 0.01f; 881 } 882 m_altVertices[quadNdx * 6 + vertexNdx].position.z() = (z + w) * 0.5f; 883 } 884 } 885 886 // Load vertices into vertex buffer 887 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA)); 888 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc); 889 890 if (useAltVertices) { 891 deMemcpy(m_altVertexBufferAlloc->getHostPtr(), m_altVertices.data(), m_altVertices.size() * sizeof(Vertex4RGBA)); 892 flushAlloc(vk, vkDevice, *m_altVertexBufferAlloc); 893 } 894 } 895 896 // Create command pool 897 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 898 899 // Create command buffer 900 { 901 std::vector<VkClearValue> attachmentClearValues; 902 903 if (m_colorAttachmentEnable) 904 attachmentClearValues.push_back(defaultClearValue(m_colorFormat)); 905 906 attachmentClearValues.push_back(defaultClearValue(m_depthFormat)); 907 908 const VkImageMemoryBarrier colorBarrier = 909 { 910 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 911 DE_NULL, // const void* pNext; 912 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 913 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 914 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 915 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 916 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 917 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 918 *m_colorImage, // VkImage image; 919 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 920 }; 921 922 VkImageSubresourceRange depthBarrierSubresourceRange = m_depthImageSubresourceRange; 923 VkImageLayout newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 924 if (m_separateDepthStencilLayouts) 925 { 926 depthBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 927 newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; 928 } 929 930 const VkImageMemoryBarrier depthBarrier = 931 { 932 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 933 DE_NULL, // const void* pNext; 934 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 935 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 936 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 937 newLayout , // VkImageLayout newLayout; 938 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 939 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 940 *m_depthImage, // VkImage image; 941 depthBarrierSubresourceRange, // VkImageSubresourceRange subresourceRange; 942 }; 943 944 std::vector<VkImageMemoryBarrier> imageLayoutBarriers; 945 946 if (m_colorAttachmentEnable) 947 imageLayoutBarriers.push_back(colorBarrier); 948 949 imageLayoutBarriers.push_back(depthBarrier); 950 951 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 952 953 beginCommandBuffer(vk, *m_cmdBuffer, 0u); 954 955 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 956 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0, 957 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data()); 958 959 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data()); 960 961 const VkDeviceSize quadOffset = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA); 962 963 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++) 964 { 965 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx; 966 967 if (m_depthClipControl == DepthClipControlCase::NORMAL_W && depthCompareOps[quadNdx] != vk::VK_COMPARE_OP_NEVER) 968 { 969 m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer); 970 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_altVertexBuffer.get(), &vertexBufferOffset); 971 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_altVertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0); 972 } 973 974 if (m_depthClipControl == DepthClipControlCase::BEFORE_STATIC 975 || m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC 976 || m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS) 977 { 978 if (vk::isConstructionTypeShaderObject(pipelineConstructionType)) 979 { 980#ifndef CTS_USES_VULKANSC 981 vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data()); 982#else 983 vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data()); 984#endif 985 } 986 else 987 { 988 vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data()); 989 } 990 } 991 992 if (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS) 993 m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer); 994 m_graphicsPipelines[quadNdx].bind(*m_cmdBuffer); 995 996 if (m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC) 997 { 998 if (vk::isConstructionTypeShaderObject(pipelineConstructionType)) 999 { 1000#ifndef CTS_USES_VULKANSC 1001 vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data()); 1002#else 1003 vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data()); 1004#endif 1005 } 1006 else 1007 { 1008 vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data()); 1009 } 1010 } 1011 1012 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 1013 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0); 1014 } 1015 1016 m_renderPass.end(vk, *m_cmdBuffer); 1017 endCommandBuffer(vk, *m_cmdBuffer); 1018 } 1019} 1020 1021DepthTestInstance::~DepthTestInstance (void) 1022{ 1023} 1024 1025tcu::TestStatus DepthTestInstance::iterate (void) 1026{ 1027 const DeviceInterface& vk = m_context.getDeviceInterface(); 1028 const VkDevice vkDevice = m_context.getDevice(); 1029 const VkQueue queue = m_context.getUniversalQueue(); 1030 1031 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 1032 1033 return verifyImage(); 1034} 1035 1036tcu::TestStatus DepthTestInstance::verifyImage (void) 1037{ 1038 const tcu::TextureFormat tcuColorFormat = mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM); 1039 const tcu::TextureFormat tcuDepthFormat = mapVkFormat(m_depthFormat); 1040 const ColorVertexShader vertexShader; 1041 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat, (m_depthClipControl != DepthClipControlCase::DISABLED)); 1042 const rr::Program program (&vertexShader, &fragmentShader); 1043 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 1044 bool colorCompareOk = false; 1045 bool depthCompareOk = false; 1046 1047 // Render reference image 1048 { 1049 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++) 1050 { 1051 // Set depth state 1052 rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits); 1053 renderState.fragOps.depthTestEnabled = m_depthTestEnable; 1054 renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]); 1055 if (m_depthBoundsTestEnable) 1056 { 1057 renderState.fragOps.depthBoundsTestEnabled = true; 1058 renderState.fragOps.minDepthBound = m_depthBoundsMin; 1059 renderState.fragOps.maxDepthBound = m_depthBoundsMax; 1060 } 1061 1062 refRenderer.draw(renderState, 1063 mapVkPrimitiveTopology(m_primitiveTopology), 1064 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6, 1065 m_vertices.begin() + (quadNdx + 1) * 6)); 1066 } 1067 } 1068 1069 // Compare color result with reference image 1070 if (m_colorAttachmentEnable) 1071 { 1072 const DeviceInterface& vk = m_context.getDeviceInterface(); 1073 const VkDevice vkDevice = m_context.getDevice(); 1074 const VkQueue queue = m_context.getUniversalQueue(); 1075 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1076 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 1077 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize); 1078 1079 colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 1080 "IntImageCompare", 1081 "Image comparison", 1082 refRenderer.getAccess(), 1083 result->getAccess(), 1084 tcu::UVec4(2, 2, 2, 2), 1085 tcu::IVec3(1, 1, 0), 1086 true, 1087 tcu::COMPARE_LOG_RESULT); 1088 } 1089 else 1090 { 1091 colorCompareOk = true; 1092 } 1093 1094 // Compare depth result with reference image 1095 { 1096 const DeviceInterface& vk = m_context.getDeviceInterface(); 1097 const VkDevice vkDevice = m_context.getDevice(); 1098 const VkQueue queue = m_context.getUniversalQueue(); 1099 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1100 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 1101 de::MovePtr<tcu::TextureLevel> result = readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_depthFormat, m_renderSize); 1102 1103 { 1104 de::MovePtr<tcu::TextureLevel> convertedReferenceLevel; 1105 tcu::Maybe<tcu::TextureFormat> convertedFormat; 1106 1107 if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_24_8_REV) 1108 { 1109 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24); 1110 } 1111 else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_16_8_8) 1112 { 1113 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16); 1114 } 1115 else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV) 1116 { 1117 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT); 1118 } 1119 1120 if (convertedFormat) 1121 { 1122 convertedReferenceLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(*convertedFormat, refRenderer.getDepthStencilAccess().getSize().x(), refRenderer.getDepthStencilAccess().getSize().y())); 1123 tcu::copy(convertedReferenceLevel->getAccess(), refRenderer.getDepthStencilAccess()); 1124 } 1125 1126 float depthThreshold = 0.0f; 1127 1128 if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) 1129 { 1130 const tcu::IVec4 formatBits = tcu::getTextureFormatBitDepth(result->getFormat()); 1131 depthThreshold = 1.0f / static_cast<float>((1 << formatBits[0]) - 1); 1132 } 1133 else if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) 1134 { 1135 depthThreshold = 0.0000001f; 1136 } 1137 else 1138 TCU_FAIL("unrecognized format type class"); 1139 1140 depthCompareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), 1141 "DepthImageCompare", 1142 "Depth image comparison", 1143 convertedReferenceLevel ? convertedReferenceLevel->getAccess() : refRenderer.getDepthStencilAccess(), 1144 result->getAccess(), 1145 tcu::Vec4(depthThreshold, 0.0f, 0.0f, 0.0f), 1146 tcu::COMPARE_LOG_RESULT); 1147 } 1148 } 1149 1150 if (colorCompareOk && depthCompareOk) 1151 return tcu::TestStatus::pass("Result image matches reference"); 1152 else 1153 return tcu::TestStatus::fail("Image mismatch"); 1154} 1155 1156std::string getFormatCaseName (const VkFormat format) 1157{ 1158 const std::string fullName = getFormatName(format); 1159 1160 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_")); 1161 1162 return de::toLower(fullName.substr(10)); 1163} 1164 1165std::string getTopologyName (const VkPrimitiveTopology topology) { 1166 const std::string fullName = getPrimitiveTopologyName(topology); 1167 1168 DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_")); 1169 1170 return de::toLower(fullName.substr(22)); 1171} 1172 1173std::string getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT]) 1174{ 1175 std::ostringstream name; 1176 1177 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++) 1178 { 1179 const std::string fullOpName = getCompareOpName(quadDepthOps[quadNdx]); 1180 1181 DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_")); 1182 1183 name << de::toLower(fullOpName.substr(14)); 1184 1185 if (quadNdx < DepthTest::QUAD_COUNT - 1) 1186 name << "_"; 1187 } 1188 1189 return name.str(); 1190} 1191 1192} // anonymous 1193 1194tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 1195{ 1196 const VkFormat depthFormats[] = 1197 { 1198 VK_FORMAT_D16_UNORM, 1199 VK_FORMAT_X8_D24_UNORM_PACK32, 1200 VK_FORMAT_D32_SFLOAT, 1201 VK_FORMAT_D16_UNORM_S8_UINT, 1202 VK_FORMAT_D24_UNORM_S8_UINT, 1203 VK_FORMAT_D32_SFLOAT_S8_UINT 1204 }; 1205 1206 // Each entry configures the depth compare operators of QUAD_COUNT quads. 1207 // All entries cover pair-wise combinations of compare operators. 1208 const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] = 1209 { 1210 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL }, 1211 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER }, 1212 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL }, 1213 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1214 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS }, 1215 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS }, 1216 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER }, 1217 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL }, 1218 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS }, 1219 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL }, 1220 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER }, 1221 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL }, 1222 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL }, 1223 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS }, 1224 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1225 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS }, 1226 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS }, 1227 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER }, 1228 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL }, 1229 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1230 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER }, 1231 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER }, 1232 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL }, 1233 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL }, 1234 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1235 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL }, 1236 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS }, 1237 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL }, 1238 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER }, 1239 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL }, 1240 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL }, 1241 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS }, 1242 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS }, 1243 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1244 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER }, 1245 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1246 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL }, 1247 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER }, 1248 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL }, 1249 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL }, 1250 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS }, 1251 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS }, 1252 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS }, 1253 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL }, 1254 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER }, 1255 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL }, 1256 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL }, 1257 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1258 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER }, 1259 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS }, 1260 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS }, 1261 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER }, 1262 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL }, 1263 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL }, 1264 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS }, 1265 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER }, 1266 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL }, 1267 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL }, 1268 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL }, 1269 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER }, 1270 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER }, 1271 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER }, 1272 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL }, 1273 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS }, 1274 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER }, 1275 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER }, 1276 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1277 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL }, 1278 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS }, 1279 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER }, 1280 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL }, 1281 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL }, 1282 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS }, 1283 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER } 1284 }; 1285 1286 const bool colorAttachmentEnabled[] = { true, false }; 1287 1288 const VkPrimitiveTopology primitiveTopologies[] = { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST }; 1289 1290 de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth")); 1291 de::MovePtr<tcu::TestCaseGroup> noColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "nocolor")); 1292 1293 // Tests for format features 1294 if (!isConstructionTypeLibrary(pipelineConstructionType)) 1295 { 1296 de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features")); 1297 1298 // Formats that must be supported in all implementations 1299 addFunctionCase(formatFeaturesTests.get(), 1300 "support_d16_unorm", 1301 testSupportsDepthStencilFormat, 1302 VK_FORMAT_D16_UNORM); 1303 1304 // Sets where at least one of the formats must be supported 1305 const VkFormat depthOnlyFormats[] = { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT }; 1306 const VkFormat depthStencilFormats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT }; 1307 1308 addFunctionCase(formatFeaturesTests.get(), 1309 "support_d24_unorm_or_d32_sfloat", 1310 testSupportsAtLeastOneDepthStencilFormat, 1311 std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats))); 1312 1313 addFunctionCase(formatFeaturesTests.get(), 1314 "support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint", 1315 testSupportsAtLeastOneDepthStencilFormat, 1316 std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats))); 1317 1318 depthTests->addChild(formatFeaturesTests.release()); 1319 } 1320 1321 for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++) 1322 { 1323 const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx]; 1324 1325 // Tests for format and compare operators 1326 { 1327 // Uses different depth formats 1328 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format")); 1329 1330 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++) 1331 { 1332 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(depthFormats[formatNdx]).order); 1333 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(depthFormats[formatNdx]).order); 1334 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1; 1335 1336 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts) 1337 { 1338 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts); 1339 1340 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx, 1341 (getFormatCaseName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "")).c_str(), 1342 (std::string("Uses format ") + getFormatName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? " with separate depth/stencil layouts" : "")).c_str())); 1343 de::MovePtr<tcu::TestCaseGroup> compareOpsTests (new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators")); 1344 1345 for (size_t topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveTopologies); topologyNdx++) { 1346 const std::string topologyName = getTopologyName(primitiveTopologies[topologyNdx]) + "_"; 1347 for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++) 1348 { 1349 compareOpsTests->addChild(new DepthTest(testCtx, 1350 topologyName + getCompareOpsName(depthOps[opsNdx]), 1351 pipelineConstructionType, 1352 depthFormats[formatNdx], 1353 depthOps[opsNdx], 1354 useSeparateDepthStencilLayouts, 1355 primitiveTopologies[topologyNdx], 1356 false, 1357 0.0f, 1358 1.0f)); 1359 1360 compareOpsTests->addChild(new DepthTest(testCtx, 1361 topologyName + getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test", 1362 pipelineConstructionType, 1363 depthFormats[formatNdx], 1364 depthOps[opsNdx], 1365 useSeparateDepthStencilLayouts, 1366 primitiveTopologies[topologyNdx], 1367 true, 1368 0.1f, 1369 0.25f, 1370 true, 1371 false, 1372 colorEnabled)); 1373 } 1374 } 1375 // Special VkPipelineDepthStencilStateCreateInfo known to have issues 1376 { 1377 const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER }; 1378 1379 compareOpsTests->addChild(new DepthTest(testCtx, 1380 "never_zerodepthbounds_depthdisabled_stencilenabled", 1381 pipelineConstructionType, 1382 depthFormats[formatNdx], 1383 depthOpsSpecial, 1384 useSeparateDepthStencilLayouts, 1385 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1386 true, 1387 0.0f, 1388 0.0f, 1389 false, 1390 true, 1391 colorEnabled)); 1392 } 1393 formatTest->addChild(compareOpsTests.release()); 1394 1395 // Test case with depth test enabled, but depth write disabled 1396 de::MovePtr<tcu::TestCaseGroup> depthTestDisabled(new tcu::TestCaseGroup(testCtx, "depth_test_disabled")); 1397 { 1398 const VkCompareOp depthOpsDepthTestDisabled[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS }; 1399 depthTestDisabled->addChild(new DepthTest(testCtx, 1400 "depth_write_enabled", 1401 pipelineConstructionType, 1402 depthFormats[formatNdx], 1403 depthOpsDepthTestDisabled, 1404 useSeparateDepthStencilLayouts, 1405 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1406 false, /* depthBoundsTestEnable */ 1407 0.0f, /* depthBoundMin*/ 1408 1.0f, /* depthBoundMax*/ 1409 false, /* depthTestEnable */ 1410 false, /* stencilTestEnable */ 1411 colorEnabled /* colorAttachmentEnable */)); 1412 } 1413 formatTest->addChild(depthTestDisabled.release()); 1414 1415 // Test case with depth buffer placed in local memory 1416 de::MovePtr<tcu::TestCaseGroup> hostVisibleTests(new tcu::TestCaseGroup(testCtx, "host_visible", "Test for disabled depth test")); 1417 { 1418 const VkCompareOp hostVisibleOps[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS }; 1419 1420 // Depth buffer placed in local memory 1421 hostVisibleTests->addChild(new DepthTest(testCtx, 1422 "local_memory_depth_buffer", 1423 pipelineConstructionType, 1424 depthFormats[formatNdx], 1425 hostVisibleOps, 1426 useSeparateDepthStencilLayouts, 1427 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1428 false, /* depthBoundsTestEnable */ 1429 0.0f, /* depthBoundMin*/ 1430 1.0f, /* depthBoundMax*/ 1431 true, /* depthTestEnable */ 1432 false, /* stencilTestEnable */ 1433 colorEnabled, /* colorAttachmentEnable */ 1434 true, /* hostVisible */ 1435 tcu::UVec2(256, 256) /*renderSize*/)); 1436 } 1437 1438 formatTest->addChild(hostVisibleTests.release()); 1439 formatTests->addChild(formatTest.release()); 1440 } 1441 } 1442 if (colorEnabled) 1443 depthTests->addChild(formatTests.release()); 1444 else 1445 noColorAttachmentTests->addChild(formatTests.release()); 1446 } 1447 } 1448 depthTests->addChild(noColorAttachmentTests.release()); 1449 1450#ifndef CTS_USES_VULKANSC 1451 de::MovePtr<tcu::TestCaseGroup> depthClipControlTests (new tcu::TestCaseGroup(testCtx, "depth_clip_control", "Depth tests with depth clip control enabled")); 1452 { 1453 const VkCompareOp compareOps[] = { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS }; 1454 1455 const struct 1456 { 1457 const DepthClipControlCase viewportCase; 1458 const std::string suffix; 1459 } kViewportCases[] = 1460 { 1461 { DepthClipControlCase::NORMAL, "" }, 1462 { DepthClipControlCase::NORMAL_W, "_different_w" }, 1463 { DepthClipControlCase::BEFORE_STATIC, "_viewport_before_static" }, 1464 { DepthClipControlCase::BEFORE_DYNAMIC, "_viewport_before_dynamic" }, 1465 { DepthClipControlCase::BEFORE_TWO_DYNAMICS, "_viewport_before_two_dynamic" }, 1466 { DepthClipControlCase::AFTER_DYNAMIC, "_viewport_after_dynamic" }, 1467 }; 1468 1469 for (const auto& viewportCase : kViewportCases) 1470 for (const auto& format : depthFormats) 1471 for (const auto& compareOp : compareOps) 1472 { 1473 std::string testName = getFormatCaseName(format) + "_" + de::toLower(std::string(getCompareOpName(compareOp)).substr(14)) + viewportCase.suffix; 1474 1475 const VkCompareOp ops[DepthTest::QUAD_COUNT] = { compareOp, compareOp, compareOp, compareOp }; 1476 depthClipControlTests->addChild(new DepthTest(testCtx, testName, pipelineConstructionType, format, ops, 1477 false, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false, 0.0f, 1.0f, true, false, true, false, tcu::UVec2(32,32), viewportCase.viewportCase)); 1478 } 1479 } 1480 depthTests->addChild(depthClipControlTests.release()); 1481#endif // CTS_USES_VULKANSC 1482 1483 return depthTests.release(); 1484} 1485 1486} // pipeline 1487} // vkt 1488