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) 2017 Google Inc. 8 * Copyright (c) 2023 LunarG, Inc. 9 * Copyright (c) 2023 Nintendo 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 * 23 *//*! 24 * \file 25 * \brief Multisample Tests 26 *//*--------------------------------------------------------------------*/ 27 28#include "vktPipelineMultisampleTests.hpp" 29#include "vktPipelineMultisampleImageTests.hpp" 30#include "vktPipelineMultisampleSampleLocationsExtTests.hpp" 31#include "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp" 32#include "vktPipelineMultisampleResolveRenderAreaTests.hpp" 33#include "vktPipelineMultisampleShaderFragmentMaskTests.hpp" 34#include "vktPipelineMultisampledRenderToSingleSampledTests.hpp" 35#include "vktPipelineClearUtil.hpp" 36#include "vktPipelineImageUtil.hpp" 37#include "vktPipelineVertexUtil.hpp" 38#include "vktPipelineReferenceRenderer.hpp" 39#include "vktTestCase.hpp" 40#include "vktTestCaseUtil.hpp" 41#include "vkImageUtil.hpp" 42#include "vkMemUtil.hpp" 43#include "vkPrograms.hpp" 44#include "vkQueryUtil.hpp" 45#include "vkRef.hpp" 46#include "vkRefUtil.hpp" 47#include "vkCmdUtil.hpp" 48#include "vkTypeUtil.hpp" 49#include "vkObjUtil.hpp" 50#include "vkBufferWithMemory.hpp" 51#include "vkImageWithMemory.hpp" 52#include "vkBuilderUtil.hpp" 53#include "vkBarrierUtil.hpp" 54#include "tcuImageCompare.hpp" 55#include "tcuTestLog.hpp" 56#include "deUniquePtr.hpp" 57#include "deSharedPtr.hpp" 58#include "deStringUtil.hpp" 59#include "deMemory.h" 60 61#include <sstream> 62#include <vector> 63#include <map> 64#include <memory> 65#include <algorithm> 66#include <set> 67#include <array> 68#include <utility> 69 70namespace vkt 71{ 72namespace pipeline 73{ 74 75using namespace vk; 76 77namespace 78{ 79enum GeometryType 80{ 81 GEOMETRY_TYPE_OPAQUE_TRIANGLE, 82 GEOMETRY_TYPE_OPAQUE_LINE, 83 GEOMETRY_TYPE_OPAQUE_POINT, 84 GEOMETRY_TYPE_OPAQUE_QUAD, 85 GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH, //!< placed at z = 0.5 86 GEOMETRY_TYPE_TRANSLUCENT_QUAD, 87 GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 88 GEOMETRY_TYPE_INVISIBLE_QUAD, 89 GEOMETRY_TYPE_GRADIENT_QUAD 90}; 91 92enum TestModeBits 93{ 94 TEST_MODE_DEPTH_BIT = 1u, 95 TEST_MODE_STENCIL_BIT = 2u, 96}; 97typedef deUint32 TestModeFlags; 98 99enum RenderType 100{ 101 // resolve multisample rendering to single sampled image 102 RENDER_TYPE_RESOLVE = 0u, 103 104 // copy samples to an array of single sampled images 105 RENDER_TYPE_COPY_SAMPLES = 1u, 106 107 // render first with only depth/stencil and then with color + depth/stencil 108 RENDER_TYPE_DEPTHSTENCIL_ONLY = 2u, 109 110 // render using color attachment at location 1 and location 0 set as unused 111 RENDER_TYPE_UNUSED_ATTACHMENT = 3u, 112 113 // render using color attachment with single sample, required by alpha_to_one tests. 114 RENDER_TYPE_SINGLE_SAMPLE = 4u 115}; 116 117enum ImageBackingMode 118{ 119 IMAGE_BACKING_MODE_REGULAR = 0u, 120 IMAGE_BACKING_MODE_SPARSE 121}; 122 123struct MultisampleTestParams 124{ 125 PipelineConstructionType pipelineConstructionType; 126 GeometryType geometryType; 127 float pointSize; 128 ImageBackingMode backingMode; 129 bool useFragmentShadingRate; 130}; 131 132void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params); 133bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples); 134bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format); 135VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void); 136VkPipelineColorBlendAttachmentState getAlphaToCoverageBlendState (bool blendEnable); 137deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image); 138VkImageAspectFlags getImageAspectFlags (const VkFormat format); 139VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType); 140std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType); 141VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil); 142 143class MultisampleTest : public vkt::TestCase 144{ 145public: 146 147 MultisampleTest (tcu::TestContext& testContext, 148 const std::string& name, 149 PipelineConstructionType pipelineConstructionType, 150 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 151 const VkPipelineColorBlendAttachmentState& blendState, 152 GeometryType geometryType, 153 float pointSize, 154 ImageBackingMode backingMode, 155 const bool useFragmentShadingRate); 156 virtual ~MultisampleTest (void) {} 157 158 virtual void initPrograms (SourceCollections& programCollection) const; 159 virtual TestInstance* createInstance (Context& context) const; 160 virtual void checkSupport (Context& context) const; 161 162protected: 163 virtual TestInstance* createMultisampleTestInstance (Context& context, 164 VkPrimitiveTopology topology, 165 float pointSize, 166 const std::vector<Vertex4RGBA>& vertices, 167 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 168 const VkPipelineColorBlendAttachmentState& colorBlendState) const = 0; 169 170 const PipelineConstructionType m_pipelineConstructionType; 171 VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 172 const VkPipelineColorBlendAttachmentState m_colorBlendState; 173 const GeometryType m_geometryType; 174 const float m_pointSize; 175 const ImageBackingMode m_backingMode; 176 std::vector<VkSampleMask> m_sampleMask; 177 bool m_useFragmentShadingRate; 178}; 179 180class RasterizationSamplesTest : public MultisampleTest 181{ 182public: 183 RasterizationSamplesTest (tcu::TestContext& testContext, 184 const std::string& name, 185 PipelineConstructionType pipelineConstructionType, 186 VkSampleCountFlagBits rasterizationSamples, 187 GeometryType geometryType, 188 float pointSize, 189 ImageBackingMode backingMode, 190 TestModeFlags modeFlags, 191 const bool useFragmentShadingRate); 192 virtual ~RasterizationSamplesTest (void) {} 193 194protected: 195 virtual TestInstance* createMultisampleTestInstance (Context& context, 196 VkPrimitiveTopology topology, 197 float pointSize, 198 const std::vector<Vertex4RGBA>& vertices, 199 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 200 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 201 202 static VkPipelineMultisampleStateCreateInfo getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples); 203 204 const ImageBackingMode m_backingMode; 205 const TestModeFlags m_modeFlags; 206}; 207 208class MinSampleShadingTest : public MultisampleTest 209{ 210public: 211 MinSampleShadingTest (tcu::TestContext& testContext, 212 const std::string& name, 213 const PipelineConstructionType pipelineConstructionType, 214 VkSampleCountFlagBits rasterizationSamples, 215 float minSampleShading, 216 GeometryType geometryType, 217 float pointSize, 218 ImageBackingMode backingMode, 219 const bool minSampleShadingEnabled, 220 const bool useFragmentShadingRate); 221 virtual ~MinSampleShadingTest (void) {} 222 223protected: 224 virtual void initPrograms (SourceCollections& programCollection) const; 225 virtual void checkSupport (Context& context) const; 226 virtual TestInstance* createMultisampleTestInstance (Context& context, 227 VkPrimitiveTopology topology, 228 float pointSize, 229 const std::vector<Vertex4RGBA>& vertices, 230 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 231 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 232 233 static VkPipelineMultisampleStateCreateInfo getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, 234 float minSampleShading, 235 bool minSampleShadingEnabled); 236 237 const float m_pointSize; 238 const ImageBackingMode m_backingMode; 239 const bool m_minSampleShadingEnabled; 240}; 241 242class SampleMaskTest : public MultisampleTest 243{ 244public: 245 SampleMaskTest (tcu::TestContext& testContext, 246 const std::string& name, 247 const PipelineConstructionType pipelineConstructionType, 248 VkSampleCountFlagBits rasterizationSamples, 249 const std::vector<VkSampleMask>& sampleMask, 250 GeometryType geometryType, 251 float pointSize, 252 ImageBackingMode backingMode, 253 const bool useFragmentShadingRate); 254 255 virtual ~SampleMaskTest (void) {} 256 257protected: 258 virtual TestInstance* createMultisampleTestInstance (Context& context, 259 VkPrimitiveTopology topology, 260 float pointSize, 261 const std::vector<Vertex4RGBA>& vertices, 262 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 263 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 264 265 static VkPipelineMultisampleStateCreateInfo getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask); 266 267 const ImageBackingMode m_backingMode; 268}; 269 270class AlphaToOneTest : public MultisampleTest 271{ 272public: 273 AlphaToOneTest (tcu::TestContext& testContext, 274 const std::string& name, 275 const PipelineConstructionType pipelineConstructionType, 276 VkSampleCountFlagBits rasterizationSamples, 277 ImageBackingMode backingMode, 278 const bool useFragmentShadingRate); 279 280 virtual ~AlphaToOneTest (void) {} 281 282protected: 283 virtual void checkSupport (Context& context) const; 284 virtual TestInstance* createMultisampleTestInstance (Context& context, 285 VkPrimitiveTopology topology, 286 float pointSize, 287 const std::vector<Vertex4RGBA>& vertices, 288 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 289 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 290 291 static VkPipelineMultisampleStateCreateInfo getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples); 292 static VkPipelineColorBlendAttachmentState getAlphaToOneBlendState (void); 293 294 const ImageBackingMode m_backingMode; 295}; 296 297class AlphaToCoverageTest : public MultisampleTest 298{ 299public: 300 AlphaToCoverageTest (tcu::TestContext& testContext, 301 const std::string& name, 302 const PipelineConstructionType pipelineConstructionType, 303 VkSampleCountFlagBits rasterizationSamples, 304 GeometryType geometryType, 305 ImageBackingMode backingMode, 306 const bool useFragmentShadingRate, 307 const bool checkDepthBuffer); 308 309 virtual ~AlphaToCoverageTest (void) {} 310 void initPrograms (SourceCollections& programCollection) const override; 311 312protected: 313 TestInstance* createMultisampleTestInstance (Context& context, 314 VkPrimitiveTopology topology, 315 float pointSize, 316 const std::vector<Vertex4RGBA>& vertices, 317 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 318 const VkPipelineColorBlendAttachmentState& colorBlendState) const override; 319 320 static VkPipelineMultisampleStateCreateInfo getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples); 321 322 GeometryType m_geometryType; 323 const ImageBackingMode m_backingMode; 324 const bool m_checkDepthBuffer; 325}; 326 327class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest 328{ 329public: 330 AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext, 331 const std::string& name, 332 const PipelineConstructionType pipelineConstructionType, 333 VkSampleCountFlagBits rasterizationSamples, 334 GeometryType geometryType, 335 ImageBackingMode backingMode, 336 const bool useFragmentShadingRate); 337 338 virtual ~AlphaToCoverageNoColorAttachmentTest (void) {} 339 340protected: 341 virtual TestInstance* createMultisampleTestInstance (Context& context, 342 VkPrimitiveTopology topology, 343 float pointSize, 344 const std::vector<Vertex4RGBA>& vertices, 345 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 346 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 347 348 static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples); 349 350 GeometryType m_geometryType; 351 const ImageBackingMode m_backingMode; 352}; 353 354class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest 355{ 356public: 357 AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext, 358 const std::string& name, 359 const PipelineConstructionType pipelineConstructionType, 360 VkSampleCountFlagBits rasterizationSamples, 361 GeometryType geometryType, 362 ImageBackingMode backingMode, 363 const bool useFragmentShadingRate); 364 365 virtual ~AlphaToCoverageColorUnusedAttachmentTest (void) {} 366 367protected: 368 virtual void initPrograms (SourceCollections& programCollection) const; 369 370 virtual TestInstance* createMultisampleTestInstance (Context& context, 371 VkPrimitiveTopology topology, 372 float pointSize, 373 const std::vector<Vertex4RGBA>& vertices, 374 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 375 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 376 377 static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples); 378 379 GeometryType m_geometryType; 380 const ImageBackingMode m_backingMode; 381}; 382 383class SampleMaskWithConservativeTest : public vkt::TestCase 384{ 385 public: 386 SampleMaskWithConservativeTest(tcu::TestContext& testContext, 387 const std::string& name, 388 const PipelineConstructionType pipelineConstructionType, 389 const VkSampleCountFlagBits rasterizationSamples, 390 const VkConservativeRasterizationModeEXT conservativeRasterizationMode, 391 const bool enableMinSampleShading, 392 const float minSampleShading, 393 const bool enableSampleMask, 394 const VkSampleMask sampleMask, 395 const bool enablePostDepthCoverage, 396 const bool useFragmentShadingRate); 397 398 ~SampleMaskWithConservativeTest (void) {} 399 400 void initPrograms (SourceCollections& programCollection) const; 401 TestInstance* createInstance (Context& context) const; 402 virtual void checkSupport (Context& context) const; 403 404private: 405 const PipelineConstructionType m_pipelineConstructionType; 406 const VkSampleCountFlagBits m_rasterizationSamples; 407 const bool m_enableMinSampleShading; 408 float m_minSampleShading; 409 const bool m_enableSampleMask; 410 const VkSampleMask m_sampleMask; 411 const VkConservativeRasterizationModeEXT m_conservativeRasterizationMode; 412 const bool m_enablePostDepthCoverage; 413 const RenderType m_renderType; 414 const bool m_useFragmentShadingRate; 415}; 416#ifndef CTS_USES_VULKANSC 417class SampleMaskWithDepthTestTest : public vkt::TestCase 418{ 419public: 420 SampleMaskWithDepthTestTest (tcu::TestContext& testContext, 421 const std::string& name, 422 const PipelineConstructionType pipelineConstructionType, 423 const VkSampleCountFlagBits rasterizationSamples, 424 const bool enablePostDepthCoverage, 425 const bool useFragmentShadingRate); 426 427 ~SampleMaskWithDepthTestTest (void) {} 428 429 void initPrograms (SourceCollections& programCollection) const; 430 TestInstance* createInstance (Context& context) const; 431 virtual void checkSupport (Context& context) const; 432private: 433 const PipelineConstructionType m_pipelineConstructionType; 434 const VkSampleCountFlagBits m_rasterizationSamples; 435 const bool m_enablePostDepthCoverage; 436 const bool m_useFragmentShadingRate; 437}; 438#endif // CTS_USES_VULKANSC 439class MultisampleRenderer 440{ 441public: 442 443 MultisampleRenderer (Context& context, 444 PipelineConstructionType pipelineConstructionType, 445 const VkFormat colorFormat, 446 const tcu::IVec2& renderSize, 447 const VkPrimitiveTopology topology, 448 const std::vector<Vertex4RGBA>& vertices, 449 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 450 const VkPipelineColorBlendAttachmentState& blendState, 451 const RenderType renderType, 452 const ImageBackingMode backingMode, 453 const bool useFragmentShadingRate); 454 455 MultisampleRenderer (Context& context, 456 PipelineConstructionType pipelineConstructionType, 457 const VkFormat colorFormat, 458 const VkFormat depthStencilFormat, 459 const tcu::IVec2& renderSize, 460 const bool useDepth, 461 const bool useStencil, 462 const deUint32 numTopologies, 463 const VkPrimitiveTopology* pTopology, 464 const std::vector<Vertex4RGBA>* pVertices, 465 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 466 const VkPipelineColorBlendAttachmentState& blendState, 467 const RenderType renderType, 468 const ImageBackingMode backingMode, 469 const bool useFragmentShadingRate, 470 const float depthClearValue = 1.0f); 471 472 MultisampleRenderer (Context& context, 473 PipelineConstructionType pipelineConstructionType, 474 const VkFormat colorFormat, 475 const VkFormat depthStencilFormat, 476 const tcu::IVec2& renderSize, 477 const bool useDepth, 478 const bool useStencil, 479 const bool useConservative, 480 const bool useFragmentShadingRate, 481 const deUint32 numTopologies, 482 const VkPrimitiveTopology* pTopology, 483 const std::vector<Vertex4RGBA>* pVertices, 484 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 485 const VkPipelineColorBlendAttachmentState& blendState, 486 const VkPipelineRasterizationConservativeStateCreateInfoEXT& conservativeStateCreateInfo, 487 const RenderType renderType, 488 const ImageBackingMode backingMode, 489 const float depthClearValue = 1.0f); 490 491 virtual ~MultisampleRenderer (void); 492 493 de::MovePtr<tcu::TextureLevel> render (void); 494 de::MovePtr<tcu::TextureLevel> getSingleSampledImage (deUint32 sampleId); 495 de::MovePtr<tcu::TextureLevel> renderReusingDepth (); 496 497 498protected: 499 void initialize (Context& context, 500 const deUint32 numTopologies, 501 const VkPrimitiveTopology* pTopology, 502 const std::vector<Vertex4RGBA>* pVertices); 503 504 Context& m_context; 505 const PipelineConstructionType m_pipelineConstructionType; 506 507 const Unique<VkSemaphore> m_bindSemaphore; 508 509 const VkFormat m_colorFormat; 510 const VkFormat m_depthStencilFormat; 511 tcu::IVec2 m_renderSize; 512 const bool m_useDepth; 513 const bool m_useStencil; 514 const bool m_useConservative; 515 516 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 517 const VkPipelineColorBlendAttachmentState m_colorBlendState; 518 const VkPipelineRasterizationConservativeStateCreateInfoEXT m_rasterizationConservativeStateCreateInfo; 519 520 const RenderType m_renderType; 521 522 Move<VkImage> m_colorImage; 523 de::MovePtr<Allocation> m_colorImageAlloc; 524 Move<VkImageView> m_colorAttachmentView; 525 526 Move<VkImage> m_resolveImage; 527 de::MovePtr<Allocation> m_resolveImageAlloc; 528 Move<VkImageView> m_resolveAttachmentView; 529 530 struct PerSampleImage 531 { 532 Move<VkImage> m_image; 533 de::MovePtr<Allocation> m_imageAlloc; 534 Move<VkImageView> m_attachmentView; 535 }; 536 std::vector<de::SharedPtr<PerSampleImage> > m_perSampleImages; 537 538 Move<VkImage> m_depthStencilImage; 539 de::MovePtr<Allocation> m_depthStencilImageAlloc; 540 Move<VkImageView> m_depthStencilAttachmentView; 541 542 RenderPassWrapper m_renderPass; 543 544 ShaderWrapper m_vertexShaderModule; 545 ShaderWrapper m_fragmentShaderModule; 546 547 ShaderWrapper m_copySampleVertexShaderModule; 548 ShaderWrapper m_copySampleFragmentShaderModule; 549 550 Move<VkBuffer> m_vertexBuffer; 551 de::MovePtr<Allocation> m_vertexBufferAlloc; 552 553 PipelineLayoutWrapper m_pipelineLayout; 554 std::vector<GraphicsPipelineWrapper> m_graphicsPipelines; 555 556 Move<VkDescriptorSetLayout> m_copySampleDesciptorLayout; 557 Move<VkDescriptorPool> m_copySampleDesciptorPool; 558 Move<VkDescriptorSet> m_copySampleDesciptorSet; 559 560 PipelineLayoutWrapper m_copySamplePipelineLayout; 561 std::vector<GraphicsPipelineWrapper> m_copySamplePipelines; 562 563 Move<VkCommandPool> m_cmdPool; 564 Move<VkCommandBuffer> m_cmdBuffer; 565 566 std::vector<de::SharedPtr<Allocation> > m_allocations; 567 568 ImageBackingMode m_backingMode; 569 const float m_depthClearValue; 570 const bool m_useFragmentShadingRate; 571}; 572 573class RasterizationSamplesInstance : public vkt::TestInstance 574{ 575public: 576 RasterizationSamplesInstance (Context& context, 577 const PipelineConstructionType pipelineConstructionType, 578 VkPrimitiveTopology topology, 579 float pointSize, 580 const std::vector<Vertex4RGBA>& vertices, 581 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 582 const VkPipelineColorBlendAttachmentState& blendState, 583 const TestModeFlags modeFlags, 584 ImageBackingMode backingMode, 585 const bool useFragmentShadingRate); 586 virtual ~RasterizationSamplesInstance (void) {} 587 588 virtual tcu::TestStatus iterate (void); 589 590protected: 591 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 592 593 const VkFormat m_colorFormat; 594 const tcu::IVec2 m_renderSize; 595 const VkPrimitiveTopology m_primitiveTopology; 596 const float m_pointSize; 597 const std::vector<Vertex4RGBA> m_vertices; 598 const std::vector<Vertex4RGBA> m_fullQuadVertices; //!< used by depth/stencil case 599 const TestModeFlags m_modeFlags; 600 de::MovePtr<MultisampleRenderer> m_multisampleRenderer; 601 const bool m_useFragmentShadingRate; 602}; 603 604class MinSampleShadingInstance : public vkt::TestInstance 605{ 606public: 607 MinSampleShadingInstance (Context& context, 608 const PipelineConstructionType pipelineConstructionType, 609 VkPrimitiveTopology topology, 610 float pointSize, 611 const std::vector<Vertex4RGBA>& vertices, 612 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 613 const VkPipelineColorBlendAttachmentState& blendState, 614 ImageBackingMode backingMode, 615 const bool useFragmentShadingRate); 616 virtual ~MinSampleShadingInstance (void) {} 617 618 virtual tcu::TestStatus iterate (void); 619 620protected: 621 virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& testShadingImages, 622 const tcu::ConstPixelBufferAccess& noSampleshadingImage); 623 624 const PipelineConstructionType m_pipelineConstructionType; 625 const VkFormat m_colorFormat; 626 const tcu::IVec2 m_renderSize; 627 const VkPrimitiveTopology m_primitiveTopology; 628 const std::vector<Vertex4RGBA> m_vertices; 629 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 630 const VkPipelineColorBlendAttachmentState m_colorBlendState; 631 const ImageBackingMode m_backingMode; 632 const bool m_useFragmentShadingRate; 633}; 634 635class MinSampleShadingDisabledInstance : public MinSampleShadingInstance 636{ 637public: 638 MinSampleShadingDisabledInstance (Context& context, 639 const PipelineConstructionType pipelineConstructionType, 640 VkPrimitiveTopology topology, 641 float pointSize, 642 const std::vector<Vertex4RGBA>& vertices, 643 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 644 const VkPipelineColorBlendAttachmentState& blendState, 645 ImageBackingMode backingMode, 646 const bool useFragmentShadingRate); 647 virtual ~MinSampleShadingDisabledInstance (void) {} 648 649protected: 650 virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, 651 const tcu::ConstPixelBufferAccess& noSampleshadingImage); 652}; 653 654class SampleMaskInstance : public vkt::TestInstance 655{ 656public: 657 SampleMaskInstance (Context& context, 658 const PipelineConstructionType pipelineConstructionType, 659 VkPrimitiveTopology topology, 660 float pointSize, 661 const std::vector<Vertex4RGBA>& vertices, 662 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 663 const VkPipelineColorBlendAttachmentState& blendState, 664 ImageBackingMode backingMode, 665 const bool useFragmentShadingRate); 666 virtual ~SampleMaskInstance (void) {} 667 668 virtual tcu::TestStatus iterate (void); 669 670protected: 671 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, 672 const tcu::ConstPixelBufferAccess& minShadingImage, 673 const tcu::ConstPixelBufferAccess& maxShadingImage); 674 const PipelineConstructionType m_pipelineConstructionType; 675 const VkFormat m_colorFormat; 676 const tcu::IVec2 m_renderSize; 677 const VkPrimitiveTopology m_primitiveTopology; 678 const std::vector<Vertex4RGBA> m_vertices; 679 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 680 const VkPipelineColorBlendAttachmentState m_colorBlendState; 681 const ImageBackingMode m_backingMode; 682 const bool m_useFragmentShadingRate; 683}; 684 685class AlphaToOneInstance : public vkt::TestInstance 686{ 687public: 688 AlphaToOneInstance (Context& context, 689 const PipelineConstructionType pipelineConstructionType, 690 VkPrimitiveTopology topology, 691 const std::vector<Vertex4RGBA>& vertices, 692 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 693 const VkPipelineColorBlendAttachmentState& blendState, 694 ImageBackingMode backingMode, 695 const bool useFragmentShadingRate); 696 virtual ~AlphaToOneInstance (void) {} 697 698 virtual tcu::TestStatus iterate (void); 699 700protected: 701 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 702 const tcu::ConstPixelBufferAccess& noAlphaOneImage); 703 const PipelineConstructionType m_pipelineConstructionType; 704 const VkFormat m_colorFormat; 705 const tcu::IVec2 m_renderSize; 706 const VkPrimitiveTopology m_primitiveTopology; 707 const std::vector<Vertex4RGBA> m_vertices; 708 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 709 const VkPipelineColorBlendAttachmentState m_colorBlendState; 710 const ImageBackingMode m_backingMode; 711 const bool m_useFragmentShadingRate; 712}; 713 714class AlphaToCoverageInstance : public vkt::TestInstance 715{ 716public: 717 AlphaToCoverageInstance (Context& context, 718 const PipelineConstructionType pipelineConstructionType, 719 VkPrimitiveTopology topology, 720 const std::vector<Vertex4RGBA>& vertices, 721 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 722 const VkPipelineColorBlendAttachmentState& blendState, 723 GeometryType geometryType, 724 ImageBackingMode backingMode, 725 const bool useFragmentShadingRate, 726 const bool checkDepthBuffer); 727 virtual ~AlphaToCoverageInstance (void) {} 728 729 virtual tcu::TestStatus iterate (void); 730 731protected: 732 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 733 virtual tcu::TestStatus verifyDepthBufferCheck (const tcu::ConstPixelBufferAccess& result); 734 735 const PipelineConstructionType m_pipelineConstructionType; 736 const VkFormat m_colorFormat; 737 const VkFormat m_depthStencilFormat; 738 const tcu::IVec2 m_renderSize; 739 const VkPrimitiveTopology m_primitiveTopology; 740 const std::vector<Vertex4RGBA> m_vertices; 741 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 742 const VkPipelineColorBlendAttachmentState m_colorBlendState; 743 const GeometryType m_geometryType; 744 const ImageBackingMode m_backingMode; 745 const bool m_useFragmentShadingRate; 746 const bool m_checkDepthBuffer; 747}; 748 749class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance 750{ 751public: 752 AlphaToCoverageNoColorAttachmentInstance (Context& context, 753 const PipelineConstructionType pipelineConstructionType, 754 VkPrimitiveTopology topology, 755 const std::vector<Vertex4RGBA>& vertices, 756 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 757 const VkPipelineColorBlendAttachmentState& blendState, 758 GeometryType geometryType, 759 ImageBackingMode backingMode, 760 const bool useFragmentShadingRate); 761 virtual ~AlphaToCoverageNoColorAttachmentInstance (void) {} 762 763 virtual tcu::TestStatus iterate (void); 764 765protected: 766 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 767 768 const PipelineConstructionType m_pipelineConstructionType; 769 const VkFormat m_colorFormat; 770 const VkFormat m_depthStencilFormat; 771 const tcu::IVec2 m_renderSize; 772 const VkPrimitiveTopology m_primitiveTopology; 773 const std::vector<Vertex4RGBA> m_vertices; 774 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 775 const VkPipelineColorBlendAttachmentState m_colorBlendState; 776 const GeometryType m_geometryType; 777 const ImageBackingMode m_backingMode; 778 const bool m_useFragmentShadingRate; 779}; 780 781class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance 782{ 783public: 784 AlphaToCoverageColorUnusedAttachmentInstance (Context& context, 785 const PipelineConstructionType pipelineConstructionType, 786 VkPrimitiveTopology topology, 787 const std::vector<Vertex4RGBA>& vertices, 788 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 789 const VkPipelineColorBlendAttachmentState& blendState, 790 GeometryType geometryType, 791 ImageBackingMode backingMode, 792 const bool useFragmentShadingRate); 793 virtual ~AlphaToCoverageColorUnusedAttachmentInstance (void) {} 794 795 virtual tcu::TestStatus iterate (void); 796 797protected: 798 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 799 800 const PipelineConstructionType m_pipelineConstructionType; 801 const VkFormat m_colorFormat; 802 const tcu::IVec2 m_renderSize; 803 const VkPrimitiveTopology m_primitiveTopology; 804 const std::vector<Vertex4RGBA> m_vertices; 805 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 806 const VkPipelineColorBlendAttachmentState m_colorBlendState; 807 const GeometryType m_geometryType; 808 const ImageBackingMode m_backingMode; 809 const bool m_useFragmentShadingRate; 810}; 811 812class SampleMaskWithConservativeInstance : public vkt::TestInstance 813{ 814public: 815 SampleMaskWithConservativeInstance (Context& context, 816 const PipelineConstructionType pipelineConstructionType, 817 const VkSampleCountFlagBits rasterizationSamples, 818 const bool enableMinSampleShading, 819 const float minSampleShading, 820 const bool enableSampleMask, 821 const VkSampleMask sampleMask, 822 const VkConservativeRasterizationModeEXT conservativeRasterizationMode, 823 const bool enablePostDepthCoverage, 824 const bool enableFullyCoveredEXT, 825 const RenderType renderType, 826 const bool useFragmentShadingRate); 827 ~SampleMaskWithConservativeInstance (void) {} 828 829 tcu::TestStatus iterate (void); 830 831protected: 832 VkPipelineMultisampleStateCreateInfo getMultisampleState (const VkSampleCountFlagBits rasterizationSamples, const bool enableMinSampleShading, const float minSampleShading, const bool enableSampleMask); 833 VkPipelineRasterizationConservativeStateCreateInfoEXT getRasterizationConservativeStateCreateInfo (const VkConservativeRasterizationModeEXT conservativeRasterizationMode); 834 std::vector<Vertex4RGBA> generateVertices (void); 835 tcu::TestStatus verifyImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& result); 836 837 const PipelineConstructionType m_pipelineConstructionType; 838 const VkSampleCountFlagBits m_rasterizationSamples; 839 const bool m_enablePostDepthCoverage; 840 const bool m_enableFullyCoveredEXT; 841 const VkFormat m_colorFormat; 842 const VkFormat m_depthStencilFormat; 843 const tcu::IVec2 m_renderSize; 844 const bool m_useDepth; 845 const bool m_useStencil; 846 const bool m_useConservative; 847 const bool m_useFragmentShadingRate; 848 const VkConservativeRasterizationModeEXT m_conservativeRasterizationMode; 849 const VkPrimitiveTopology m_topology; 850 const tcu::Vec4 m_renderColor; 851 const float m_depthClearValue; 852 const std::vector<Vertex4RGBA> m_vertices; 853 const bool m_enableSampleMask; 854 const std::vector<VkSampleMask> m_sampleMask; 855 const bool m_enableMinSampleShading; 856 const float m_minSampleShading; 857 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 858 const VkPipelineRasterizationConservativeStateCreateInfoEXT m_rasterizationConservativeStateCreateInfo; 859 const VkPipelineColorBlendAttachmentState m_blendState; 860 const RenderType m_renderType; 861 const ImageBackingMode m_imageBackingMode; 862}; 863 864#ifndef CTS_USES_VULKANSC 865class SampleMaskWithDepthTestInstance : public vkt::TestInstance 866{ 867public: 868 SampleMaskWithDepthTestInstance (Context& context, 869 const PipelineConstructionType pipelineConstructionType, 870 const VkSampleCountFlagBits rasterizationSamples, 871 const bool enablePostDepthCoverage, 872 const bool useFragmentShadingRate); 873 ~SampleMaskWithDepthTestInstance (void) {} 874 875 tcu::TestStatus iterate (void); 876 877protected: 878 VkPipelineMultisampleStateCreateInfo getMultisampleState (const VkSampleCountFlagBits rasterizationSamples); 879 std::vector<Vertex4RGBA> generateVertices (void); 880 tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 881 882 struct SampleCoverage 883 { 884 SampleCoverage() {} 885 SampleCoverage(deUint32 min_, deUint32 max_) 886 : min(min_), max(max_) {} 887 888 deUint32 min; 889 deUint32 max; 890 }; 891 892 const PipelineConstructionType m_pipelineConstructionType; 893 const VkSampleCountFlagBits m_rasterizationSamples; 894 const bool m_enablePostDepthCoverage; 895 const VkFormat m_colorFormat; 896 const VkFormat m_depthStencilFormat; 897 const tcu::IVec2 m_renderSize; 898 const bool m_useDepth; 899 const bool m_useStencil; 900 const VkPrimitiveTopology m_topology; 901 const tcu::Vec4 m_renderColor; 902 const std::vector<Vertex4RGBA> m_vertices; 903 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 904 const VkPipelineColorBlendAttachmentState m_blendState; 905 const RenderType m_renderType; 906 const ImageBackingMode m_imageBackingMode; 907 const float m_depthClearValue; 908 std::map<VkSampleCountFlagBits, SampleCoverage> m_refCoverageAfterDepthTest; 909 const bool m_useFragmentShadingRate; 910}; 911 912 913// Helper functions 914 915void checkSupport (Context& context, MultisampleTestParams params) 916{ 917 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), params.pipelineConstructionType); 918} 919#endif // CTS_USES_VULKANSC 920 921void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params) 922{ 923 const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string(""); 924 std::ostringstream vertexSource; 925 926 vertexSource << 927 "#version 310 es\n" 928 "layout(location = 0) in vec4 position;\n" 929 "layout(location = 1) in vec4 color;\n" 930 "layout(location = 0) out highp vec4 vtxColor;\n" 931 "void main (void)\n" 932 "{\n" 933 " gl_Position = position;\n" 934 " vtxColor = color;\n" 935 << pointSize 936 << "}\n"; 937 938 static const char* fragmentSource = 939 "#version 310 es\n" 940 "layout(location = 0) in highp vec4 vtxColor;\n" 941 "layout(location = 0) out highp vec4 fragColor;\n" 942 "void main (void)\n" 943 "{\n" 944 " fragColor = vtxColor;\n" 945 "}\n"; 946 947 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 948 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); 949} 950 951void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params, bool minSampleShadingEnabled) 952{ 953 { 954 const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string(""); 955 std::ostringstream vertexSource; 956 std::ostringstream fragmentSource; 957 958 vertexSource << 959 "#version 440\n" 960 "layout(location = 0) in vec4 position;\n" 961 "layout(location = 1) in vec4 color;\n" 962 "void main (void)\n" 963 "{\n" 964 " gl_Position = position;\n" 965 << pointSize 966 << "}\n"; 967 968 fragmentSource << "#version 440\n" 969 "layout(location = 0) out highp vec4 fragColor;\n" 970 "void main (void)\n" 971 "{\n"; 972 if (minSampleShadingEnabled) { 973 fragmentSource << " uint sampleId = gl_SampleID;\n"; // Enable sample shading for shader objects by reading gl_SampleID 974 } 975 fragmentSource << " fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n" 976 "}\n"; 977 978 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 979 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str()); 980 } 981 982 { 983 static const char* vertexSource = 984 "#version 440\n" 985 "void main (void)\n" 986 "{\n" 987 " const vec4 positions[4] = vec4[4](\n" 988 " vec4(-1.0, -1.0, 0.0, 1.0),\n" 989 " vec4(-1.0, 1.0, 0.0, 1.0),\n" 990 " vec4( 1.0, -1.0, 0.0, 1.0),\n" 991 " vec4( 1.0, 1.0, 0.0, 1.0)\n" 992 " );\n" 993 " gl_Position = positions[gl_VertexIndex];\n" 994 "}\n"; 995 996 static const char* fragmentSource = 997 "#version 440\n" 998 "precision highp float;\n" 999 "layout(location = 0) out highp vec4 fragColor;\n" 1000 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n" 1001 "layout(push_constant) uniform PushConstantsBlock\n" 1002 "{\n" 1003 " int sampleId;\n" 1004 "} pushConstants;\n" 1005 "void main (void)\n" 1006 "{\n" 1007 " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n" 1008 "}\n"; 1009 1010 sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource); 1011 sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource); 1012 } 1013} 1014 1015void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources) 1016{ 1017 std::ostringstream vertexSource; 1018 1019 vertexSource << 1020 "#version 310 es\n" 1021 "layout(location = 0) in vec4 position;\n" 1022 "layout(location = 1) in vec4 color;\n" 1023 "layout(location = 0) out highp vec4 vtxColor;\n" 1024 "void main (void)\n" 1025 "{\n" 1026 " gl_Position = position;\n" 1027 " vtxColor = color;\n" 1028 "}\n"; 1029 1030 // Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel. 1031 static const char* fragmentSource = 1032 "#version 310 es\n" 1033 "layout(location = 0) in highp vec4 vtxColor;\n" 1034 "layout(location = 0) out highp vec4 fragColor0;\n" 1035 "layout(location = 1) out highp vec3 fragColor1;\n" 1036 "void main (void)\n" 1037 "{\n" 1038 " fragColor0 = vtxColor;\n" 1039 " fragColor1 = vtxColor.rgb;\n" 1040 "}\n"; 1041 1042 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 1043 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); 1044} 1045 1046bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples) 1047{ 1048 VkPhysicalDeviceProperties deviceProperties; 1049 1050 instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties); 1051 1052 return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples); 1053} 1054 1055bool checkFragmentShadingRateRequirements(Context& context, deUint32 sampleCount) 1056{ 1057 const auto& vki = context.getInstanceInterface(); 1058 const auto physicalDevice = context.getPhysicalDevice(); 1059 1060 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate"); 1061 1062 if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate) 1063 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported"); 1064 1065 // Fetch information about supported fragment shading rates 1066 deUint32 supportedFragmentShadingRateCount = 0; 1067 vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, DE_NULL); 1068 1069 std::vector<vk::VkPhysicalDeviceFragmentShadingRateKHR> supportedFragmentShadingRates(supportedFragmentShadingRateCount, 1070 { 1071 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR, 1072 DE_NULL, 1073 vk::VK_SAMPLE_COUNT_1_BIT, 1074 {1, 1} 1075 }); 1076 vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, supportedFragmentShadingRates.data()); 1077 1078 for (const auto& rate : supportedFragmentShadingRates) 1079 { 1080 if ((rate.fragmentSize.width == 2u) && 1081 (rate.fragmentSize.height == 2u) && 1082 (rate.sampleCounts & sampleCount)) 1083 return true; 1084 } 1085 1086 return false; 1087} 1088 1089VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState () 1090{ 1091 const VkPipelineColorBlendAttachmentState colorBlendState = 1092 { 1093 false, // VkBool32 blendEnable; 1094 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 1095 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 1096 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 1097 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 1098 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 1099 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 1100 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 1101 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 1102 }; 1103 1104 return colorBlendState; 1105} 1106 1107VkPipelineColorBlendAttachmentState getAlphaToCoverageBlendState (bool blendEnable) 1108{ 1109 const VkPipelineColorBlendAttachmentState colorBlendState = 1110 { 1111 blendEnable, // VkBool32 blendEnable; 1112 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 1113 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 1114 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 1115 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; 1116 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 1117 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 1118 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 1119 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 1120 }; 1121 1122 return colorBlendState; 1123} 1124 1125deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image) 1126{ 1127 DE_ASSERT(image.getFormat().getPixelSize() == 4); 1128 1129 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> 1130 const deUint32 pixelCount = image.getWidth() * image.getHeight() * image.getDepth(); 1131 1132 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) 1133 { 1134 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx); 1135 1136 if (histogram.find(pixelValue) != histogram.end()) 1137 histogram[pixelValue]++; 1138 else 1139 histogram[pixelValue] = 1; 1140 } 1141 1142 return (deUint32)histogram.size(); 1143} 1144 1145VkImageAspectFlags getImageAspectFlags (const VkFormat format) 1146{ 1147 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 1148 1149 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 1150 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; 1151 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; 1152 1153 DE_ASSERT(false); 1154 return 0u; 1155} 1156 1157std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType) 1158{ 1159 std::vector<Vertex4RGBA> vertices; 1160 1161 switch (geometryType) 1162 { 1163 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 1164 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: 1165 { 1166 Vertex4RGBA vertexData[3] = 1167 { 1168 { 1169 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 1170 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1171 }, 1172 { 1173 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 1174 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1175 }, 1176 { 1177 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 1178 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1179 } 1180 }; 1181 1182 if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE) 1183 { 1184 for (int i = 0; i < 3; i++) 1185 vertexData[i].color = tcu::Vec4(); 1186 } 1187 1188 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3); 1189 break; 1190 } 1191 1192 case GEOMETRY_TYPE_OPAQUE_LINE: 1193 { 1194 const Vertex4RGBA vertexData[2] = 1195 { 1196 { 1197 tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f), 1198 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1199 }, 1200 { 1201 tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f), 1202 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1203 } 1204 }; 1205 1206 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2); 1207 break; 1208 } 1209 1210 case GEOMETRY_TYPE_OPAQUE_POINT: 1211 { 1212 const Vertex4RGBA vertex = 1213 { 1214 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 1215 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1216 }; 1217 1218 vertices = std::vector<Vertex4RGBA>(1, vertex); 1219 break; 1220 } 1221 1222 case GEOMETRY_TYPE_OPAQUE_QUAD: 1223 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 1224 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 1225 case GEOMETRY_TYPE_INVISIBLE_QUAD: 1226 case GEOMETRY_TYPE_GRADIENT_QUAD: 1227 { 1228 Vertex4RGBA vertexData[4] = 1229 { 1230 { 1231 tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), 1232 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1233 }, 1234 { 1235 tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), 1236 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1237 }, 1238 { 1239 tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), 1240 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1241 }, 1242 { 1243 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), 1244 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1245 } 1246 }; 1247 1248 if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD) 1249 { 1250 for (int i = 0; i < 4; i++) 1251 vertexData[i].color.w() = 0.25f; 1252 } 1253 else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD) 1254 { 1255 for (int i = 0; i < 4; i++) 1256 vertexData[i].color.w() = 0.0f; 1257 } 1258 else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD) 1259 { 1260 vertexData[0].color.w() = 0.0f; 1261 vertexData[2].color.w() = 0.0f; 1262 } 1263 else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH) 1264 { 1265 for (int i = 0; i < 4; i++) 1266 vertexData[i].position.z() = 0.5f; 1267 } 1268 1269 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + de::arrayLength(vertexData)); 1270 break; 1271 } 1272 1273 default: 1274 DE_ASSERT(false); 1275 } 1276 return vertices; 1277} 1278 1279VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType) 1280{ 1281 switch (geometryType) 1282 { 1283 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 1284 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 1285 1286 case GEOMETRY_TYPE_OPAQUE_LINE: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 1287 case GEOMETRY_TYPE_OPAQUE_POINT: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 1288 1289 case GEOMETRY_TYPE_OPAQUE_QUAD: 1290 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 1291 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 1292 case GEOMETRY_TYPE_INVISIBLE_QUAD: 1293 case GEOMETRY_TYPE_GRADIENT_QUAD: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 1294 1295 default: 1296 DE_ASSERT(false); 1297 return VK_PRIMITIVE_TOPOLOGY_LAST; 1298 } 1299} 1300 1301bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format) 1302{ 1303 VkFormatProperties formatProps; 1304 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps); 1305 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; 1306} 1307 1308VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil) 1309{ 1310 if (useDepth && !useStencil) 1311 return VK_FORMAT_D16_UNORM; // must be supported 1312 1313 const InstanceInterface& vki = context.getInstanceInterface(); 1314 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 1315 1316 // One of these formats must be supported. 1317 1318 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT)) 1319 return VK_FORMAT_D24_UNORM_S8_UINT; 1320 1321 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT)) 1322 return VK_FORMAT_D32_SFLOAT_S8_UINT; 1323 1324 return VK_FORMAT_UNDEFINED; 1325} 1326 1327 1328// MultisampleTest 1329 1330MultisampleTest::MultisampleTest (tcu::TestContext& testContext, 1331 const std::string& name, 1332 const PipelineConstructionType pipelineConstructionType, 1333 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1334 const VkPipelineColorBlendAttachmentState& blendState, 1335 GeometryType geometryType, 1336 float pointSize, 1337 ImageBackingMode backingMode, 1338 const bool useFragmentShadingRate) 1339 : vkt::TestCase (testContext, name) 1340 , m_pipelineConstructionType(pipelineConstructionType) 1341 , m_multisampleStateParams (multisampleStateParams) 1342 , m_colorBlendState (blendState) 1343 , m_geometryType (geometryType) 1344 , m_pointSize (pointSize) 1345 , m_backingMode (backingMode) 1346 , m_useFragmentShadingRate (useFragmentShadingRate) 1347{ 1348 if (m_multisampleStateParams.pSampleMask) 1349 { 1350 // Copy pSampleMask to avoid dependencies with other classes 1351 1352 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32); 1353 1354 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++) 1355 m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]); 1356 1357 m_multisampleStateParams.pSampleMask = m_sampleMask.data(); 1358 } 1359} 1360 1361void MultisampleTest::initPrograms (SourceCollections& programCollection) const 1362{ 1363 MultisampleTestParams params = {m_pipelineConstructionType, m_geometryType, m_pointSize, m_backingMode, m_useFragmentShadingRate}; 1364 initMultisamplePrograms(programCollection, params); 1365} 1366 1367TestInstance* MultisampleTest::createInstance (Context& context) const 1368{ 1369 return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState); 1370} 1371 1372void MultisampleTest::checkSupport (Context& context) const 1373{ 1374 if (m_geometryType == GEOMETRY_TYPE_OPAQUE_POINT && m_pointSize > 1.0f) 1375 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS); 1376 1377 if (m_useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_multisampleStateParams.rasterizationSamples)) 1378 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported"); 1379 1380 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 1381} 1382 1383// RasterizationSamplesTest 1384 1385RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext& testContext, 1386 const std::string& name, 1387 PipelineConstructionType pipelineConstructionType, 1388 VkSampleCountFlagBits rasterizationSamples, 1389 GeometryType geometryType, 1390 float pointSize, 1391 ImageBackingMode backingMode, 1392 TestModeFlags modeFlags, 1393 const bool useFragmentShadingRate) 1394 : MultisampleTest (testContext, name, pipelineConstructionType, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate) 1395 , m_backingMode (backingMode) 1396 , m_modeFlags (modeFlags) 1397{ 1398} 1399 1400VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples) 1401{ 1402 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1403 { 1404 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1405 DE_NULL, // const void* pNext; 1406 0u, // VkPipelineMultisampleStateCreateFlags flags; 1407 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1408 false, // VkBool32 sampleShadingEnable; 1409 0.0f, // float minSampleShading; 1410 DE_NULL, // const VkSampleMask* pSampleMask; 1411 false, // VkBool32 alphaToCoverageEnable; 1412 false // VkBool32 alphaToOneEnable; 1413 }; 1414 1415 return multisampleStateParams; 1416} 1417 1418TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context& context, 1419 VkPrimitiveTopology topology, 1420 float pointSize, 1421 const std::vector<Vertex4RGBA>& vertices, 1422 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1423 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1424{ 1425 return new RasterizationSamplesInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode, m_useFragmentShadingRate); 1426} 1427 1428 1429// MinSampleShadingTest 1430 1431MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext& testContext, 1432 const std::string& name, 1433 const PipelineConstructionType pipelineConstructionType, 1434 VkSampleCountFlagBits rasterizationSamples, 1435 float minSampleShading, 1436 GeometryType geometryType, 1437 float pointSize, 1438 ImageBackingMode backingMode, 1439 const bool minSampleShadingEnabled, 1440 const bool useFragmentShadingRate) 1441 : MultisampleTest (testContext, name, pipelineConstructionType, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading, minSampleShadingEnabled), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate) 1442 , m_pointSize (pointSize) 1443 , m_backingMode (backingMode) 1444 , m_minSampleShadingEnabled (minSampleShadingEnabled) 1445{ 1446} 1447 1448void MinSampleShadingTest::checkSupport (Context& context) const 1449{ 1450 MultisampleTest::checkSupport(context); 1451 1452 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING); 1453} 1454 1455void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const 1456{ 1457 MultisampleTestParams params = {m_pipelineConstructionType, m_geometryType, m_pointSize, m_backingMode, m_useFragmentShadingRate}; 1458 initSampleShadingPrograms(programCollection, params, m_minSampleShadingEnabled); 1459} 1460 1461TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context, 1462 VkPrimitiveTopology topology, 1463 float pointSize, 1464 const std::vector<Vertex4RGBA>& vertices, 1465 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1466 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1467{ 1468 if (m_minSampleShadingEnabled) 1469 return new MinSampleShadingInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate); 1470 else 1471 return new MinSampleShadingDisabledInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate); 1472} 1473 1474VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading, bool minSampleShadingEnabled) 1475{ 1476 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1477 { 1478 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1479 DE_NULL, // const void* pNext; 1480 0u, // VkPipelineMultisampleStateCreateFlags flags; 1481 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1482 minSampleShadingEnabled ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable; 1483 minSampleShading, // float minSampleShading; 1484 DE_NULL, // const VkSampleMask* pSampleMask; 1485 false, // VkBool32 alphaToCoverageEnable; 1486 false // VkBool32 alphaToOneEnable; 1487 }; 1488 1489 return multisampleStateParams; 1490} 1491 1492 1493// SampleMaskTest 1494 1495SampleMaskTest::SampleMaskTest (tcu::TestContext& testContext, 1496 const std::string& name, 1497 const PipelineConstructionType pipelineConstructionType, 1498 VkSampleCountFlagBits rasterizationSamples, 1499 const std::vector<VkSampleMask>& sampleMask, 1500 GeometryType geometryType, 1501 float pointSize, 1502 ImageBackingMode backingMode, 1503 const bool useFragmentShadingRate) 1504 : MultisampleTest (testContext, name, pipelineConstructionType, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate) 1505 , m_backingMode (backingMode) 1506{ 1507} 1508 1509TestInstance* SampleMaskTest::createMultisampleTestInstance (Context& context, 1510 VkPrimitiveTopology topology, 1511 float pointSize, 1512 const std::vector<Vertex4RGBA>& vertices, 1513 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1514 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1515{ 1516 DE_UNREF(pointSize); 1517 return new SampleMaskInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate); 1518} 1519 1520VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask) 1521{ 1522 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1523 { 1524 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1525 DE_NULL, // const void* pNext; 1526 0u, // VkPipelineMultisampleStateCreateFlags flags; 1527 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1528 false, // VkBool32 sampleShadingEnable; 1529 0.0f, // float minSampleShading; 1530 sampleMask.data(), // const VkSampleMask* pSampleMask; 1531 false, // VkBool32 alphaToCoverageEnable; 1532 false // VkBool32 alphaToOneEnable; 1533 }; 1534 1535 return multisampleStateParams; 1536} 1537 1538 1539// AlphaToOneTest 1540 1541AlphaToOneTest::AlphaToOneTest (tcu::TestContext& testContext, 1542 const std::string& name, 1543 const PipelineConstructionType pipelineConstructionType, 1544 VkSampleCountFlagBits rasterizationSamples, 1545 ImageBackingMode backingMode, 1546 const bool useFragmentShadingRate) 1547 : MultisampleTest (testContext, name, pipelineConstructionType, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode, useFragmentShadingRate) 1548 , m_backingMode(backingMode) 1549{ 1550} 1551 1552void AlphaToOneTest::checkSupport (Context& context) const 1553{ 1554 MultisampleTest::checkSupport(context); 1555 1556 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE); 1557} 1558 1559TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context& context, 1560 VkPrimitiveTopology topology, 1561 float pointSize, 1562 const std::vector<Vertex4RGBA>& vertices, 1563 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1564 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1565{ 1566 DE_UNREF(pointSize); 1567 return new AlphaToOneInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate); 1568} 1569 1570VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples) 1571{ 1572 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1573 { 1574 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1575 DE_NULL, // const void* pNext; 1576 0u, // VkPipelineMultisampleStateCreateFlags flags; 1577 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1578 false, // VkBool32 sampleShadingEnable; 1579 0.0f, // float minSampleShading; 1580 DE_NULL, // const VkSampleMask* pSampleMask; 1581 false, // VkBool32 alphaToCoverageEnable; 1582 true // VkBool32 alphaToOneEnable; 1583 }; 1584 1585 return multisampleStateParams; 1586} 1587 1588VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void) 1589{ 1590 const VkPipelineColorBlendAttachmentState colorBlendState = 1591 { 1592 true, // VkBool32 blendEnable; 1593 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 1594 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 1595 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 1596 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 1597 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor; 1598 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 1599 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 1600 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 1601 }; 1602 1603 return colorBlendState; 1604} 1605 1606 1607// AlphaToCoverageTest 1608 1609AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext& testContext, 1610 const std::string& name, 1611 const PipelineConstructionType pipelineConstructionType, 1612 VkSampleCountFlagBits rasterizationSamples, 1613 GeometryType geometryType, 1614 ImageBackingMode backingMode, 1615 const bool useFragmentShadingRate, 1616 const bool checkDepthBuffer) 1617 : MultisampleTest (testContext, 1618 name, 1619 pipelineConstructionType, 1620 getAlphaToCoverageStateParams(rasterizationSamples), 1621 getAlphaToCoverageBlendState(checkDepthBuffer), 1622 geometryType, 1623 1.0f, 1624 backingMode, 1625 useFragmentShadingRate) 1626 , m_geometryType (geometryType) 1627 , m_backingMode (backingMode) 1628 , m_checkDepthBuffer(checkDepthBuffer) 1629{ 1630 if (checkDepthBuffer) 1631 DE_ASSERT(geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD); 1632} 1633 1634void AlphaToCoverageTest::initPrograms (SourceCollections &programCollection) const 1635{ 1636 MultisampleTest::initPrograms(programCollection); 1637 1638 if (m_checkDepthBuffer) 1639 { 1640 std::ostringstream vert; 1641 vert 1642 << "#version 460\n" 1643 << "layout (push_constant, std430) uniform PushConstantBlock { float depth; } pc;\n" 1644 << "layout (location=0) out vec4 vtxColor;\n" 1645 << "vec2 positions[3] = vec2[](\n" 1646 << " vec2(-1.0, -1.0),\n" 1647 << " vec2(-1.0, 3.0),\n" 1648 << " vec2(3.0, -1.0)\n" 1649 << ");\n" 1650 << "void main (void) {\n" 1651 << " gl_Position = vec4(positions[gl_VertexIndex % 3], pc.depth, 1.0);\n" 1652 << " vtxColor = vec4(0.0, 0.0, 1.0, 1.0);\n" 1653 << "}\n" 1654 ; 1655 programCollection.glslSources.add("checkDepth-vert") << glu::VertexSource(vert.str()); 1656 } 1657} 1658 1659TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context& context, 1660 VkPrimitiveTopology topology, 1661 float pointSize, 1662 const std::vector<Vertex4RGBA>& vertices, 1663 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1664 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1665{ 1666 DE_UNREF(pointSize); 1667 return new AlphaToCoverageInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate, m_checkDepthBuffer); 1668} 1669 1670VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples) 1671{ 1672 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1673 { 1674 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1675 DE_NULL, // const void* pNext; 1676 0u, // VkPipelineMultisampleStateCreateFlags flags; 1677 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1678 false, // VkBool32 sampleShadingEnable; 1679 0.0f, // float minSampleShading; 1680 DE_NULL, // const VkSampleMask* pSampleMask; 1681 true, // VkBool32 alphaToCoverageEnable; 1682 false // VkBool32 alphaToOneEnable; 1683 }; 1684 1685 return multisampleStateParams; 1686} 1687 1688// AlphaToCoverageNoColorAttachmentTest 1689 1690AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext, 1691 const std::string& name, 1692 const PipelineConstructionType pipelineConstructionType, 1693 VkSampleCountFlagBits rasterizationSamples, 1694 GeometryType geometryType, 1695 ImageBackingMode backingMode, 1696 const bool useFragmentShadingRate) 1697 : MultisampleTest (testContext, name, pipelineConstructionType, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode, useFragmentShadingRate) 1698 , m_geometryType (geometryType) 1699 , m_backingMode (backingMode) 1700{ 1701} 1702 1703TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context& context, 1704 VkPrimitiveTopology topology, 1705 float pointSize, 1706 const std::vector<Vertex4RGBA>& vertices, 1707 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1708 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1709{ 1710 DE_UNREF(pointSize); 1711 return new AlphaToCoverageNoColorAttachmentInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate); 1712} 1713 1714VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples) 1715{ 1716 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1717 { 1718 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1719 DE_NULL, // const void* pNext; 1720 0u, // VkPipelineMultisampleStateCreateFlags flags; 1721 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1722 false, // VkBool32 sampleShadingEnable; 1723 0.0f, // float minSampleShading; 1724 DE_NULL, // const VkSampleMask* pSampleMask; 1725 true, // VkBool32 alphaToCoverageEnable; 1726 false // VkBool32 alphaToOneEnable; 1727 }; 1728 1729 return multisampleStateParams; 1730} 1731 1732// AlphaToCoverageColorUnusedAttachmentTest 1733 1734AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext, 1735 const std::string& name, 1736 const PipelineConstructionType pipelineConstructionType, 1737 VkSampleCountFlagBits rasterizationSamples, 1738 GeometryType geometryType, 1739 ImageBackingMode backingMode, 1740 const bool useFragmentShadingRate) 1741 : MultisampleTest (testContext, name, pipelineConstructionType, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode, useFragmentShadingRate) 1742 , m_geometryType (geometryType) 1743 , m_backingMode (backingMode) 1744{ 1745} 1746 1747void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const 1748{ 1749 initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection); 1750} 1751 1752TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context& context, 1753 VkPrimitiveTopology topology, 1754 float pointSize, 1755 const std::vector<Vertex4RGBA>& vertices, 1756 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1757 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1758{ 1759 DE_UNREF(pointSize); 1760 return new AlphaToCoverageColorUnusedAttachmentInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate); 1761} 1762 1763VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples) 1764{ 1765 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1766 { 1767 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1768 DE_NULL, // const void* pNext; 1769 0u, // VkPipelineMultisampleStateCreateFlags flags; 1770 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1771 false, // VkBool32 sampleShadingEnable; 1772 0.0f, // float minSampleShading; 1773 DE_NULL, // const VkSampleMask* pSampleMask; 1774 true, // VkBool32 alphaToCoverageEnable; 1775 false // VkBool32 alphaToOneEnable; 1776 }; 1777 1778 return multisampleStateParams; 1779} 1780 1781// SampleMaskWithConservativeTest 1782SampleMaskWithConservativeTest::SampleMaskWithConservativeTest (tcu::TestContext& testContext, 1783 const std::string& name, 1784 const PipelineConstructionType pipelineConstructionType, 1785 const VkSampleCountFlagBits rasterizationSamples, 1786 const VkConservativeRasterizationModeEXT conservativeRasterizationMode, 1787 const bool enableMinSampleShading, 1788 const float minSampleShading, 1789 const bool enableSampleMask, 1790 const VkSampleMask sampleMask, 1791 const bool enablePostDepthCoverage, 1792 const bool useFragmentShadingRate) 1793 : vkt::TestCase (testContext, name) 1794 , m_pipelineConstructionType (pipelineConstructionType) 1795 , m_rasterizationSamples (rasterizationSamples) 1796 , m_enableMinSampleShading (enableMinSampleShading) 1797 , m_minSampleShading (minSampleShading) 1798 , m_enableSampleMask (enableSampleMask) 1799 , m_sampleMask (sampleMask) 1800 , m_conservativeRasterizationMode (conservativeRasterizationMode) 1801 , m_enablePostDepthCoverage (enablePostDepthCoverage) 1802 , m_renderType (RENDER_TYPE_RESOLVE) 1803 , m_useFragmentShadingRate (useFragmentShadingRate) 1804{ 1805} 1806 1807void SampleMaskWithConservativeTest::checkSupport(Context& context) const 1808{ 1809 if (!context.getDeviceProperties().limits.standardSampleLocations) 1810 TCU_THROW(NotSupportedError, "standardSampleLocations required"); 1811 1812 if (m_useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_rasterizationSamples)) 1813 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported"); 1814 1815 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization"); 1816 1817 const auto& conservativeRasterizationProperties = context.getConservativeRasterizationPropertiesEXT(); 1818 const deUint32 subPixelPrecisionBits = context.getDeviceProperties().limits.subPixelPrecisionBits; 1819 const deUint32 subPixelPrecision = (1 << subPixelPrecisionBits); 1820 const float primitiveOverestimationSizeMult = float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize; 1821 1822 DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8); 1823 1824 if (m_enablePostDepthCoverage) 1825 { 1826 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage"); 1827 if (!conservativeRasterizationProperties.conservativeRasterizationPostDepthCoverage) 1828 TCU_THROW(NotSupportedError, "conservativeRasterizationPostDepthCoverage not supported"); 1829 } 1830 1831 context.getTestContext().getLog() 1832 << tcu::TestLog::Message 1833 << "maxExtraPrimitiveOverestimationSize=" << conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n' 1834 << "extraPrimitiveOverestimationSizeGranularity=" << conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n' 1835 << "degenerateTrianglesRasterized=" << conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n' 1836 << "primitiveOverestimationSize=" << conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n" 1837 << tcu::TestLog::EndMessage; 1838 1839 1840 if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT) 1841 { 1842 if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize) 1843 TCU_FAIL("Granularity cannot be greater than maximum extra size"); 1844 } 1845 else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT) 1846 { 1847 if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE) 1848 TCU_THROW(NotSupportedError, "Underestimation is not supported"); 1849 } 1850 else 1851 TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class"); 1852 1853 if (!conservativeRasterizationProperties.fullyCoveredFragmentShaderInputVariable) 1854 { 1855 TCU_THROW(NotSupportedError, "FullyCoveredEXT input variable is not supported"); 1856 } 1857 1858 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 1859} 1860 1861void SampleMaskWithConservativeTest::initPrograms(SourceCollections& programCollection) const 1862{ 1863 { 1864 DE_ASSERT((int)m_rasterizationSamples <= 32); 1865 1866 static const char* vertexSource = 1867 "#version 440\n" 1868 "layout(location = 0) in vec4 position;\n" 1869 "layout(location = 1) in vec4 color;\n" 1870 "layout(location = 0) out vec4 vtxColor;\n" 1871 "out gl_PerVertex\n" 1872 "{\n" 1873 " vec4 gl_Position;\n" 1874 "};\n" 1875 "\n" 1876 "void main (void)\n" 1877 "{\n" 1878 " gl_Position = position;\n" 1879 " vtxColor = color;\n" 1880 "}\n"; 1881 1882 std::ostringstream fragmentSource; 1883 fragmentSource << 1884 "#version 440\n" 1885 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") 1886 << (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT ? "#extension GL_NV_conservative_raster_underestimation : enable\n" : "") << 1887 "layout(early_fragment_tests) in;\n" 1888 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") << 1889 "layout(location = 0) in vec4 vtxColor;\n" 1890 "layout(location = 0) out vec4 fragColor;\n" 1891 "void main (void)\n" 1892 "{\n"; 1893 if (m_enableMinSampleShading) 1894 { 1895 fragmentSource << 1896 " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n" 1897 " fragColor = vtxColor * (1.0 / " << (int32_t)m_rasterizationSamples << " * coveredSamples);\n"; 1898 } 1899 else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT) 1900 { 1901 fragmentSource << 1902 " fragColor = gl_FragFullyCoveredNV ? vtxColor : vec4(0.0f);\n"; 1903 } 1904 else 1905 { 1906 fragmentSource << 1907 " fragColor = vtxColor;\n"; 1908 } 1909 fragmentSource << 1910 "}\n"; 1911 1912 1913 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource); 1914 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str()); 1915 } 1916 1917 { 1918 static const char* vertexSource = 1919 "#version 440\n" 1920 "void main (void)\n" 1921 "{\n" 1922 " const vec4 positions[4] = vec4[4](\n" 1923 " vec4(-1.0, -1.0, 0.0, 1.0),\n" 1924 " vec4(-1.0, 1.0, 0.0, 1.0),\n" 1925 " vec4( 1.0, -1.0, 0.0, 1.0),\n" 1926 " vec4( 1.0, 1.0, 0.0, 1.0)\n" 1927 " );\n" 1928 " gl_Position = positions[gl_VertexIndex];\n" 1929 "}\n"; 1930 1931 1932 static const char* fragmentSource = 1933 "#version 440\n" 1934 "precision highp float;\n" 1935 "layout(location = 0) out highp vec4 fragColor;\n" 1936 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n" 1937 "layout(push_constant) uniform PushConstantsBlock\n" 1938 "{\n" 1939 " int sampleId;\n" 1940 "} pushConstants;\n" 1941 "void main (void)\n" 1942 "{\n" 1943 " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n" 1944 "}\n"; 1945 1946 programCollection.glslSources.add("quad_vert") << glu::VertexSource(vertexSource); 1947 programCollection.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource); 1948 } 1949} 1950 1951 1952TestInstance* SampleMaskWithConservativeTest::createInstance (Context& context) const 1953{ 1954 return new SampleMaskWithConservativeInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enableMinSampleShading, m_minSampleShading, m_enableSampleMask, m_sampleMask, 1955 m_conservativeRasterizationMode, m_enablePostDepthCoverage, true, m_renderType, m_useFragmentShadingRate); 1956} 1957 1958// SampleMaskWithDepthTestTest 1959#ifndef CTS_USES_VULKANSC 1960SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext& testContext, 1961 const std::string& name, 1962 const PipelineConstructionType pipelineConstructionType, 1963 const VkSampleCountFlagBits rasterizationSamples, 1964 const bool enablePostDepthCoverage, 1965 const bool useFragmentShadingRate) 1966 : vkt::TestCase (testContext, name) 1967 , m_pipelineConstructionType (pipelineConstructionType) 1968 , m_rasterizationSamples (rasterizationSamples) 1969 , m_enablePostDepthCoverage (enablePostDepthCoverage) 1970 , m_useFragmentShadingRate (useFragmentShadingRate) 1971{ 1972} 1973 1974void SampleMaskWithDepthTestTest::checkSupport (Context& context) const 1975{ 1976 if (!context.getDeviceProperties().limits.standardSampleLocations) 1977 TCU_THROW(NotSupportedError, "standardSampleLocations required"); 1978 1979 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage"); 1980 1981 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 1982 1983 if (m_useFragmentShadingRate) 1984 { 1985 if (!context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask) 1986 TCU_THROW(NotSupportedError, "fragmentShadingRateWithShaderSampleMask not supported"); 1987 1988 if (!checkFragmentShadingRateRequirements(context, m_rasterizationSamples)) 1989 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported"); 1990 } 1991} 1992 1993void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const 1994{ 1995 DE_ASSERT((int)m_rasterizationSamples <= 32); 1996 1997 static const char* vertexSource = 1998 "#version 440\n" 1999 "layout(location = 0) in vec4 position;\n" 2000 "layout(location = 1) in vec4 color;\n" 2001 "layout(location = 0) out vec4 vtxColor;\n" 2002 "out gl_PerVertex\n" 2003 "{\n" 2004 " vec4 gl_Position;\n" 2005 "};\n" 2006 "\n" 2007 "void main (void)\n" 2008 "{\n" 2009 " gl_Position = position;\n" 2010 " vtxColor = color;\n" 2011 "}\n"; 2012 2013 uint32_t samplesPerFragment = m_rasterizationSamples; 2014 if (m_useFragmentShadingRate) 2015 { 2016 // When FSR coverage is enabled the tests uses a pipeline FSR rate of {2,2}, 2017 // which means each fragment shader invocation covers 4 pixels. 2018 samplesPerFragment *= 4; 2019 2020 if (!m_enablePostDepthCoverage) 2021 // For the 4 specific pixels this tests verifies, the primitive 2022 // drawn by the test fully covers 3 of those pixels and 2023 // partially covers 1 of them. When the fragment shader executes 2024 // for those 4 pixels the non-PostDepthCoverage sample mask 2025 // (the sample mask before the depth test) will only have 2026 // 7/8 of the samples set since the last 1/8 is not even covered 2027 // by the primitive. 2028 samplesPerFragment -= m_rasterizationSamples / 2; 2029 } 2030 2031 std::ostringstream fragmentSource; 2032 fragmentSource << 2033 "#version 440\n" 2034 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") << 2035 "layout(early_fragment_tests) in;\n" 2036 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") << 2037 "layout(location = 0) in vec4 vtxColor;\n" 2038 "layout(location = 0) out vec4 fragColor;\n" 2039 "void main (void)\n" 2040 "{\n" 2041 " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n" 2042 " fragColor = vtxColor * (1.0 / " << samplesPerFragment << " * coveredSamples);\n" 2043 "}\n"; 2044 2045 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource); 2046 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str()); 2047} 2048 2049TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const 2050{ 2051 return new SampleMaskWithDepthTestInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enablePostDepthCoverage, m_useFragmentShadingRate); 2052} 2053#endif // CTS_USES_VULKANSC 2054 2055// RasterizationSamplesInstance 2056 2057RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context, 2058 PipelineConstructionType pipelineConstructionType, 2059 VkPrimitiveTopology topology, 2060 float pointSize, 2061 const std::vector<Vertex4RGBA>& vertices, 2062 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2063 const VkPipelineColorBlendAttachmentState& blendState, 2064 const TestModeFlags modeFlags, 2065 ImageBackingMode backingMode, 2066 const bool useFragmentShadingRate) 2067 : vkt::TestInstance (context) 2068 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2069 , m_renderSize (32, 32) 2070 , m_primitiveTopology (topology) 2071 , m_pointSize (pointSize) 2072 , m_vertices (vertices) 2073 , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)) 2074 , m_modeFlags (modeFlags) 2075 , m_useFragmentShadingRate (useFragmentShadingRate) 2076{ 2077 if (m_modeFlags != 0) 2078 { 2079 const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0; 2080 const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0; 2081 const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil); 2082 2083 if (depthStencilFormat == VK_FORMAT_UNDEFINED) 2084 TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported"); 2085 2086 const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }; 2087 const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices }; 2088 2089 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 2090 new MultisampleRenderer( 2091 context, pipelineConstructionType, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2092 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate)); 2093 } 2094 else 2095 { 2096 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 2097 new MultisampleRenderer( 2098 context, pipelineConstructionType, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, 2099 blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate)); 2100 } 2101} 2102 2103tcu::TestStatus RasterizationSamplesInstance::iterate (void) 2104{ 2105 de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render()); 2106 return verifyImage(level->getAccess()); 2107} 2108 2109tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 2110{ 2111 // Verify range of unique pixels 2112 { 2113 const deUint32 numUniqueColors = getUniqueColorsCount(result); 2114 const deUint32 minUniqueColors = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3; 2115 2116 tcu::TestLog& log = m_context.getTestContext().getLog(); 2117 2118 log << tcu::TestLog::Message 2119 << "\nMin. unique colors expected: " << minUniqueColors << "\n" 2120 << "Unique colors found: " << numUniqueColors << "\n" 2121 << tcu::TestLog::EndMessage; 2122 2123 if (numUniqueColors < minUniqueColors) 2124 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 2125 } 2126 2127 // Verify shape of the rendered primitive (fuzzy-compare) 2128 { 2129 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 2130 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); 2131 const ColorVertexShader vertexShader; 2132 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); 2133 const rr::Program program (&vertexShader, &fragmentShader); 2134 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 2135 rr::RenderState renderState (refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits); 2136 2137 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) 2138 { 2139 VkPhysicalDeviceProperties deviceProperties; 2140 2141 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties); 2142 2143 // gl_PointSize is clamped to pointSizeRange 2144 renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]); 2145 } 2146 2147 if (m_modeFlags == 0) 2148 { 2149 refRenderer.colorClear(tcu::Vec4(0.0f)); 2150 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 2151 } 2152 else 2153 { 2154 // For depth/stencil case the primitive is invisible and the surroundings are filled red. 2155 refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 2156 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 2157 } 2158 2159 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT)) 2160 return tcu::TestStatus::fail("Primitive has unexpected shape"); 2161 } 2162 2163 return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds"); 2164} 2165 2166 2167// MinSampleShadingInstance 2168 2169MinSampleShadingInstance::MinSampleShadingInstance (Context& context, 2170 const PipelineConstructionType pipelineConstructionType, 2171 VkPrimitiveTopology topology, 2172 float pointSize, 2173 const std::vector<Vertex4RGBA>& vertices, 2174 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2175 const VkPipelineColorBlendAttachmentState& colorBlendState, 2176 ImageBackingMode backingMode, 2177 const bool useFragmentShadingRate) 2178 : vkt::TestInstance (context) 2179 , m_pipelineConstructionType(pipelineConstructionType) 2180 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2181 , m_renderSize (32, 32) 2182 , m_primitiveTopology (topology) 2183 , m_vertices (vertices) 2184 , m_multisampleStateParams (multisampleStateParams) 2185 , m_colorBlendState (colorBlendState) 2186 , m_backingMode (backingMode) 2187 , m_useFragmentShadingRate (useFragmentShadingRate) 2188{ 2189 DE_UNREF(pointSize); 2190} 2191 2192tcu::TestStatus MinSampleShadingInstance::iterate (void) 2193{ 2194 de::MovePtr<tcu::TextureLevel> noSampleshadingImage; 2195 std::vector<tcu::TextureLevel> sampleShadedImages; 2196 2197 // Render and resolve without sample shading 2198 { 2199 VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams; 2200 multisampleStateParms.sampleShadingEnable = VK_FALSE; 2201 multisampleStateParms.minSampleShading = 0.0; 2202 2203 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate); 2204 noSampleshadingImage = renderer.render(); 2205 } 2206 2207 // Render with test minSampleShading and collect per-sample images 2208 { 2209 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode, m_useFragmentShadingRate); 2210 renderer.render(); 2211 2212 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples); 2213 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) 2214 { 2215 sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId); 2216 } 2217 } 2218 2219 // Log images 2220 { 2221 tcu::TestLog& testLog = m_context.getTestContext().getLog(); 2222 2223 testLog << tcu::TestLog::ImageSet("Images", "Images") 2224 << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess()); 2225 2226 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) 2227 { 2228 testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess()); 2229 } 2230 testLog << tcu::TestLog::EndImageSet; 2231 } 2232 2233 return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess()); 2234} 2235 2236tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage) 2237{ 2238 const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth(); 2239 2240 bool anyPixelCovered = false; 2241 2242 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) 2243 { 2244 const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx); 2245 2246 if (noSampleShadingValue == 0) 2247 { 2248 // non-covered pixel, continue 2249 continue; 2250 } 2251 else 2252 { 2253 anyPixelCovered = true; 2254 } 2255 2256 int numNotCoveredSamples = 0; 2257 2258 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> 2259 2260 // Collect histogram of occurrences or each pixel across all samples 2261 for (size_t i = 0; i < sampleShadedImages.size(); ++i) 2262 { 2263 const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx); 2264 2265 if (sampleShadedValue == 0) 2266 { 2267 numNotCoveredSamples++; 2268 continue; 2269 } 2270 2271 if (histogram.find(sampleShadedValue) != histogram.end()) 2272 histogram[sampleShadedValue]++; 2273 else 2274 histogram[sampleShadedValue] = 1; 2275 } 2276 2277 if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size())) 2278 { 2279 return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected"); 2280 } 2281 2282 const int uniqueColorsCount = (int)histogram.size(); 2283 const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f); 2284 2285 if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount) 2286 { 2287 return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading"); 2288 } 2289 } 2290 2291 if (!anyPixelCovered) 2292 { 2293 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading"); 2294 } 2295 2296 return tcu::TestStatus::pass("Got proper count of unique colors"); 2297} 2298 2299MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance (Context& context, 2300 const PipelineConstructionType pipelineConstructionType, 2301 VkPrimitiveTopology topology, 2302 float pointSize, 2303 const std::vector<Vertex4RGBA>& vertices, 2304 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2305 const VkPipelineColorBlendAttachmentState& blendState, 2306 ImageBackingMode backingMode, 2307 const bool useFragmentShadingRate) 2308 : MinSampleShadingInstance (context, pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode, useFragmentShadingRate) 2309{ 2310} 2311 2312tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, 2313 const tcu::ConstPixelBufferAccess& noSampleshadingImage) 2314{ 2315 const deUint32 samplesCount = (int)sampleShadedImages.size(); 2316 const deUint32 width = noSampleshadingImage.getWidth(); 2317 const deUint32 height = noSampleshadingImage.getHeight(); 2318 const deUint32 depth = noSampleshadingImage.getDepth(); 2319 const tcu::UVec4 zeroPixel = tcu::UVec4(); 2320 bool anyPixelCovered = false; 2321 2322 DE_ASSERT(depth == 1); 2323 DE_UNREF(depth); 2324 2325 for (deUint32 y = 0; y < height; ++y) 2326 for (deUint32 x = 0; x < width; ++x) 2327 { 2328 const tcu::UVec4 noSampleShadingValue = noSampleshadingImage.getPixelUint(x, y); 2329 2330 if (noSampleShadingValue == zeroPixel) 2331 continue; 2332 2333 anyPixelCovered = true; 2334 tcu::UVec4 sampleShadingValue = tcu::UVec4(); 2335 2336 // Collect histogram of occurrences or each pixel across all samples 2337 for (size_t i = 0; i < samplesCount; ++i) 2338 { 2339 const tcu::UVec4 sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y); 2340 2341 sampleShadingValue += sampleShadedValue; 2342 } 2343 2344 sampleShadingValue = sampleShadingValue / samplesCount; 2345 2346 if (sampleShadingValue.w() != 255) 2347 { 2348 return tcu::TestStatus::fail("Invalid Alpha channel value"); 2349 } 2350 2351 if (sampleShadingValue != noSampleShadingValue) 2352 { 2353 return tcu::TestStatus::fail("Invalid color"); 2354 } 2355 } 2356 2357 if (!anyPixelCovered) 2358 { 2359 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShadingDisabled"); 2360 } 2361 2362 return tcu::TestStatus::pass("Got proper count of unique colors"); 2363} 2364 2365SampleMaskInstance::SampleMaskInstance (Context& context, 2366 const PipelineConstructionType pipelineConstructionType, 2367 VkPrimitiveTopology topology, 2368 float pointSize, 2369 const std::vector<Vertex4RGBA>& vertices, 2370 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2371 const VkPipelineColorBlendAttachmentState& blendState, 2372 ImageBackingMode backingMode, 2373 const bool useFragmentShadingRate) 2374 : vkt::TestInstance (context) 2375 , m_pipelineConstructionType(pipelineConstructionType) 2376 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2377 , m_renderSize (32, 32) 2378 , m_primitiveTopology (topology) 2379 , m_vertices (vertices) 2380 , m_multisampleStateParams (multisampleStateParams) 2381 , m_colorBlendState (blendState) 2382 , m_backingMode (backingMode) 2383 , m_useFragmentShadingRate (useFragmentShadingRate) 2384{ 2385 DE_UNREF(pointSize); 2386} 2387 2388tcu::TestStatus SampleMaskInstance::iterate (void) 2389{ 2390 de::MovePtr<tcu::TextureLevel> testSampleMaskImage; 2391 de::MovePtr<tcu::TextureLevel> minSampleMaskImage; 2392 de::MovePtr<tcu::TextureLevel> maxSampleMaskImage; 2393 2394 // Render with test flags 2395 { 2396 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate); 2397 testSampleMaskImage = renderer.render(); 2398 } 2399 2400 // Render with all flags off 2401 { 2402 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 2403 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0); 2404 2405 multisampleParams.pSampleMask = sampleMask.data(); 2406 2407 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate); 2408 minSampleMaskImage = renderer.render(); 2409 } 2410 2411 // Render with all flags on 2412 { 2413 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 2414 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0)); 2415 2416 multisampleParams.pSampleMask = sampleMask.data(); 2417 2418 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate); 2419 maxSampleMaskImage = renderer.render(); 2420 } 2421 2422 return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess()); 2423} 2424 2425tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage, 2426 const tcu::ConstPixelBufferAccess& minSampleMaskImage, 2427 const tcu::ConstPixelBufferAccess& maxSampleMaskImage) 2428{ 2429 const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage); 2430 const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage); 2431 const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage); 2432 2433 tcu::TestLog& log = m_context.getTestContext().getLog(); 2434 2435 log << tcu::TestLog::Message 2436 << "\nColors found: " << testColorCount << "\n" 2437 << "Min. colors expected: " << minColorCount << "\n" 2438 << "Max. colors expected: " << maxColorCount << "\n" 2439 << tcu::TestLog::EndMessage; 2440 2441 if (minColorCount > testColorCount || testColorCount > maxColorCount) 2442 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 2443 else 2444 return tcu::TestStatus::pass("Unique colors within expected bounds"); 2445} 2446#ifndef CTS_USES_VULKANSC 2447tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params) 2448{ 2449 const VkSampleCountFlagBits samples[] = 2450 { 2451 VK_SAMPLE_COUNT_1_BIT, 2452 VK_SAMPLE_COUNT_2_BIT, 2453 VK_SAMPLE_COUNT_4_BIT, 2454 VK_SAMPLE_COUNT_8_BIT, 2455 VK_SAMPLE_COUNT_16_BIT, 2456 VK_SAMPLE_COUNT_32_BIT, 2457 VK_SAMPLE_COUNT_64_BIT 2458 }; 2459 2460 const Vertex4RGBA vertexData[3] = 2461 { 2462 { 2463 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 2464 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 2465 }, 2466 { 2467 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 2468 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 2469 }, 2470 { 2471 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 2472 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 2473 } 2474 }; 2475 2476 const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3); 2477 deUint32 prevUniqueColors = 2; 2478 int renderCount = 0; 2479 2480 // Do not render with 1 sample (start with samplesNdx = 1). 2481 for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2482 { 2483 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx])) 2484 continue; 2485 2486 if (params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, samples[samplesNdx])) 2487 continue; 2488 2489 const VkPipelineMultisampleStateCreateInfo multisampleStateParams 2490 { 2491 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2492 DE_NULL, // const void* pNext; 2493 0u, // VkPipelineMultisampleStateCreateFlags flags; 2494 samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples; 2495 false, // VkBool32 sampleShadingEnable; 2496 0.0f, // float minSampleShading; 2497 DE_NULL, // const VkSampleMask* pSampleMask; 2498 false, // VkBool32 alphaToCoverageEnable; 2499 false // VkBool32 alphaToOneEnable; 2500 }; 2501 2502 MultisampleRenderer renderer (context, params.pipelineConstructionType, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode, params.useFragmentShadingRate); 2503 de::MovePtr<tcu::TextureLevel> result = renderer.render(); 2504 const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess()); 2505 2506 renderCount++; 2507 2508 if (prevUniqueColors > uniqueColors) 2509 { 2510 std::ostringstream message; 2511 2512 message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx]; 2513 return tcu::TestStatus::fail(message.str()); 2514 } 2515 2516 prevUniqueColors = uniqueColors; 2517 } 2518 2519 if (renderCount == 0) 2520 { 2521 if (params.useFragmentShadingRate && !context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate) 2522 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate is unsupported"); 2523 TCU_THROW(NotSupportedError, "Multisampling is unsupported"); 2524 } 2525 2526 return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases"); 2527} 2528#endif // CTS_USES_VULKANSC 2529 2530// AlphaToOneInstance 2531 2532AlphaToOneInstance::AlphaToOneInstance (Context& context, 2533 const PipelineConstructionType pipelineConstructionType, 2534 VkPrimitiveTopology topology, 2535 const std::vector<Vertex4RGBA>& vertices, 2536 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2537 const VkPipelineColorBlendAttachmentState& blendState, 2538 ImageBackingMode backingMode, 2539 const bool useFragmentShadingRate) 2540 : vkt::TestInstance (context) 2541 , m_pipelineConstructionType(pipelineConstructionType) 2542 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2543 , m_renderSize (32, 32) 2544 , m_primitiveTopology (topology) 2545 , m_vertices (vertices) 2546 , m_multisampleStateParams (multisampleStateParams) 2547 , m_colorBlendState (blendState) 2548 , m_backingMode (backingMode) 2549 , m_useFragmentShadingRate (useFragmentShadingRate) 2550{ 2551} 2552 2553tcu::TestStatus AlphaToOneInstance::iterate (void) 2554{ 2555 DE_ASSERT(m_multisampleStateParams.alphaToOneEnable); 2556 DE_ASSERT(m_colorBlendState.blendEnable); 2557 2558 de::MovePtr<tcu::TextureLevel> alphaOneImage; 2559 de::MovePtr<tcu::TextureLevel> noAlphaOneImage; 2560 2561 RenderType renderType = m_multisampleStateParams.rasterizationSamples == vk::VK_SAMPLE_COUNT_1_BIT ? RENDER_TYPE_SINGLE_SAMPLE : RENDER_TYPE_RESOLVE; 2562 2563 // Render with blend enabled and alpha to one on 2564 { 2565 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate); 2566 alphaOneImage = renderer.render(); 2567 } 2568 2569 // Render with blend enabled and alpha to one off 2570 { 2571 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 2572 multisampleParams.alphaToOneEnable = false; 2573 2574 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate); 2575 noAlphaOneImage = renderer.render(); 2576 } 2577 2578 return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess()); 2579} 2580 2581tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 2582 const tcu::ConstPixelBufferAccess& noAlphaOneImage) 2583{ 2584 for (int y = 0; y < m_renderSize.y(); y++) 2585 { 2586 for (int x = 0; x < m_renderSize.x(); x++) 2587 { 2588 if (alphaOneImage.getPixel(x, y).w() != 1.0) 2589 { 2590 std::ostringstream message; 2591 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " doesn't have alpha set to 1"; 2592 return tcu::TestStatus::fail(message.str()); 2593 } 2594 2595 if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y)))) 2596 { 2597 std::ostringstream message; 2598 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y); 2599 return tcu::TestStatus::fail(message.str()); 2600 } 2601 } 2602 } 2603 2604 return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one"); 2605} 2606 2607 2608// AlphaToCoverageInstance 2609 2610AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context, 2611 const PipelineConstructionType pipelineConstructionType, 2612 VkPrimitiveTopology topology, 2613 const std::vector<Vertex4RGBA>& vertices, 2614 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2615 const VkPipelineColorBlendAttachmentState& blendState, 2616 GeometryType geometryType, 2617 ImageBackingMode backingMode, 2618 const bool useFragmentShadingRate, 2619 const bool checkDepthBuffer) 2620 : vkt::TestInstance (context) 2621 , m_pipelineConstructionType(pipelineConstructionType) 2622 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2623 , m_depthStencilFormat (VK_FORMAT_D16_UNORM) 2624 , m_renderSize (32, 32) 2625 , m_primitiveTopology (topology) 2626 , m_vertices (vertices) 2627 , m_multisampleStateParams (multisampleStateParams) 2628 , m_colorBlendState (blendState) 2629 , m_geometryType (geometryType) 2630 , m_backingMode (backingMode) 2631 , m_useFragmentShadingRate (useFragmentShadingRate) 2632 , m_checkDepthBuffer (checkDepthBuffer) 2633{ 2634} 2635 2636tcu::TestStatus AlphaToCoverageInstance::iterate (void) 2637{ 2638 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); 2639 2640 de::MovePtr<tcu::TextureLevel> result; 2641 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_checkDepthBuffer, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate); 2642 2643 result = renderer.render(); 2644 2645 const auto colorStatus = verifyImage(result->getAccess()); 2646 auto depthStatus = tcu::TestStatus::pass("Pass"); 2647 2648 if (m_checkDepthBuffer) 2649 { 2650 const auto redrawResult = renderer.renderReusingDepth(); 2651 depthStatus = verifyDepthBufferCheck(redrawResult->getAccess()); 2652 } 2653 2654 if (colorStatus.getCode() == QP_TEST_RESULT_FAIL) 2655 return colorStatus; 2656 2657 if (depthStatus.getCode() == QP_TEST_RESULT_FAIL) 2658 return depthStatus; 2659 2660 return colorStatus; 2661} 2662 2663tcu::TestStatus AlphaToCoverageInstance::verifyDepthBufferCheck (const tcu::ConstPixelBufferAccess& result) 2664{ 2665 const tcu::Vec4 refColor (0.0f, 0.0f, 1.0f, 1.0f); // Must match "checkDepth-vert". 2666 const tcu::Vec4 threshold (0.0f, 0.0f, 0.0f, 0.0f); 2667 2668 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "BlueColor", "", refColor, result, threshold, tcu::COMPARE_LOG_ON_ERROR)) 2669 return tcu::TestStatus::fail("Depth buffer verification failed: depth buffer was not clear"); 2670 return tcu::TestStatus::pass("Pass"); 2671} 2672 2673tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 2674{ 2675 float maxColorValue; 2676 float minColorValue; 2677 2678 switch (m_geometryType) 2679 { 2680 case GEOMETRY_TYPE_OPAQUE_QUAD: 2681 maxColorValue = 1.01f; 2682 minColorValue = 0.99f; 2683 break; 2684 2685 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 2686 maxColorValue = 0.52f; 2687 minColorValue = 0.0f; 2688 break; 2689 2690 case GEOMETRY_TYPE_INVISIBLE_QUAD: 2691 maxColorValue = 0.01f; 2692 minColorValue = 0.0f; 2693 break; 2694 2695 default: 2696 maxColorValue = 0.0f; 2697 minColorValue = 0.0f; 2698 DE_ASSERT(false); 2699 } 2700 2701 auto& log = m_context.getTestContext().getLog(); 2702 log << tcu::TestLog::Image("Result", "Result Image", result); 2703 2704 for (int y = 0; y < m_renderSize.y(); y++) 2705 { 2706 for (int x = 0; x < m_renderSize.x(); x++) 2707 { 2708 const auto pixel = result.getPixel(x, y); 2709 const auto red = pixel.x(); 2710 2711 if (red > maxColorValue || red < minColorValue) 2712 { 2713 std::ostringstream message; 2714 message << "Pixel is not in the expected range: " << red << " not in [" << minColorValue << ", " << maxColorValue << "]"; 2715 return tcu::TestStatus::fail(message.str()); 2716 } 2717 } 2718 } 2719 2720 return tcu::TestStatus::pass("Image matches reference value"); 2721} 2722 2723// AlphaToCoverageNoColorAttachmentInstance 2724 2725AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context& context, 2726 const PipelineConstructionType pipelineConstructionType, 2727 VkPrimitiveTopology topology, 2728 const std::vector<Vertex4RGBA>& vertices, 2729 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2730 const VkPipelineColorBlendAttachmentState& blendState, 2731 GeometryType geometryType, 2732 ImageBackingMode backingMode, 2733 const bool useFragmentShadingRate) 2734 : vkt::TestInstance (context) 2735 , m_pipelineConstructionType(pipelineConstructionType) 2736 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2737 , m_depthStencilFormat (VK_FORMAT_D16_UNORM) 2738 , m_renderSize (32, 32) 2739 , m_primitiveTopology (topology) 2740 , m_vertices (vertices) 2741 , m_multisampleStateParams (multisampleStateParams) 2742 , m_colorBlendState (blendState) 2743 , m_geometryType (geometryType) 2744 , m_backingMode (backingMode) 2745 , m_useFragmentShadingRate (useFragmentShadingRate) 2746{ 2747} 2748 2749tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void) 2750{ 2751 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); 2752 2753 de::MovePtr<tcu::TextureLevel> result; 2754 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, m_useFragmentShadingRate, 1.0f); 2755 2756 result = renderer.render(); 2757 2758 return verifyImage(result->getAccess()); 2759} 2760 2761tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 2762{ 2763 for (int y = 0; y < m_renderSize.y(); y++) 2764 { 2765 for (int x = 0; x < m_renderSize.x(); x++) 2766 { 2767 // Expect full red for each pixel. Fail if clear color is showing. 2768 if (result.getPixel(x, y).x() < 1.0f) 2769 { 2770 // Log result image when failing. 2771 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet; 2772 2773 return tcu::TestStatus::fail("Fail"); 2774 } 2775 } 2776 } 2777 2778 return tcu::TestStatus::pass("Pass"); 2779} 2780 2781// AlphaToCoverageColorUnusedAttachmentInstance 2782 2783AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context& context, 2784 const PipelineConstructionType pipelineConstructionType, 2785 VkPrimitiveTopology topology, 2786 const std::vector<Vertex4RGBA>& vertices, 2787 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 2788 const VkPipelineColorBlendAttachmentState& blendState, 2789 GeometryType geometryType, 2790 ImageBackingMode backingMode, 2791 const bool useFragmentShadingRate) 2792 : vkt::TestInstance (context) 2793 , m_pipelineConstructionType (pipelineConstructionType) 2794 , m_colorFormat (VK_FORMAT_R5G6B5_UNORM_PACK16) 2795 , m_renderSize (32, 32) 2796 , m_primitiveTopology (topology) 2797 , m_vertices (vertices) 2798 , m_multisampleStateParams (multisampleStateParams) 2799 , m_colorBlendState (blendState) 2800 , m_geometryType (geometryType) 2801 , m_backingMode (backingMode) 2802 , m_useFragmentShadingRate (useFragmentShadingRate) 2803{ 2804} 2805 2806tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void) 2807{ 2808 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); 2809 2810 de::MovePtr<tcu::TextureLevel> result; 2811 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode, m_useFragmentShadingRate); 2812 2813 result = renderer.render(); 2814 2815 return verifyImage(result->getAccess()); 2816} 2817 2818tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 2819{ 2820 for (int y = 0; y < m_renderSize.y(); y++) 2821 { 2822 for (int x = 0; x < m_renderSize.x(); x++) 2823 { 2824 // Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused. 2825 // The coverage should still be affected by the alpha written to location 0. 2826 if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f) 2827 || (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f)) 2828 { 2829 // Log result image when failing. 2830 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet; 2831 2832 return tcu::TestStatus::fail("Fail"); 2833 } 2834 } 2835 } 2836 2837 return tcu::TestStatus::pass("Pass"); 2838} 2839 2840// SampleMaskWithConservativeInstance 2841 2842SampleMaskWithConservativeInstance::SampleMaskWithConservativeInstance (Context& context, 2843 const PipelineConstructionType pipelineConstructionType, 2844 const VkSampleCountFlagBits rasterizationSamples, 2845 const bool enableMinSampleShading, 2846 const float minSampleShading, 2847 const bool enableSampleMask, 2848 const VkSampleMask sampleMask, 2849 const VkConservativeRasterizationModeEXT conservativeRasterizationMode, 2850 const bool enablePostDepthCoverage, 2851 const bool enableFullyCoveredEXT, 2852 const RenderType renderType, 2853 const bool useFragmentShadingRate) 2854 : vkt::TestInstance (context) 2855 , m_pipelineConstructionType (pipelineConstructionType) 2856 , m_rasterizationSamples (rasterizationSamples) 2857 , m_enablePostDepthCoverage (enablePostDepthCoverage) 2858 , m_enableFullyCoveredEXT (enableFullyCoveredEXT) 2859 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 2860 , m_depthStencilFormat (VK_FORMAT_D16_UNORM) 2861 , m_renderSize (tcu::IVec2(10, 10)) 2862 , m_useDepth (true) 2863 , m_useStencil (false) 2864 , m_useConservative (true) 2865 , m_useFragmentShadingRate (useFragmentShadingRate) 2866 , m_conservativeRasterizationMode (conservativeRasterizationMode) 2867 , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 2868 , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) 2869 , m_depthClearValue (0.5f) 2870 , m_vertices (generateVertices()) 2871 , m_enableSampleMask (enableSampleMask) 2872 , m_sampleMask (std::vector<VkSampleMask>{sampleMask}) 2873 , m_enableMinSampleShading (enableMinSampleShading) 2874 , m_minSampleShading (minSampleShading) 2875 , m_multisampleStateParams (getMultisampleState(rasterizationSamples, enableMinSampleShading, minSampleShading, enableSampleMask)) 2876 , m_rasterizationConservativeStateCreateInfo (getRasterizationConservativeStateCreateInfo(conservativeRasterizationMode)) 2877 , m_blendState (getDefaultColorBlendAttachmentState()) 2878 , m_renderType (renderType) 2879 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR) 2880{ 2881} 2882 2883tcu::TestStatus SampleMaskWithConservativeInstance::iterate (void) 2884{ 2885 2886 de::MovePtr<tcu::TextureLevel> noSampleshadingImage; 2887 std::vector<tcu::TextureLevel> sampleShadedImages; 2888 2889 { 2890 MultisampleRenderer renderer(m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, m_useConservative, m_useFragmentShadingRate, 1u, 2891 &m_topology, &m_vertices, m_multisampleStateParams, m_blendState, m_rasterizationConservativeStateCreateInfo, RENDER_TYPE_RESOLVE, m_imageBackingMode, m_depthClearValue); 2892 noSampleshadingImage = renderer.render(); 2893 } 2894 2895 { 2896 const VkPipelineColorBlendAttachmentState colorBlendState = 2897 { 2898 false, // VkBool32 blendEnable; 2899 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 2900 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 2901 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 2902 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 2903 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 2904 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 2905 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 2906 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 2907 }; 2908 2909 MultisampleRenderer mRenderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_vertices, m_multisampleStateParams, colorBlendState, RENDER_TYPE_COPY_SAMPLES, IMAGE_BACKING_MODE_REGULAR, m_useFragmentShadingRate); 2910 mRenderer.render(); 2911 2912 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples); 2913 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) 2914 { 2915 sampleShadedImages[sampleId] = *mRenderer.getSingleSampledImage(sampleId); 2916 } 2917 2918 } 2919 2920 return verifyImage(sampleShadedImages, noSampleshadingImage->getAccess()); 2921} 2922 2923VkPipelineMultisampleStateCreateInfo SampleMaskWithConservativeInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples, const bool enableMinSampleShading, const float minSampleShading, const bool enableSampleMask) 2924{ 2925 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 2926 { 2927 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2928 DE_NULL, // const void* pNext; 2929 0u, // VkPipelineMultisampleStateCreateFlags flags; 2930 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 2931 enableMinSampleShading ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable; 2932 enableMinSampleShading ? minSampleShading : 0.0f, // float minSampleShading; 2933 enableSampleMask ? m_sampleMask.data() : DE_NULL, // const VkSampleMask* pSampleMask; 2934 false, // VkBool32 alphaToCoverageEnable; 2935 false // VkBool32 alphaToOneEnable; 2936 }; 2937 2938 return multisampleStateParams; 2939} 2940 2941VkPipelineRasterizationConservativeStateCreateInfoEXT SampleMaskWithConservativeInstance::getRasterizationConservativeStateCreateInfo(const VkConservativeRasterizationModeEXT conservativeRasterizationMode) 2942{ 2943 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo = 2944 { 2945 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType; 2946 DE_NULL, // const void* pNext; 2947 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags; 2948 conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode; 2949 0.0f // float extraPrimitiveOverestimationSize; 2950 }; 2951 2952 return rasterizationConservativeStateCreateInfo; 2953} 2954 2955std::vector<Vertex4RGBA> SampleMaskWithConservativeInstance::generateVertices (void) 2956{ 2957 std::vector<Vertex4RGBA> vertices; 2958 2959 { 2960 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor }; 2961 vertices.push_back(vertexInput); 2962 } 2963 { 2964 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor }; 2965 vertices.push_back(vertexInput); 2966 } 2967 { 2968 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), m_renderColor }; 2969 vertices.push_back(vertexInput); 2970 } 2971 2972 return vertices; 2973} 2974 2975tcu::TestStatus SampleMaskWithConservativeInstance::verifyImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& result) 2976{ 2977 bool pass = true; 2978 const int width = result.getWidth(); 2979 const int height = result.getHeight(); 2980 tcu::TestLog& log = m_context.getTestContext().getLog(); 2981 2982 const deUint32 samplesCount = (int)sampleShadedImages.size(); 2983 2984 for (size_t i = 0; i < samplesCount; ++i) 2985 { 2986 const tcu::ConstPixelBufferAccess &s = sampleShadedImages[i].getAccess(); 2987 2988 log << tcu::TestLog::ImageSet("Per sample image", "Per sampe image") 2989 << tcu::TestLog::Image("Layer", "Layer", s) 2990 << tcu::TestLog::EndImageSet; 2991 } 2992 2993 // Leave sample count intact (return 1) if multiplication by minSampleShading won't exceed base 2 2994 // otherwise round up to the nearest power of 2 2995 auto sampleCountDivider = [](float x) { 2996 float power = 1.0; 2997 while (power < x) 2998 { 2999 power *= 2; 3000 } 3001 return power; 3002 }; 3003 3004 DE_ASSERT(width == 10); 3005 DE_ASSERT(height == 10); 3006 3007 const tcu::Vec4 clearColor = tcu::Vec4(0.0f); 3008 std::vector<std::pair<int, int>> fullyCoveredPixelsCoordinateSet; 3009 3010 // Generating set of pixel coordinate values covered by the triangle 3011 if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT) 3012 { 3013 for (int i = 0; i < width; i++) 3014 { 3015 for (int j = 0; j < height; j++) 3016 { 3017 // Rasterization will cover half of the triangle plus 1 pixel edge due to the overeestimation 3018 if (i < 5 && i + j < 11) 3019 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j)); 3020 } 3021 } 3022 } 3023 else 3024 { 3025 if (m_useFragmentShadingRate && !m_enableMinSampleShading) 3026 { 3027 // When m_enableMinSampleShading is not enabled shader uses gl_FragFullyCoveredNV. 3028 // Additionaly when FSR coverage is enabled the tests uses a pipeline FSR rate of { 2,2 } 3029 // and as a result rasterization will cover only four pixels due to the underestimation. 3030 for (int i = 2; i < 4; i++) 3031 for (int j = 2; j < 4; j++) 3032 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j)); 3033 } 3034 else 3035 { 3036 for (int i = 1; i < width; i++) 3037 { 3038 for (int j = 1; j < height; j++) 3039 { 3040 // Rasterization will cover half of the triangle minus 1 pixel edge due to the underestimation 3041 if (i < 5 && i + j < 8) 3042 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j)); 3043 } 3044 } 3045 } 3046 } 3047 3048 for (int x = 0; x < width; ++x) 3049 for (int y = 0; y < height; ++y) 3050 { 3051 const tcu::Vec4 resultPixel = result.getPixel(x, y); 3052 3053 if (std::find(fullyCoveredPixelsCoordinateSet.begin(), fullyCoveredPixelsCoordinateSet.end(), std::make_pair(x, y)) != fullyCoveredPixelsCoordinateSet.end()) 3054 { 3055 if (m_enableMinSampleShading) 3056 { 3057 tcu::UVec4 sampleShadingValue = tcu::UVec4(); 3058 for (size_t i = 0; i < samplesCount; ++i) 3059 { 3060 const tcu::UVec4 sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y); 3061 3062 sampleShadingValue += sampleShadedValue; 3063 } 3064 3065 //Calculate coverage of a single sample Image based on accumulated value from the whole set 3066 int sampleCoverageValue = sampleShadingValue.w() / samplesCount; 3067 //Calculates an estimated coverage value based on the number of samples and the minimumSampleShading 3068 int expectedCovergaveValue = (int)(255.0 / sampleCountDivider((float)m_rasterizationSamples * m_minSampleShading)) + 1; 3069 3070 //The specification allows for larger sample count than minimum value, however resulted coverage should never be lower than minimum 3071 if (sampleCoverageValue > expectedCovergaveValue) 3072 { 3073 log << tcu::TestLog::Message << "Coverage value " << sampleCoverageValue << " greather than expected: " << expectedCovergaveValue << tcu::TestLog::EndMessage; 3074 3075 pass = false; 3076 } 3077 } 3078 else if (m_enableSampleMask) 3079 { 3080 // Sample mask with all bits on will not affect fragment coverage 3081 if (m_sampleMask[0] == 0xFFFFFFFF) 3082 { 3083 if (resultPixel != m_renderColor) 3084 { 3085 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3086 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage; 3087 3088 pass = false; 3089 } 3090 } 3091 // Sample mask with half bits off will reduce sample coverage by half 3092 else if (m_sampleMask[0] == 0xAAAAAAAA) 3093 { 3094 3095 const tcu::Vec4 renderColorHalfOpacity(0.0f, 0.5f, 0.0f, 0.5f); 3096 const float threshold = 0.02f; 3097 3098 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx) 3099 { 3100 if ((renderColorHalfOpacity[componentNdx] != 0.0f && resultPixel[componentNdx] <= (renderColorHalfOpacity[componentNdx] - threshold)) 3101 || resultPixel[componentNdx] >= (renderColorHalfOpacity[componentNdx] + threshold)) 3102 { 3103 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3104 << " Reference: " << renderColorHalfOpacity << " +/- " << threshold << tcu::TestLog::EndMessage; 3105 3106 pass = false; 3107 } 3108 } 3109 } 3110 // Sample mask with all bits off will cause all fragment to failed opacity test 3111 else if (m_sampleMask[0] == 0x00000000) 3112 { 3113 if (resultPixel != clearColor) 3114 { 3115 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3116 << " Reference: " << clearColor << tcu::TestLog::EndMessage; 3117 3118 pass = false; 3119 } 3120 } 3121 else 3122 { 3123 log << tcu::TestLog::Message << "Unexpected sample mask value" << tcu::TestLog::EndMessage; 3124 3125 pass = false; 3126 } 3127 } 3128 else 3129 { 3130 if (resultPixel != m_renderColor) 3131 { 3132 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3133 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage; 3134 3135 pass = false; 3136 } 3137 } 3138 } 3139 else 3140 { 3141 if (resultPixel != clearColor) 3142 { 3143 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3144 << " Reference: " << clearColor << tcu::TestLog::EndMessage; 3145 3146 pass = false; 3147 } 3148 } 3149 } 3150 3151 if (pass) 3152 return tcu::TestStatus::pass("Passed"); 3153 else 3154 { 3155 log << tcu::TestLog::ImageSet("LayerContent", "Layer content") 3156 << tcu::TestLog::Image("Layer", "Layer", result) 3157 << tcu::TestLog::EndImageSet; 3158 3159 return tcu::TestStatus::fail("Failed"); 3160 } 3161 3162} 3163 3164// SampleMaskWithDepthTestInstance 3165#ifndef CTS_USES_VULKANSC 3166SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context& context, 3167 const PipelineConstructionType pipelineConstructionType, 3168 const VkSampleCountFlagBits rasterizationSamples, 3169 const bool enablePostDepthCoverage, 3170 const bool useFragmentShadingRate) 3171 : vkt::TestInstance (context) 3172 , m_pipelineConstructionType(pipelineConstructionType) 3173 , m_rasterizationSamples (rasterizationSamples) 3174 , m_enablePostDepthCoverage (enablePostDepthCoverage) 3175 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 3176 , m_depthStencilFormat (VK_FORMAT_D16_UNORM) 3177 , m_renderSize (tcu::IVec2(3, 3)) 3178 , m_useDepth (true) 3179 , m_useStencil (false) 3180 , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 3181 , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) 3182 , m_vertices (generateVertices()) 3183 , m_multisampleStateParams (getMultisampleState(rasterizationSamples)) 3184 , m_blendState (getDefaultColorBlendAttachmentState()) 3185 , m_renderType (RENDER_TYPE_RESOLVE) 3186 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR) 3187 , m_depthClearValue (0.667f) 3188 , m_useFragmentShadingRate (useFragmentShadingRate) 3189{ 3190 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT] = SampleCoverage(1u, 1u); // !< Sample coverage of the diagonally halved pixel, 3191 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT] = SampleCoverage(2u, 2u); // !< with max possible subPixelPrecisionBits threshold 3192 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT] = SampleCoverage(2u, 6u); // !< 3193 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT] = SampleCoverage(6u, 11u); // !< 3194} 3195 3196tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void) 3197{ 3198 de::MovePtr<tcu::TextureLevel> result; 3199 3200 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology, 3201 &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_useFragmentShadingRate, m_depthClearValue); 3202 result = renderer.render(); 3203 3204 return verifyImage(result->getAccess()); 3205} 3206 3207VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples) 3208{ 3209 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 3210 { 3211 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 3212 DE_NULL, // const void* pNext; 3213 0u, // VkPipelineMultisampleStateCreateFlags flags; 3214 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 3215 false, // VkBool32 sampleShadingEnable; 3216 0.0f, // float minSampleShading; 3217 DE_NULL, // const VkSampleMask* pSampleMask; 3218 false, // VkBool32 alphaToCoverageEnable; 3219 false // VkBool32 alphaToOneEnable; 3220 }; 3221 3222 return multisampleStateParams; 3223} 3224 3225std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void) 3226{ 3227 std::vector<Vertex4RGBA> vertices; 3228 3229 { 3230 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor }; 3231 vertices.push_back(vertexInput); 3232 } 3233 { 3234 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor }; 3235 vertices.push_back(vertexInput); 3236 } 3237 { 3238 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), m_renderColor }; 3239 vertices.push_back(vertexInput); 3240 } 3241 3242 return vertices; 3243} 3244 3245tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 3246{ 3247 bool pass = true; 3248 const int width = result.getWidth(); 3249 const int height = result.getHeight(); 3250 tcu::TestLog& log = m_context.getTestContext().getLog(); 3251 3252 DE_ASSERT(width == 3); 3253 DE_ASSERT(height == 3); 3254 3255 const tcu::Vec4 clearColor = tcu::Vec4(0.0f); 3256 3257 for (int x = 0; x < width; ++x) 3258 for (int y = 0; y < height; ++y) 3259 { 3260 const tcu::Vec4 resultPixel = result.getPixel(x, y); 3261 3262 if (x + y == 0) 3263 { 3264 const float threshold = 0.02f; 3265 tcu::Vec4 expectedPixel = m_renderColor; 3266 3267 if (m_useFragmentShadingRate && m_enablePostDepthCoverage) 3268 { 3269 // The fragment shader for this test outputs a fragment value that 3270 // is based off gl_SampleMaskIn. For the FSR case that sample mask 3271 // applies to 4 pixels, rather than the usual 1 pixel per fragment 3272 // shader invocation. Those 4 pixels represent: 3273 // a) The fully covered pixel (this "x + y == 0" case) 3274 // b) The two partially covered pixels (the "x + y == 1" case below) 3275 // c) The non-covered pixel (the "else" case below) 3276 // 3277 // For the PostDepthCoverage case, the gl_SampleMaskIn represents 3278 // coverage after the depth test, so it has roughly 50% of the bits 3279 // set. This means that the expected result for this case (a) 3280 // will not be the "m_renderColor" but ~50% of the m_renderColor. 3281 expectedPixel = expectedPixel * tcu::Vec4(0.5f); 3282 } 3283 3284 bool localPass = true; 3285 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx) 3286 { 3287 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= expectedPixel[componentNdx] * (1.0f - threshold) 3288 || resultPixel[componentNdx] >= expectedPixel[componentNdx] * (1.0f + threshold))) 3289 localPass = false; 3290 } 3291 3292 if (!localPass) 3293 { 3294 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3295 << " Reference range ( " << expectedPixel * (1.0f - threshold) << " ; " << expectedPixel * (1.0f + threshold) << " )" << tcu::TestLog::EndMessage; 3296 pass = false; 3297 } 3298 } 3299 else if (x + y == 1) 3300 { 3301 const float threshold = 0.02f; 3302 float minCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples; 3303 float maxCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples; 3304 3305 // default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test) 3306 // post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test) 3307 3308 if (m_enablePostDepthCoverage) 3309 { 3310 minCoverage *= minCoverage; 3311 maxCoverage *= maxCoverage; 3312 } 3313 3314 bool localPass = true; 3315 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx) 3316 { 3317 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold) 3318 || resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold))) 3319 localPass = false; 3320 } 3321 3322 if (!localPass) 3323 { 3324 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3325 << " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage; 3326 pass = false; 3327 } 3328 } 3329 else 3330 { 3331 if (resultPixel != clearColor) 3332 { 3333 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel 3334 << " Reference: " << clearColor << tcu::TestLog::EndMessage; 3335 pass = false; 3336 } 3337 } 3338 } 3339 3340 if (pass) 3341 return tcu::TestStatus::pass("Passed"); 3342 else 3343 return tcu::TestStatus::fail("Failed"); 3344} 3345#endif // CTS_USES_VULKANSC 3346// MultisampleRenderer 3347 3348MultisampleRenderer::MultisampleRenderer (Context& context, 3349 const PipelineConstructionType pipelineConstructionType, 3350 const VkFormat colorFormat, 3351 const tcu::IVec2& renderSize, 3352 const VkPrimitiveTopology topology, 3353 const std::vector<Vertex4RGBA>& vertices, 3354 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 3355 const VkPipelineColorBlendAttachmentState& blendState, 3356 const RenderType renderType, 3357 const ImageBackingMode backingMode, 3358 const bool useFragmentShadingRate) 3359 : m_context (context) 3360 , m_pipelineConstructionType(pipelineConstructionType) 3361 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice())) 3362 , m_colorFormat (colorFormat) 3363 , m_depthStencilFormat (VK_FORMAT_UNDEFINED) 3364 , m_renderSize (renderSize) 3365 , m_useDepth (false) 3366 , m_useStencil (false) 3367 , m_useConservative (false) 3368 , m_multisampleStateParams (multisampleStateParams) 3369 , m_colorBlendState (blendState) 3370 , m_rasterizationConservativeStateCreateInfo () 3371 , m_renderType (renderType) 3372 , m_backingMode (backingMode) 3373 , m_depthClearValue (1.0f) 3374 , m_useFragmentShadingRate (useFragmentShadingRate) 3375{ 3376 initialize(context, 1u, &topology, &vertices); 3377} 3378 3379MultisampleRenderer::MultisampleRenderer (Context& context, 3380 const PipelineConstructionType pipelineConstructionType, 3381 const VkFormat colorFormat, 3382 const VkFormat depthStencilFormat, 3383 const tcu::IVec2& renderSize, 3384 const bool useDepth, 3385 const bool useStencil, 3386 const deUint32 numTopologies, 3387 const VkPrimitiveTopology* pTopology, 3388 const std::vector<Vertex4RGBA>* pVertices, 3389 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 3390 const VkPipelineColorBlendAttachmentState& blendState, 3391 const RenderType renderType, 3392 const ImageBackingMode backingMode, 3393 const bool useFragmentShadingRate, 3394 const float depthClearValue) 3395 : m_context (context) 3396 , m_pipelineConstructionType(pipelineConstructionType) 3397 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice())) 3398 , m_colorFormat (colorFormat) 3399 , m_depthStencilFormat (depthStencilFormat) 3400 , m_renderSize (renderSize) 3401 , m_useDepth (useDepth) 3402 , m_useStencil (useStencil) 3403 , m_useConservative (false) 3404 , m_multisampleStateParams (multisampleStateParams) 3405 , m_colorBlendState (blendState) 3406 , m_rasterizationConservativeStateCreateInfo () 3407 , m_renderType (renderType) 3408 , m_backingMode (backingMode) 3409 , m_depthClearValue (depthClearValue) 3410 , m_useFragmentShadingRate (useFragmentShadingRate) 3411{ 3412 initialize(context, numTopologies, pTopology, pVertices); 3413} 3414 3415MultisampleRenderer::MultisampleRenderer (Context& context, 3416 const PipelineConstructionType pipelineConstructionType, 3417 const VkFormat colorFormat, 3418 const VkFormat depthStencilFormat, 3419 const tcu::IVec2& renderSize, 3420 const bool useDepth, 3421 const bool useStencil, 3422 const bool useConservative, 3423 const bool useFragmentShadingRate, 3424 const deUint32 numTopologies, 3425 const VkPrimitiveTopology* pTopology, 3426 const std::vector<Vertex4RGBA>* pVertices, 3427 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 3428 const VkPipelineColorBlendAttachmentState& blendState, 3429 const VkPipelineRasterizationConservativeStateCreateInfoEXT& conservativeStateCreateInfo, 3430 const RenderType renderType, 3431 const ImageBackingMode backingMode, 3432 const float depthClearValue) 3433 : m_context (context) 3434 , m_pipelineConstructionType(pipelineConstructionType) 3435 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice())) 3436 , m_colorFormat (colorFormat) 3437 , m_depthStencilFormat (depthStencilFormat) 3438 , m_renderSize (renderSize) 3439 , m_useDepth (useDepth) 3440 , m_useStencil (useStencil) 3441 , m_useConservative (useConservative) 3442 , m_multisampleStateParams (multisampleStateParams) 3443 , m_colorBlendState (blendState) 3444 , m_rasterizationConservativeStateCreateInfo (conservativeStateCreateInfo) 3445 , m_renderType (renderType) 3446 , m_backingMode (backingMode) 3447 , m_depthClearValue (depthClearValue) 3448 , m_useFragmentShadingRate (useFragmentShadingRate) 3449{ 3450 initialize(context, numTopologies, pTopology, pVertices); 3451} 3452 3453void MultisampleRenderer::initialize (Context& context, 3454 const deUint32 numTopologies, 3455 const VkPrimitiveTopology* pTopology, 3456 const std::vector<Vertex4RGBA>* pVertices) 3457{ 3458 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples)) 3459 throw tcu::NotSupportedError("Unsupported number of rasterization samples"); 3460 3461 const InstanceInterface& vki = context.getInstanceInterface(); 3462 const DeviceInterface& vk = context.getDeviceInterface(); 3463 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 3464 const VkDevice vkDevice = context.getDevice(); 3465 const VkPhysicalDeviceFeatures features = context.getDeviceFeatures(); 3466 const deUint32 queueFamilyIndices[] = { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() }; 3467 const bool sparse = m_backingMode == IMAGE_BACKING_MODE_SPARSE; 3468 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 3469 const VkImageCreateFlags imageCreateFlags = sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u; 3470 const VkSharingMode sharingMode = (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; 3471 Allocator& memAlloc = m_context.getDefaultAllocator(); 3472 const bool usesResolveImage = m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT; 3473 3474 if (sparse) 3475 { 3476 bool sparseSamplesSupported = false; 3477 switch(m_multisampleStateParams.rasterizationSamples) 3478 { 3479 case VK_SAMPLE_COUNT_1_BIT: 3480 sparseSamplesSupported = features.sparseResidencyImage2D; 3481 break; 3482 case VK_SAMPLE_COUNT_2_BIT: 3483 sparseSamplesSupported = features.sparseResidency2Samples; 3484 break; 3485 case VK_SAMPLE_COUNT_4_BIT: 3486 sparseSamplesSupported = features.sparseResidency4Samples; 3487 break; 3488 case VK_SAMPLE_COUNT_8_BIT: 3489 sparseSamplesSupported = features.sparseResidency8Samples; 3490 break; 3491 case VK_SAMPLE_COUNT_16_BIT: 3492 sparseSamplesSupported = features.sparseResidency16Samples; 3493 break; 3494 default: 3495 break; 3496 } 3497 3498 if (!sparseSamplesSupported) 3499 throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency"); 3500 } 3501 3502 if (sparse && !context.getDeviceFeatures().sparseBinding) 3503 throw tcu::NotSupportedError("No sparseBinding support"); 3504 3505 // Create color image 3506 { 3507 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 3508 (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u); 3509 3510 const VkImageCreateInfo colorImageParams = 3511 { 3512 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3513 DE_NULL, // const void* pNext; 3514 imageCreateFlags, // VkImageCreateFlags flags; 3515 VK_IMAGE_TYPE_2D, // VkImageType imageType; 3516 m_colorFormat, // VkFormat format; 3517 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 3518 1u, // deUint32 mipLevels; 3519 1u, // deUint32 arrayLayers; 3520 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 3521 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3522 imageUsageFlags, // VkImageUsageFlags usage; 3523 sharingMode, // VkSharingMode sharingMode; 3524 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // deUint32 queueFamilyIndexCount; 3525 queueFamilyIndices, // const deUint32* pQueueFamilyIndices; 3526 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 3527 }; 3528 3529#ifndef CTS_USES_VULKANSC 3530 if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams)) 3531 TCU_THROW(NotSupportedError, "The image format does not support sparse operations."); 3532#endif // CTS_USES_VULKANSC 3533 3534 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 3535 3536 // Allocate and bind color image memory 3537 if (sparse) 3538 { 3539#ifndef CTS_USES_VULKANSC 3540 allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage); 3541#endif // CTS_USES_VULKANSC 3542 } 3543 else 3544 { 3545 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 3546 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 3547 } 3548 } 3549 3550 // Create resolve image 3551 if (usesResolveImage) 3552 { 3553 const VkImageCreateInfo resolveImageParams = 3554 { 3555 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3556 DE_NULL, // const void* pNext; 3557 0u, // VkImageCreateFlags flags; 3558 VK_IMAGE_TYPE_2D, // VkImageType imageType; 3559 m_colorFormat, // VkFormat format; 3560 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 3561 1u, // deUint32 mipLevels; 3562 1u, // deUint32 arrayLayers; 3563 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 3564 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3565 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; 3566 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3567 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3568 1u, // deUint32 queueFamilyIndexCount; 3569 queueFamilyIndices, // const deUint32* pQueueFamilyIndices; 3570 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 3571 }; 3572 3573 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams); 3574 3575 // Allocate and bind resolve image memory 3576 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any); 3577 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset())); 3578 3579 // Create resolve attachment view 3580 { 3581 const VkImageViewCreateInfo resolveAttachmentViewParams = 3582 { 3583 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3584 DE_NULL, // const void* pNext; 3585 0u, // VkImageViewCreateFlags flags; 3586 *m_resolveImage, // VkImage image; 3587 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3588 m_colorFormat, // VkFormat format; 3589 componentMappingRGBA, // VkComponentMapping components; 3590 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 3591 }; 3592 3593 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams); 3594 } 3595 } 3596 3597 // Create per-sample output images 3598 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 3599 { 3600 const VkImageCreateInfo perSampleImageParams = 3601 { 3602 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3603 DE_NULL, // const void* pNext; 3604 0u, // VkImageCreateFlags flags; 3605 VK_IMAGE_TYPE_2D, // VkImageType imageType; 3606 m_colorFormat, // VkFormat format; 3607 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 3608 1u, // deUint32 mipLevels; 3609 1u, // deUint32 arrayLayers; 3610 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 3611 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3612 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; 3613 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3614 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3615 1u, // deUint32 queueFamilyIndexCount; 3616 queueFamilyIndices, // const deUint32* pQueueFamilyIndices; 3617 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 3618 }; 3619 3620 m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples)); 3621 3622 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 3623 { 3624 m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage); 3625 PerSampleImage& image = *m_perSampleImages[i]; 3626 3627 image.m_image = createImage(vk, vkDevice, &perSampleImageParams); 3628 3629 // Allocate and bind image memory 3630 image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any); 3631 VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset())); 3632 3633 // Create per-sample attachment view 3634 { 3635 const VkImageViewCreateInfo perSampleAttachmentViewParams = 3636 { 3637 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3638 DE_NULL, // const void* pNext; 3639 0u, // VkImageViewCreateFlags flags; 3640 *image.m_image, // VkImage image; 3641 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3642 m_colorFormat, // VkFormat format; 3643 componentMappingRGBA, // VkComponentMapping components; 3644 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 3645 }; 3646 3647 image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams); 3648 } 3649 } 3650 } 3651 3652 // Create a depth/stencil image 3653 if (m_useDepth || m_useStencil) 3654 { 3655 const VkImageCreateInfo depthStencilImageParams = 3656 { 3657 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3658 DE_NULL, // const void* pNext; 3659 0u, // VkImageCreateFlags flags; 3660 VK_IMAGE_TYPE_2D, // VkImageType imageType; 3661 m_depthStencilFormat, // VkFormat format; 3662 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 3663 1u, // deUint32 mipLevels; 3664 1u, // deUint32 arrayLayers; 3665 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 3666 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3667 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage; 3668 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3669 1u, // deUint32 queueFamilyIndexCount; 3670 queueFamilyIndices, // const deUint32* pQueueFamilyIndices; 3671 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 3672 }; 3673 3674 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams); 3675 3676 // Allocate and bind depth/stencil image memory 3677 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any); 3678 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset())); 3679 } 3680 3681 // Create color attachment view 3682 { 3683 const VkImageViewCreateInfo colorAttachmentViewParams = 3684 { 3685 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3686 DE_NULL, // const void* pNext; 3687 0u, // VkImageViewCreateFlags flags; 3688 *m_colorImage, // VkImage image; 3689 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3690 m_colorFormat, // VkFormat format; 3691 componentMappingRGBA, // VkComponentMapping components; 3692 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 3693 }; 3694 3695 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 3696 } 3697 3698 VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0; 3699 3700 // Create depth/stencil attachment view 3701 if (m_useDepth || m_useStencil) 3702 { 3703 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat); 3704 3705 const VkImageViewCreateInfo depthStencilAttachmentViewParams = 3706 { 3707 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3708 DE_NULL, // const void* pNext; 3709 0u, // VkImageViewCreateFlags flags; 3710 *m_depthStencilImage, // VkImage image; 3711 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3712 m_depthStencilFormat, // VkFormat format; 3713 componentMappingRGBA, // VkComponentMapping components; 3714 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 3715 }; 3716 3717 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams); 3718 } 3719 3720 // Create render pass 3721 { 3722 std::vector<VkAttachmentDescription> attachmentDescriptions; 3723 { 3724 const VkAttachmentDescription colorAttachmentDescription = 3725 { 3726 0u, // VkAttachmentDescriptionFlags flags; 3727 m_colorFormat, // VkFormat format; 3728 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 3729 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3730 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3731 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3732 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3733 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3734 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 3735 }; 3736 attachmentDescriptions.push_back(colorAttachmentDescription); 3737 } 3738 3739 deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED; 3740 3741 if (usesResolveImage) 3742 { 3743 resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 3744 3745 const VkAttachmentDescription resolveAttachmentDescription = 3746 { 3747 0u, // VkAttachmentDescriptionFlags flags; 3748 m_colorFormat, // VkFormat format; 3749 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 3750 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3751 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3752 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3753 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3754 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3755 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 3756 }; 3757 attachmentDescriptions.push_back(resolveAttachmentDescription); 3758 } 3759 3760 deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED; 3761 3762 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 3763 { 3764 perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 3765 3766 const VkAttachmentDescription perSampleAttachmentDescription = 3767 { 3768 0u, // VkAttachmentDescriptionFlags flags; 3769 m_colorFormat, // VkFormat format; 3770 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 3771 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3772 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3773 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3774 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3775 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3776 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 3777 }; 3778 3779 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 3780 { 3781 attachmentDescriptions.push_back(perSampleAttachmentDescription); 3782 } 3783 } 3784 3785 deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED; 3786 3787 if (m_useDepth || m_useStencil) 3788 { 3789 depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 3790 3791 const VkAttachmentDescription depthStencilAttachmentDescription = 3792 { 3793 0u, // VkAttachmentDescriptionFlags flags; 3794 m_depthStencilFormat, // VkFormat format; 3795 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 3796 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp; 3797 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp; 3798 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp; 3799 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp; 3800 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3801 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 3802 }; 3803 attachmentDescriptions.push_back(depthStencilAttachmentDescription); 3804 } 3805 3806 const VkAttachmentReference colorAttachmentReference = 3807 { 3808 0u, // deUint32 attachment; 3809 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 3810 }; 3811 3812 const VkAttachmentReference inputAttachmentReference = 3813 { 3814 0u, // deUint32 attachment; 3815 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout; 3816 }; 3817 3818 const VkAttachmentReference resolveAttachmentReference = 3819 { 3820 resolveAttachmentIndex, // deUint32 attachment; 3821 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 3822 }; 3823 3824 const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] = 3825 { 3826 { 3827 VK_ATTACHMENT_UNUSED, // deUint32 attachment 3828 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout 3829 }, 3830 { 3831 0u, // deUint32 attachment 3832 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout 3833 } 3834 }; 3835 3836 const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] = 3837 { 3838 { 3839 VK_ATTACHMENT_UNUSED, // deUint32 attachment 3840 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout 3841 }, 3842 { 3843 resolveAttachmentIndex, // deUint32 attachment 3844 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout 3845 } 3846 }; 3847 3848 std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size()); 3849 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 3850 { 3851 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 3852 { 3853 const VkAttachmentReference perSampleAttachmentReference = 3854 { 3855 perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment; 3856 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 3857 }; 3858 perSampleAttachmentReferences[i] = perSampleAttachmentReference; 3859 } 3860 } 3861 3862 const VkAttachmentReference depthStencilAttachmentReference = 3863 { 3864 depthStencilAttachmentIndex, // deUint32 attachment; 3865 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; 3866 }; 3867 3868 std::vector<VkSubpassDescription> subpassDescriptions; 3869 std::vector<VkSubpassDependency> subpassDependencies; 3870 3871 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) 3872 { 3873 const VkSubpassDescription subpassDescription0 = 3874 { 3875 0u, // VkSubpassDescriptionFlags flags 3876 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 3877 0u, // deUint32 inputAttachmentCount 3878 DE_NULL, // const VkAttachmentReference* pInputAttachments 3879 0u, // deUint32 colorAttachmentCount 3880 DE_NULL, // const VkAttachmentReference* pColorAttachments 3881 DE_NULL, // const VkAttachmentReference* pResolveAttachments 3882 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment 3883 0u, // deUint32 preserveAttachmentCount 3884 DE_NULL // const VkAttachmentReference* pPreserveAttachments 3885 }; 3886 3887 const VkSubpassDescription subpassDescription1 = 3888 { 3889 0u, // VkSubpassDescriptionFlags flags 3890 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 3891 0u, // deUint32 inputAttachmentCount 3892 DE_NULL, // const VkAttachmentReference* pInputAttachments 3893 1u, // deUint32 colorAttachmentCount 3894 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments 3895 &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments 3896 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment 3897 0u, // deUint32 preserveAttachmentCount 3898 DE_NULL // const VkAttachmentReference* pPreserveAttachments 3899 }; 3900 3901 const VkSubpassDependency subpassDependency = 3902 { 3903 0u, // deUint32 srcSubpass 3904 1u, // deUint32 dstSubpass 3905 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask 3906 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask 3907 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 3908 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask 3909 0u // VkDependencyFlags dependencyFlags 3910 }; 3911 3912 subpassDescriptions.push_back(subpassDescription0); 3913 subpassDescriptions.push_back(subpassDescription1); 3914 subpassDependencies.push_back(subpassDependency); 3915 } 3916 else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT) 3917 { 3918 const VkSubpassDescription renderSubpassDescription = 3919 { 3920 0u, // VkSubpassDescriptionFlags flags 3921 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 3922 0u, // deUint32 inputAttachmentCount 3923 DE_NULL, // const VkAttachmentReference* pInputAttachments 3924 2u, // deUint32 colorAttachmentCount 3925 colorAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pColorAttachments 3926 resolveAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pResolveAttachments 3927 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment 3928 0u, // deUint32 preserveAttachmentCount 3929 DE_NULL // const VkAttachmentReference* pPreserveAttachments 3930 }; 3931 3932 subpassDescriptions.push_back(renderSubpassDescription); 3933 } 3934 else 3935 { 3936 { 3937 const VkSubpassDescription renderSubpassDescription = 3938 { 3939 0u, // VkSubpassDescriptionFlags flags; 3940 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 3941 0u, // deUint32 inputAttachmentCount; 3942 DE_NULL, // const VkAttachmentReference* pInputAttachments; 3943 1u, // deUint32 colorAttachmentCount; 3944 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 3945 usesResolveImage ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments; 3946 (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment; 3947 0u, // deUint32 preserveAttachmentCount; 3948 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 3949 }; 3950 subpassDescriptions.push_back(renderSubpassDescription); 3951 } 3952 3953 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 3954 { 3955 3956 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 3957 { 3958 const VkSubpassDescription copySampleSubpassDescription = 3959 { 3960 0u, // VkSubpassDescriptionFlags flags; 3961 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 3962 1u, // deUint32 inputAttachmentCount; 3963 &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments; 3964 1u, // deUint32 colorAttachmentCount; 3965 &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments; 3966 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 3967 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 3968 0u, // deUint32 preserveAttachmentCount; 3969 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 3970 }; 3971 subpassDescriptions.push_back(copySampleSubpassDescription); 3972 3973 const VkSubpassDependency copySampleSubpassDependency = 3974 { 3975 0u, // deUint32 srcSubpass 3976 1u + static_cast<deUint32>(i), // deUint32 dstSubpass 3977 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask 3978 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask 3979 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 3980 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask 3981 0u, // VkDependencyFlags dependencyFlags 3982 }; 3983 subpassDependencies.push_back(copySampleSubpassDependency); 3984 } 3985 // the very last sample pass must synchronize with all prior subpasses 3986 for (size_t i = 0; i < (m_perSampleImages.size() - 1); ++i) 3987 { 3988 const VkSubpassDependency storeSubpassDependency = 3989 { 3990 1u + static_cast<deUint32>(i), // deUint32 srcSubpass 3991 static_cast<deUint32>(m_perSampleImages.size()), // deUint32 dstSubpass 3992 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask 3993 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask 3994 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 3995 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask 3996 0u, // VkDependencyFlags dependencyFlags 3997 }; 3998 subpassDependencies.push_back(storeSubpassDependency); 3999 } 4000 } 4001 } 4002 4003 const VkRenderPassCreateInfo renderPassParams = 4004 { 4005 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 4006 DE_NULL, // const void* pNext; 4007 0u, // VkRenderPassCreateFlags flags; 4008 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount; 4009 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; 4010 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount; 4011 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses; 4012 (deUint32)subpassDependencies.size(), // deUint32 dependencyCount; 4013 subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL 4014 }; 4015 4016 m_renderPass = RenderPassWrapper(m_pipelineConstructionType, vk, vkDevice, &renderPassParams); 4017 } 4018 4019 // Create framebuffer 4020 { 4021 std::vector<VkImage> images; 4022 std::vector<VkImageView> attachments; 4023 images.push_back(*m_colorImage); 4024 attachments.push_back(*m_colorAttachmentView); 4025 if (usesResolveImage) 4026 { 4027 images.push_back(*m_resolveImage); 4028 attachments.push_back(*m_resolveAttachmentView); 4029 } 4030 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4031 { 4032 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 4033 { 4034 images.push_back(*m_perSampleImages[i]->m_image); 4035 attachments.push_back(*m_perSampleImages[i]->m_attachmentView); 4036 } 4037 } 4038 4039 if (m_useDepth || m_useStencil) 4040 { 4041 images.push_back(*m_depthStencilImage); 4042 attachments.push_back(*m_depthStencilAttachmentView); 4043 } 4044 4045 const VkFramebufferCreateInfo framebufferParams = 4046 { 4047 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 4048 DE_NULL, // const void* pNext; 4049 0u, // VkFramebufferCreateFlags flags; 4050 *m_renderPass, // VkRenderPass renderPass; 4051 (deUint32)attachments.size(), // deUint32 attachmentCount; 4052 &attachments[0], // const VkImageView* pAttachments; 4053 (deUint32)m_renderSize.x(), // deUint32 width; 4054 (deUint32)m_renderSize.y(), // deUint32 height; 4055 1u // deUint32 layers; 4056 }; 4057 4058 m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images); 4059 } 4060 4061 // Create pipeline layout 4062 { 4063 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 4064 { 4065 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 4066 DE_NULL, // const void* pNext; 4067 0u, // VkPipelineLayoutCreateFlags flags; 4068 0u, // deUint32 setLayoutCount; 4069 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 4070 0u, // deUint32 pushConstantRangeCount; 4071 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 4072 }; 4073 4074 m_pipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams); 4075 4076 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4077 { 4078 4079 // Create descriptor set layout 4080 const VkDescriptorSetLayoutBinding layoutBinding = 4081 { 4082 0u, // deUint32 binding; 4083 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType; 4084 1u, // deUint32 descriptorCount; 4085 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 4086 DE_NULL, // const VkSampler* pImmutableSamplers; 4087 }; 4088 4089 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = 4090 { 4091 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType 4092 DE_NULL, // const void* pNext 4093 0u, // VkDescriptorSetLayoutCreateFlags flags 4094 1u, // deUint32 bindingCount 4095 &layoutBinding // const VkDescriptorSetLayoutBinding* pBindings 4096 }; 4097 m_copySampleDesciptorLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams); 4098 4099 // Create pipeline layout 4100 4101 const VkPushConstantRange pushConstantRange = 4102 { 4103 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 4104 0u, // deUint32 offset; 4105 sizeof(deInt32) // deUint32 size; 4106 }; 4107 const VkPipelineLayoutCreateInfo copySamplePipelineLayoutParams = 4108 { 4109 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 4110 DE_NULL, // const void* pNext; 4111 0u, // VkPipelineLayoutCreateFlags flags; 4112 1u, // deUint32 setLayoutCount; 4113 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 4114 1u, // deUint32 pushConstantRangeCount; 4115 &pushConstantRange // const VkPushConstantRange* pPushConstantRanges; 4116 }; 4117 m_copySamplePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, ©SamplePipelineLayoutParams); 4118 } 4119 } 4120 4121 m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 4122 m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 4123 4124 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4125 { 4126 m_copySampleVertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0); 4127 m_copySampleFragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0); 4128 } 4129 4130 // Create pipeline 4131 { 4132 const VkVertexInputBindingDescription vertexInputBindingDescription = 4133 { 4134 0u, // deUint32 binding; 4135 sizeof(Vertex4RGBA), // deUint32 stride; 4136 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; 4137 }; 4138 4139 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 4140 { 4141 { 4142 0u, // deUint32 location; 4143 0u, // deUint32 binding; 4144 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 4145 0u // deUint32 offset; 4146 }, 4147 { 4148 1u, // deUint32 location; 4149 0u, // deUint32 binding; 4150 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 4151 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset; 4152 } 4153 }; 4154 4155 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 4156 { 4157 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 4158 DE_NULL, // const void* pNext; 4159 0u, // VkPipelineVertexInputStateCreateFlags flags; 4160 1u, // deUint32 vertexBindingDescriptionCount; 4161 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 4162 2u, // deUint32 vertexAttributeDescriptionCount; 4163 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 4164 }; 4165 4166 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) }; 4167 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) }; 4168 4169 const deUint32 attachmentCount = m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u; 4170 4171 std::vector<VkPipelineColorBlendAttachmentState> attachments; 4172 4173 for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++) 4174 attachments.push_back(m_colorBlendState); 4175 4176 VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 4177 { 4178 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 4179 DE_NULL, // const void* pNext; 4180 0u, // VkPipelineColorBlendStateCreateFlags flags; 4181 false, // VkBool32 logicOpEnable; 4182 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 4183 attachmentCount, // deUint32 attachmentCount; 4184 attachments.data(), // const VkPipelineColorBlendAttachmentState* pAttachments; 4185 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 4186 }; 4187 4188 const VkStencilOpState stencilOpState = 4189 { 4190 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 4191 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp; 4192 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 4193 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp; 4194 1u, // deUint32 compareMask; 4195 1u, // deUint32 writeMask; 4196 1u, // deUint32 reference; 4197 }; 4198 4199 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 4200 { 4201 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 4202 DE_NULL, // const void* pNext; 4203 0u, // VkPipelineDepthStencilStateCreateFlags flags; 4204 m_useDepth, // VkBool32 depthTestEnable; 4205 m_useDepth, // VkBool32 depthWriteEnable; 4206 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 4207 false, // VkBool32 depthBoundsTestEnable; 4208 m_useStencil, // VkBool32 stencilTestEnable; 4209 stencilOpState, // VkStencilOpState front; 4210 stencilOpState, // VkStencilOpState back; 4211 0.0f, // float minDepthBounds; 4212 1.0f, // float maxDepthBounds; 4213 }; 4214 4215 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo 4216 { 4217 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType 4218 m_useConservative ? &m_rasterizationConservativeStateCreateInfo : DE_NULL, // const void* pNext 4219 0u, // VkPipelineRasterizationStateCreateFlags flags 4220 VK_FALSE, // VkBool32 depthClampEnable 4221 VK_FALSE, // VkBool32 rasterizerDiscardEnable 4222 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode 4223 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode 4224 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace 4225 VK_FALSE, // VkBool32 depthBiasEnable 4226 0.0f, // float depthBiasConstantFactor 4227 0.0f, // float depthBiasClamp 4228 0.0f, // float depthBiasSlopeFactor 4229 1.0f // float lineWidth 4230 }; 4231 4232 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo 4233 { 4234 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType; 4235 DE_NULL, // const void* pNext; 4236 { 2, 2 }, // VkExtent2D fragmentSize; 4237 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2]; 4238 }; 4239 4240 const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u; 4241 4242 m_graphicsPipelines.reserve(numSubpasses * numTopologies); 4243 for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++) 4244 { 4245 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) 4246 { 4247 if (subpassIdx == 0) 4248 { 4249 colorBlendStateParams.attachmentCount = 0; 4250 } 4251 else 4252 { 4253 colorBlendStateParams.attachmentCount = 1; 4254 } 4255 } 4256 for (deUint32 i = 0u; i < numTopologies; ++i) 4257 { 4258 m_graphicsPipelines.emplace_back(vki, vk, physicalDevice, vkDevice, context.getDeviceExtensions(), m_pipelineConstructionType); 4259 m_graphicsPipelines.back().setDefaultTopology(pTopology[i]) 4260 .setupVertexInputState(&vertexInputStateParams) 4261 .setupPreRasterizationShaderState(viewports, 4262 scissors, 4263 m_pipelineLayout, 4264 *m_renderPass, 4265 subpassIdx, 4266 m_vertexShaderModule, 4267 &rasterizationStateCreateInfo, 4268 ShaderWrapper(), ShaderWrapper(), ShaderWrapper(), DE_NULL, 4269 (m_useFragmentShadingRate ? &shadingRateStateCreateInfo : nullptr)) 4270 .setupFragmentShaderState(m_pipelineLayout, 4271 *m_renderPass, 4272 subpassIdx, 4273 m_fragmentShaderModule, 4274 &depthStencilStateParams, 4275 &m_multisampleStateParams) 4276 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &m_multisampleStateParams) 4277 .setMonolithicPipelineLayout(m_pipelineLayout) 4278 .buildPipeline(); 4279 } 4280 } 4281 } 4282 4283 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4284 { 4285 // Create pipelines for copying samples to single sampled images 4286 { 4287 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams 4288 { 4289 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 4290 DE_NULL, // const void* pNext; 4291 0u, // VkPipelineVertexInputStateCreateFlags flags; 4292 0u, // deUint32 vertexBindingDescriptionCount; 4293 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 4294 0u, // deUint32 vertexAttributeDescriptionCount; 4295 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 4296 }; 4297 4298 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) }; 4299 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) }; 4300 4301 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams 4302 { 4303 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 4304 DE_NULL, // const void* pNext; 4305 0u, // VkPipelineColorBlendStateCreateFlags flags; 4306 false, // VkBool32 logicOpEnable; 4307 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 4308 1u, // deUint32 attachmentCount; 4309 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments; 4310 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 4311 }; 4312 4313 m_copySamplePipelines.reserve(m_perSampleImages.size()); 4314 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 4315 { 4316 // Pipeline is to be used in subpasses subsequent to sample-shading subpass 4317 4318 const deUint32 subpassIdx = 1u + (deUint32)i; 4319 m_copySamplePipelines.emplace_back(vki, vk, physicalDevice, vkDevice, m_context.getDeviceExtensions(), m_pipelineConstructionType); 4320 m_copySamplePipelines.back().setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 4321 .setDefaultRasterizationState() 4322 .setDefaultMultisampleState() 4323 .setDefaultDepthStencilState() 4324 .setupVertexInputState(&vertexInputStateParams) 4325 .setupPreRasterizationShaderState(viewports, 4326 scissors, 4327 m_copySamplePipelineLayout, 4328 *m_renderPass, 4329 subpassIdx, 4330 m_copySampleVertexShaderModule) 4331 .setupFragmentShaderState(m_copySamplePipelineLayout, 4332 *m_renderPass, 4333 subpassIdx, 4334 m_copySampleFragmentShaderModule) 4335 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams) 4336 .setMonolithicPipelineLayout(m_copySamplePipelineLayout) 4337 .buildPipeline(); 4338 } 4339 } 4340 4341 const VkDescriptorPoolSize descriptorPoolSize 4342 { 4343 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type; 4344 1u // deUint32 descriptorCount; 4345 }; 4346 4347 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo 4348 { 4349 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType 4350 DE_NULL, // const void* pNext 4351 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags 4352 1u, // deUint32 maxSets 4353 1u, // deUint32 poolSizeCount 4354 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes 4355 }; 4356 4357 m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo); 4358 4359 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo 4360 { 4361 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType 4362 DE_NULL, // const void* pNext 4363 *m_copySampleDesciptorPool, // VkDescriptorPool descriptorPool 4364 1u, // deUint32 descriptorSetCount 4365 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts 4366 }; 4367 4368 m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo); 4369 4370 const VkDescriptorImageInfo imageInfo 4371 { 4372 DE_NULL, 4373 *m_colorAttachmentView, 4374 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 4375 }; 4376 const VkWriteDescriptorSet descriptorWrite 4377 { 4378 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 4379 DE_NULL, // const void* pNext; 4380 *m_copySampleDesciptorSet, // VkDescriptorSet dstSet; 4381 0u, // deUint32 dstBinding; 4382 0u, // deUint32 dstArrayElement; 4383 1u, // deUint32 descriptorCount; 4384 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType; 4385 &imageInfo, // const VkDescriptorImageInfo* pImageInfo; 4386 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo; 4387 DE_NULL, // const VkBufferView* pTexelBufferView; 4388 }; 4389 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL); 4390 } 4391 4392 // Create vertex buffer 4393 { 4394 const VkBufferCreateInfo vertexBufferParams 4395 { 4396 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 4397 DE_NULL, // const void* pNext; 4398 0u, // VkBufferCreateFlags flags; 4399 1024u, // VkDeviceSize size; 4400 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 4401 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 4402 1u, // deUint32 queueFamilyIndexCount; 4403 &queueFamilyIndices[0] // const deUint32* pQueueFamilyIndices; 4404 }; 4405 4406 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 4407 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 4408 4409 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 4410 4411 // Load vertices into vertex buffer 4412 { 4413 Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr()); 4414 4415 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) 4416 { 4417 DE_ASSERT(numTopologies == 1); 4418 4419 std::vector<Vertex4RGBA> vertices = pVertices[0]; 4420 4421 // Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage. 4422 for (size_t i = 0; i < vertices.size(); i++) 4423 vertices[i].color.w() = 0.0f; 4424 4425 deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA)); 4426 4427 pDst += vertices.size(); 4428 4429 // The second draw uses original vertices which are pure red. 4430 deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA)); 4431 } 4432 else 4433 { 4434 for (deUint32 i = 0u; i < numTopologies; ++i) 4435 { 4436 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA)); 4437 pDst += pVertices[i].size(); 4438 } 4439 } 4440 } 4441 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc); 4442 } 4443 4444 // Create command pool 4445 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]); 4446 4447 // Create command buffer 4448 { 4449 VkClearValue colorClearValue; 4450 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) 4451 { 4452 colorClearValue.color.float32[0] = 0.25; 4453 colorClearValue.color.float32[1] = 0.25; 4454 colorClearValue.color.float32[2] = 0.25; 4455 colorClearValue.color.float32[3] = 1.0f; 4456 } 4457 else 4458 { 4459 colorClearValue.color.float32[0] = 0.0f; 4460 colorClearValue.color.float32[1] = 0.0f; 4461 colorClearValue.color.float32[2] = 0.0f; 4462 colorClearValue.color.float32[3] = 0.0f; 4463 } 4464 4465 VkClearValue depthStencilClearValue; 4466 depthStencilClearValue.depthStencil.depth = m_depthClearValue; 4467 depthStencilClearValue.depthStencil.stencil = 0u; 4468 4469 std::vector<VkClearValue> clearValues; 4470 clearValues.push_back(colorClearValue); 4471 if (usesResolveImage) 4472 { 4473 clearValues.push_back(colorClearValue); 4474 } 4475 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4476 { 4477 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 4478 { 4479 clearValues.push_back(colorClearValue); 4480 } 4481 } 4482 if (m_useDepth || m_useStencil) 4483 { 4484 clearValues.push_back(depthStencilClearValue); 4485 } 4486 4487 vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 4488 std::vector<VkImageMemoryBarrier> imageLayoutBarriers; 4489 4490 { 4491 const VkImageMemoryBarrier colorImageBarrier = 4492 // color attachment image 4493 { 4494 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4495 DE_NULL, // const void* pNext; 4496 0u, // VkAccessFlags srcAccessMask; 4497 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 4498 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4499 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4500 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4501 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4502 *m_colorImage, // VkImage image; 4503 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 4504 }; 4505 imageLayoutBarriers.push_back(colorImageBarrier); 4506 } 4507 if (usesResolveImage) 4508 { 4509 const VkImageMemoryBarrier resolveImageBarrier = 4510 // resolve attachment image 4511 { 4512 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4513 DE_NULL, // const void* pNext; 4514 0u, // VkAccessFlags srcAccessMask; 4515 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 4516 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4517 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4518 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4519 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4520 *m_resolveImage, // VkImage image; 4521 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 4522 }; 4523 imageLayoutBarriers.push_back(resolveImageBarrier); 4524 } 4525 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4526 { 4527 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 4528 { 4529 const VkImageMemoryBarrier perSampleImageBarrier = 4530 // resolve attachment image 4531 { 4532 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4533 DE_NULL, // const void* pNext; 4534 0u, // VkAccessFlags srcAccessMask; 4535 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 4536 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4537 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4538 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4539 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4540 *m_perSampleImages[i]->m_image, // VkImage image; 4541 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 4542 }; 4543 imageLayoutBarriers.push_back(perSampleImageBarrier); 4544 } 4545 } 4546 if (m_useDepth || m_useStencil) 4547 { 4548 const VkImageMemoryBarrier depthStencilImageBarrier = 4549 // depth/stencil attachment image 4550 { 4551 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4552 DE_NULL, // const void* pNext; 4553 0u, // VkAccessFlags srcAccessMask; 4554 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 4555 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4556 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4557 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4558 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4559 *m_depthStencilImage, // VkImage image; 4560 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 4561 }; 4562 imageLayoutBarriers.push_back(depthStencilImageBarrier); 4563 dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; 4564 } 4565 4566 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 4567 4568 beginCommandBuffer(vk, *m_cmdBuffer, 0u); 4569 4570 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0, 4571 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]); 4572 4573 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]); 4574 4575 VkDeviceSize vertexBufferOffset = 0u; 4576 4577 for (deUint32 i = 0u; i < numTopologies; ++i) 4578 { 4579 m_graphicsPipelines[i].bind(*m_cmdBuffer); 4580 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 4581 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0); 4582 4583 vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA)); 4584 } 4585 4586 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY) 4587 { 4588 // The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value. 4589 m_renderPass.nextSubpass(vk, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 4590 m_graphicsPipelines[1].bind(*m_cmdBuffer); 4591 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 4592 // The depth test should pass as the first draw didn't touch the depth buffer. 4593 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0); 4594 } 4595 else if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 4596 { 4597 // Copy each sample id to single sampled image 4598 for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId) 4599 { 4600 m_renderPass.nextSubpass(vk, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 4601 m_copySamplePipelines[sampleId].bind(*m_cmdBuffer); 4602 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL); 4603 vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId); 4604 vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); 4605 } 4606 } 4607 4608 m_renderPass.end(vk, *m_cmdBuffer); 4609 4610 endCommandBuffer(vk, *m_cmdBuffer); 4611 } 4612} 4613 4614MultisampleRenderer::~MultisampleRenderer (void) 4615{ 4616} 4617 4618de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void) 4619{ 4620 const DeviceInterface& vk = m_context.getDeviceInterface(); 4621 const VkDevice vkDevice = m_context.getDevice(); 4622 const VkQueue queue = m_context.getUniversalQueue(); 4623 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 4624 4625 if (m_backingMode == IMAGE_BACKING_MODE_SPARSE) 4626 { 4627 const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT }; 4628 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get(), false, 1u, 1u, &m_bindSemaphore.get(), stageBits); 4629 } 4630 else 4631 { 4632 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 4633 } 4634 4635 if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT) 4636 { 4637 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>()); 4638 } 4639 else if(m_renderType == RENDER_TYPE_SINGLE_SAMPLE) 4640 { 4641 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_colorImage, m_colorFormat, m_renderSize.cast<deUint32>()); 4642 } 4643 else 4644 { 4645 return de::MovePtr<tcu::TextureLevel>(); 4646 } 4647} 4648 4649de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId) 4650{ 4651 return readColorAttachment(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), m_context.getDefaultAllocator(), *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>()); 4652} 4653 4654de::MovePtr<tcu::TextureLevel> MultisampleRenderer::renderReusingDepth () 4655{ 4656 const auto ctx = m_context.getContextCommonData(); 4657 const auto renderSize = m_renderSize.cast<uint32_t>(); 4658 const auto scissor = makeRect2D(renderSize); 4659 const auto fbExtent = makeExtent3D(scissor.extent.width, scissor.extent.height, 1u); 4660 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 4661 const auto sampleCount = m_multisampleStateParams.rasterizationSamples; 4662 const auto singleSample = VK_SAMPLE_COUNT_1_BIT; 4663 const auto bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 4664 4665 ImageWithBuffer secondColorBuffer (ctx.vkd, ctx.device, ctx.allocator, fbExtent, m_colorFormat, colorUsage, VK_IMAGE_TYPE_2D, makeDefaultImageSubresourceRange(), 1u, sampleCount); 4666 ImageWithBuffer secondResolveBuffer (ctx.vkd, ctx.device, ctx.allocator, fbExtent, m_colorFormat, colorUsage, VK_IMAGE_TYPE_2D, makeDefaultImageSubresourceRange(), 1u, singleSample); 4667 4668 const auto pcSize = static_cast<uint32_t>(sizeof(float)); 4669 const auto pcStages = VK_SHADER_STAGE_VERTEX_BIT; 4670 const auto pcRange = makePushConstantRange(pcStages, 0u, pcSize); 4671 const auto pipelineLayout = makePipelineLayout(ctx.vkd, ctx.device, VK_NULL_HANDLE, &pcRange); 4672 4673 const std::vector<VkAttachmentDescription> attachmentDescriptions 4674 { 4675 { // Color attachment. 4676 0u, // VkAttachmentDescriptionFlags flags; 4677 m_colorFormat, // VkFormat format; 4678 sampleCount, // VkSampleCountFlagBits samples; 4679 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 4680 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 4681 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 4682 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 4683 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 4684 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 4685 }, 4686 { // Depth/stencil attachment. 4687 0u, // VkAttachmentDescriptionFlags flags; 4688 m_depthStencilFormat, // VkFormat format; 4689 sampleCount, // VkSampleCountFlagBits samples; 4690 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; 4691 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 4692 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 4693 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 4694 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 4695 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 4696 }, 4697 { // Resolve attachment. 4698 0u, // VkAttachmentDescriptionFlags flags; 4699 m_colorFormat, // VkFormat format; 4700 singleSample, // VkSampleCountFlagBits samples; 4701 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 4702 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 4703 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 4704 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 4705 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 4706 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 4707 }, 4708 }; 4709 4710 const auto colorAttachmentReference = makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 4711 const auto dsAttachmentReference = makeAttachmentReference(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 4712 const auto resolveAttachmentReference = makeAttachmentReference(2u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 4713 4714 const VkSubpassDescription subpassDescription = 4715 { 4716 0u, // VkSubpassDescriptionFlags flags; 4717 bindPoint, // VkPipelineBindPoint pipelineBindPoint; 4718 0u, // uint32_t inputAttachmentCount; 4719 nullptr, // const VkAttachmentReference* pInputAttachments; 4720 1u, // uint32_t colorAttachmentCount; 4721 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 4722 &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments; 4723 &dsAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 4724 0u, // uint32_t preserveAttachmentCount; 4725 nullptr, // const uint32_t* pPreserveAttachments; 4726 }; 4727 4728 const VkRenderPassCreateInfo rpCreateInfo = 4729 { 4730 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 4731 nullptr, // const void* pNext; 4732 0u, // VkRenderPassCreateFlags flags; 4733 de::sizeU32(attachmentDescriptions), // uint32_t attachmentCount; 4734 de::dataOrNull(attachmentDescriptions), // const VkAttachmentDescription* pAttachments; 4735 1u, // uint32_t subpassCount; 4736 &subpassDescription, // const VkSubpassDescription* pSubpasses; 4737 0u, // uint32_t dependencyCount; 4738 nullptr, // const VkSubpassDependency* pDependencies; 4739 }; 4740 const auto renderPass = createRenderPass(ctx.vkd, ctx.device, &rpCreateInfo); 4741 4742 const std::vector<VkImageView> fbImageViews 4743 { 4744 secondColorBuffer.getImageView(), 4745 *m_depthStencilAttachmentView, 4746 secondResolveBuffer.getImageView(), 4747 }; 4748 const auto framebuffer = makeFramebuffer(ctx.vkd, ctx.device, renderPass.get(), de::sizeU32(fbImageViews), de::dataOrNull(fbImageViews), fbExtent.width, fbExtent.height); 4749 4750 const std::vector<VkViewport> viewports (1u, makeViewport(fbExtent)); 4751 const std::vector<VkRect2D> scissors (1u, scissor); 4752 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = initVulkanStructure(); 4753 const auto stencilOpState = makeStencilOpState(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0u, 0u, 0u); 4754 4755 // This is the key to test the depth buffer contains the clear value and has not been written to: 4756 // The comparison op is EQUAL, so we will only draw if the depth buffer contains the expected value. 4757 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = 4758 { 4759 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 4760 nullptr, // const void* pNext; 4761 0u, // VkPipelineDepthStencilStateCreateFlags flags; 4762 VK_TRUE, // VkBool32 depthTestEnable; 4763 VK_FALSE, // VkBool32 depthWriteEnable; 4764 VK_COMPARE_OP_EQUAL, // VkCompareOp depthCompareOp; 4765 VK_FALSE, // VkBool32 depthBoundsTestEnable; 4766 VK_FALSE, // VkBool32 stencilTestEnable; 4767 stencilOpState, // VkStencilOpState front; 4768 stencilOpState, // VkStencilOpState back; 4769 0.0f, // float minDepthBounds; 4770 1.0f, // float maxDepthBounds; 4771 }; 4772 4773 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = 4774 { 4775 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 4776 nullptr, // const void* pNext; 4777 0u, // VkPipelineMultisampleStateCreateFlags flags; 4778 sampleCount, // VkSampleCountFlagBits rasterizationSamples; 4779 VK_FALSE, // VkBool32 sampleShadingEnable; 4780 1.0f, // float minSampleShading; 4781 nullptr, // const VkSampleMask* pSampleMask; 4782 VK_FALSE, // VkBool32 alphaToCoverageEnable; 4783 VK_FALSE, // VkBool32 alphaToOneEnable; 4784 }; 4785 4786 const auto& binaries = m_context.getBinaryCollection(); 4787 const auto vertModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("checkDepth-vert")); 4788 const auto fragModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("color_frag")); 4789 const auto pipeline = makeGraphicsPipeline( 4790 ctx.vkd, ctx.device, pipelineLayout.get(), 4791 vertModule.get(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragModule.get(), renderPass.get(), 4792 viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u, 4793 &vertexInputStateCreateInfo, nullptr, &multisampleStateCreateInfo, &depthStencilStateCreateInfo); 4794 4795 const CommandPoolWithBuffer cmd (ctx.vkd, ctx.device, ctx.qfIndex); 4796 const auto cmdBuffer = cmd.cmdBuffer.get(); 4797 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f); 4798 4799 beginCommandBuffer(ctx.vkd, cmdBuffer); 4800 { 4801 // Make sure the previous depth buffer writes have completed already. 4802 const auto depthBarrier = makeMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)); 4803 const auto depthStages = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); 4804 cmdPipelineMemoryBarrier(ctx.vkd, cmdBuffer, depthStages, depthStages, &depthBarrier); 4805 } 4806 beginRenderPass(ctx.vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissor, clearColor); 4807 ctx.vkd.cmdBindPipeline(cmdBuffer, bindPoint, pipeline.get()); 4808 ctx.vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pcStages, 0u, pcSize, &m_depthClearValue); 4809 ctx.vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u); 4810 endRenderPass(ctx.vkd, cmdBuffer); 4811 endCommandBuffer(ctx.vkd, cmdBuffer); 4812 submitCommandsAndWait(ctx.vkd, ctx.device, ctx.queue, cmdBuffer); 4813 4814 return readColorAttachment(ctx.vkd, ctx.device, ctx.queue, ctx.qfIndex, ctx.allocator, secondResolveBuffer.getImage(), m_colorFormat, renderSize); 4815} 4816 4817// Multisample tests with subpasses using no attachments. 4818class VariableRateTestCase : public vkt::TestCase 4819{ 4820public: 4821 using SampleCounts = std::vector<vk::VkSampleCountFlagBits>; 4822 4823 struct PushConstants 4824 { 4825 int width; 4826 int height; 4827 int samples; 4828 }; 4829 4830 struct TestParams 4831 { 4832 PipelineConstructionType pipelineConstructionType; // The way pipeline is constructed. 4833 bool nonEmptyFramebuffer; // Empty framebuffer or not. 4834 vk::VkSampleCountFlagBits fbCount; // If not empty, framebuffer sample count. 4835 bool unusedAttachment; // If not empty, create unused attachment or not. 4836 SampleCounts subpassCounts; // Counts for the different subpasses. 4837 bool useFragmentShadingRate; // Use pipeline fragment shading rate. 4838 }; 4839 4840 static const deInt32 kWidth = 256u; 4841 static const deInt32 kHeight = 256u; 4842 4843 VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params); 4844 virtual ~VariableRateTestCase (void) {} 4845 4846 virtual void initPrograms (vk::SourceCollections& programCollection) const; 4847 virtual TestInstance* createInstance (Context& context) const; 4848 virtual void checkSupport (Context& context) const; 4849 4850 static constexpr vk::VkFormat kColorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM; 4851 4852private: 4853 TestParams m_params; 4854}; 4855 4856class VariableRateTestInstance : public vkt::TestInstance 4857{ 4858public: 4859 using TestParams = VariableRateTestCase::TestParams; 4860 4861 VariableRateTestInstance (Context& context, const TestParams& counts); 4862 virtual ~VariableRateTestInstance (void) {} 4863 4864 virtual tcu::TestStatus iterate (void); 4865 4866private: 4867 TestParams m_params; 4868}; 4869 4870VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params) 4871 : vkt::TestCase (testCtx, name) 4872 , m_params (params) 4873{ 4874} 4875 4876void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const 4877{ 4878 std::stringstream vertSrc; 4879 4880 vertSrc << "#version 450\n" 4881 << "\n" 4882 << "layout(location=0) in vec2 inPos;\n" 4883 << "\n" 4884 << "void main() {\n" 4885 << " gl_Position = vec4(inPos, 0.0, 1.0);\n" 4886 << "}\n" 4887 ; 4888 4889 std::stringstream fragSrc; 4890 4891 fragSrc << "#version 450\n" 4892 << "\n" 4893 << "layout(set=0, binding=0, std430) buffer OutBuffer {\n" 4894 << " int coverage[];\n" 4895 << "} out_buffer;\n" 4896 << "\n" 4897 << "layout(push_constant) uniform PushConstants {\n" 4898 << " int width;\n" 4899 << " int height;\n" 4900 << " int samples;\n" 4901 << "} push_constants;\n" 4902 << "\n" 4903 << "void main() {\n" 4904 << " ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n" 4905 << " int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n" 4906 << " out_buffer.coverage[pos] = 1;\n" 4907 << "}\n" 4908 ; 4909 4910 programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str()); 4911 programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str()); 4912} 4913 4914TestInstance* VariableRateTestCase::createInstance (Context& context) const 4915{ 4916 return new VariableRateTestInstance(context, m_params); 4917} 4918 4919void VariableRateTestCase::checkSupport (Context& context) const 4920{ 4921 const auto& vki = context.getInstanceInterface(); 4922 const auto physicalDevice = context.getPhysicalDevice(); 4923 4924 // When using multiple subpasses, require variableMultisampleRate. 4925 if (m_params.subpassCounts.size() > 1) 4926 { 4927 if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate) 4928 TCU_THROW(NotSupportedError, "Variable multisample rate not supported"); 4929 } 4930 4931 // Check if sampleRateShading is supported. 4932 if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading) 4933 TCU_THROW(NotSupportedError, "Sample rate shading is not supported"); 4934 4935 // Make sure all subpass sample counts are supported. 4936 const auto properties = vk::getPhysicalDeviceProperties(vki, physicalDevice); 4937 const auto& supportedCounts = properties.limits.framebufferNoAttachmentsSampleCounts; 4938 4939 for (const auto count : m_params.subpassCounts) 4940 { 4941 if ((supportedCounts & count) == 0u) 4942 TCU_THROW(NotSupportedError, "Sample count combination not supported"); 4943 } 4944 4945 if (m_params.nonEmptyFramebuffer) 4946 { 4947 // Check the framebuffer sample count is supported. 4948 const auto formatProperties = vk::getPhysicalDeviceImageFormatProperties(vki, physicalDevice, kColorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0u); 4949 if ((formatProperties.sampleCounts & m_params.fbCount) == 0u) 4950 TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment"); 4951 } 4952 4953 if (m_params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_params.fbCount)) 4954 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported"); 4955 4956 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType); 4957} 4958 4959void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size) 4960{ 4961 auto& alloc = buffer.getAllocation(); 4962 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size)); 4963 vk::flushAlloc(vkd, device, alloc); 4964} 4965 4966VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params) 4967 : vkt::TestInstance (context) 4968 , m_params (params) 4969{ 4970} 4971 4972tcu::TestStatus VariableRateTestInstance::iterate (void) 4973{ 4974 using PushConstants = VariableRateTestCase::PushConstants; 4975 4976 const auto& vki = m_context.getInstanceInterface(); 4977 const auto& vkd = m_context.getDeviceInterface(); 4978 const auto physDevice = m_context.getPhysicalDevice(); 4979 const auto device = m_context.getDevice(); 4980 auto& allocator = m_context.getDefaultAllocator(); 4981 const auto& queue = m_context.getUniversalQueue(); 4982 const auto queueIndex = m_context.getUniversalQueueFamilyIndex(); 4983 4984 const vk::VkDeviceSize kWidth = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth); 4985 const vk::VkDeviceSize kHeight = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight); 4986 constexpr auto kColorFormat = VariableRateTestCase::kColorFormat; 4987 4988 const auto kWidth32 = static_cast<deUint32>(kWidth); 4989 const auto kHeight32 = static_cast<deUint32>(kHeight); 4990 4991 std::vector<std::unique_ptr<vk::BufferWithMemory>> referenceBuffers; 4992 std::vector<std::unique_ptr<vk::BufferWithMemory>> outputBuffers; 4993 std::vector<size_t> bufferNumElements; 4994 std::vector<vk::VkDeviceSize> bufferSizes; 4995 4996 // Create reference and output buffers. 4997 for (const auto count : m_params.subpassCounts) 4998 { 4999 bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count)); 5000 bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32)); 5001 const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 5002 5003 referenceBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible}); 5004 outputBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible}); 5005 } 5006 5007 // Descriptor set layout. 5008 vk::DescriptorSetLayoutBuilder builder; 5009 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT); 5010 const auto descriptorSetLayout = builder.build(vkd, device); 5011 5012 // Pipeline layout. 5013 const vk::VkPushConstantRange pushConstantRange = 5014 { 5015 vk::VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 5016 0u, // deUint32 offset; 5017 static_cast<deUint32>(sizeof(PushConstants)), // deUint32 size; 5018 }; 5019 5020 const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = 5021 { 5022 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 5023 nullptr, // const void* pNext; 5024 0u, // VkPipelineLayoutCreateFlags flags; 5025 1u, // deUint32 setLayoutCount; 5026 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 5027 1u, // deUint32 pushConstantRangeCount; 5028 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges; 5029 }; 5030 const vk::PipelineLayoutWrapper pipelineLayout (m_params.pipelineConstructionType, vkd, device, &pipelineLayoutCreateInfo); 5031 5032 // Subpass with no attachments. 5033 const vk::VkSubpassDescription emptySubpassDescription = 5034 { 5035 0u, // VkSubpassDescriptionFlags flags; 5036 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 5037 0u, // deUint32 inputAttachmentCount; 5038 nullptr, // const VkAttachmentReference* pInputAttachments; 5039 0u, // deUint32 colorAttachmentCount; 5040 nullptr, // const VkAttachmentReference* pColorAttachments; 5041 nullptr, // const VkAttachmentReference* pResolveAttachments; 5042 nullptr, // const VkAttachmentReference* pDepthStencilAttachment; 5043 0u, // deUint32 preserveAttachmentCount; 5044 nullptr, // const deUint32* pPreserveAttachments; 5045 }; 5046 5047 // Unused attachment reference. 5048 const vk::VkAttachmentReference unusedAttachmentReference = 5049 { 5050 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 5051 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; 5052 }; 5053 5054 // Subpass with unused attachment. 5055 const vk::VkSubpassDescription unusedAttachmentSubpassDescription = 5056 { 5057 0u, // VkSubpassDescriptionFlags flags; 5058 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 5059 0u, // deUint32 inputAttachmentCount; 5060 nullptr, // const VkAttachmentReference* pInputAttachments; 5061 1u, // deUint32 colorAttachmentCount; 5062 &unusedAttachmentReference, // const VkAttachmentReference* pColorAttachments; 5063 nullptr, // const VkAttachmentReference* pResolveAttachments; 5064 nullptr, // const VkAttachmentReference* pDepthStencilAttachment; 5065 0u, // deUint32 preserveAttachmentCount; 5066 nullptr, // const deUint32* pPreserveAttachments; 5067 }; 5068 5069 // Renderpass with multiple subpasses. 5070 vk::VkRenderPassCreateInfo renderPassCreateInfo = 5071 { 5072 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 5073 nullptr, // const void* pNext; 5074 0u, // VkRenderPassCreateFlags flags; 5075 0u, // deUint32 attachmentCount; 5076 nullptr, // const VkAttachmentDescription* pAttachments; 5077 0u, // deUint32 subpassCount; 5078 nullptr, // const VkSubpassDescription* pSubpasses; 5079 0u, // deUint32 dependencyCount; 5080 nullptr, // const VkSubpassDependency* pDependencies; 5081 }; 5082 5083 std::vector<vk::VkSubpassDescription> subpassesVector; 5084 5085 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i) 5086 subpassesVector.push_back(emptySubpassDescription); 5087 renderPassCreateInfo.subpassCount = static_cast<deUint32>(subpassesVector.size()); 5088 renderPassCreateInfo.pSubpasses = subpassesVector.data(); 5089 RenderPassWrapper renderPassMultiplePasses (m_params.pipelineConstructionType, vkd, device, &renderPassCreateInfo); 5090 5091 // Render pass with single subpass. 5092 const vk::VkAttachmentDescription colorAttachmentDescription = 5093 { 5094 0u, // VkAttachmentDescriptionFlags flags; 5095 kColorFormat, // VkFormat format; 5096 m_params.fbCount, // VkSampleCountFlagBits samples; 5097 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 5098 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 5099 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 5100 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 5101 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5102 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 5103 }; 5104 5105 if (m_params.nonEmptyFramebuffer) 5106 { 5107 renderPassCreateInfo.attachmentCount = 1u; 5108 renderPassCreateInfo.pAttachments = &colorAttachmentDescription; 5109 } 5110 const bool unusedAttachmentSubpass = (m_params.nonEmptyFramebuffer && m_params.unusedAttachment); 5111 renderPassCreateInfo.subpassCount = 1u; 5112 renderPassCreateInfo.pSubpasses = (unusedAttachmentSubpass ? &unusedAttachmentSubpassDescription : &emptySubpassDescription); 5113 RenderPassWrapper renderPassSingleSubpass (m_params.pipelineConstructionType, vkd, device, &renderPassCreateInfo); 5114 5115 // Framebuffers. 5116 vk::VkFramebufferCreateInfo framebufferCreateInfo = 5117 { 5118 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 5119 nullptr, // const void* pNext; 5120 0u, // VkFramebufferCreateFlags flags; 5121 DE_NULL, // VkRenderPass renderPass; 5122 0u, // deUint32 attachmentCount; 5123 nullptr, // const VkImageView* pAttachments; 5124 kWidth32, // deUint32 width; 5125 kHeight32, // deUint32 height; 5126 1u, // deUint32 layers; 5127 }; 5128 5129 // Framebuffer for multiple-subpasses render pass. 5130 framebufferCreateInfo.renderPass = renderPassMultiplePasses.get(); 5131 renderPassMultiplePasses.createFramebuffer(vkd, device, &framebufferCreateInfo, std::vector<VkImage>{}); 5132 5133 // Framebuffer for single-subpass render pass. 5134 std::unique_ptr<vk::ImageWithMemory> imagePtr; 5135 vk::Move<vk::VkImageView> imageView; 5136 std::vector<vk::VkImage> images; 5137 5138 if (m_params.nonEmptyFramebuffer) 5139 { 5140 const vk::VkImageCreateInfo imageCreateInfo = 5141 { 5142 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 5143 nullptr, // const void* pNext; 5144 0u, // VkImageCreateFlags flags; 5145 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType; 5146 kColorFormat, // VkFormat format; 5147 vk::makeExtent3D(kWidth32, kHeight32, 1u), // VkExtent3D extent; 5148 1u, // deUint32 mipLevels; 5149 1u, // deUint32 arrayLayers; 5150 m_params.fbCount, // VkSampleCountFlagBits samples; 5151 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 5152 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage; 5153 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 5154 0u, // deUint32 queueFamilyIndexCount; 5155 nullptr, // const deUint32* pQueueFamilyIndices; 5156 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5157 }; 5158 imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any}); 5159 5160 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 5161 imageView = vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange); 5162 5163 framebufferCreateInfo.attachmentCount = 1u; 5164 framebufferCreateInfo.pAttachments = &imageView.get(); 5165 images.push_back(**imagePtr); 5166 } 5167 framebufferCreateInfo.renderPass = renderPassSingleSubpass.get(); 5168 renderPassSingleSubpass.createFramebuffer(vkd, device, &framebufferCreateInfo, images); 5169 5170 // Shader modules and stages. 5171 const auto vertModule = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("vert"), 0u); 5172 const auto fragModule = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("frag"), 0u); 5173 5174 // Vertices, input state and assembly. 5175 const std::vector<tcu::Vec2> vertices = 5176 { 5177 { -0.987f, -0.964f }, 5178 { 0.982f, -0.977f }, 5179 { 0.005f, 0.891f }, 5180 }; 5181 5182 const auto vertexBinding = vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX); 5183 const auto vertexAttribute = vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u); 5184 5185 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = 5186 { 5187 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 5188 nullptr, // const void* pNext; 5189 0u, // VkPipelineVertexInputStateCreateFlags flags; 5190 1u, // deUint32 vertexBindingDescriptionCount; 5191 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 5192 1u, // deUint32 vertexAttributeDescriptionCount; 5193 &vertexAttribute, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 5194 }; 5195 5196 // Graphics pipelines to create output buffers. 5197 const std::vector<VkViewport> viewport { vk::makeViewport(kWidth32, kHeight32) }; 5198 const std::vector<VkRect2D> scissor { vk::makeRect2D(kWidth32, kHeight32) }; 5199 5200 const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT); 5201 5202 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 5203 { 5204 VK_FALSE, // VkBool32 blendEnable; 5205 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor; 5206 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 5207 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 5208 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; 5209 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 5210 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 5211 colorComponentFlags, // VkColorComponentFlags colorWriteMask; 5212 }; 5213 5214 const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoNoAttachments = 5215 { 5216 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 5217 DE_NULL, // const void* pNext; 5218 0u, // VkPipelineColorBlendStateCreateFlags flags; 5219 VK_FALSE, // VkBool32 logicOpEnable; 5220 vk::VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 5221 0u, // deUint32 attachmentCount; 5222 nullptr, // const VkPipelineColorBlendAttachmentState* pAttachments; 5223 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 5224 }; 5225 5226 const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoOneAttachment = 5227 { 5228 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 5229 DE_NULL, // const void* pNext; 5230 0u, // VkPipelineColorBlendStateCreateFlags flags; 5231 VK_FALSE, // VkBool32 logicOpEnable; 5232 vk::VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 5233 1u, // deUint32 attachmentCount; 5234 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 5235 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 5236 }; 5237 5238 vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo 5239 { 5240 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 5241 nullptr, // const void* pNext; 5242 0u, // VkPipelineMultisampleStateCreateFlags flags; 5243 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 5244 VK_FALSE, // VkBool32 sampleShadingEnable; 5245 0.0f, // float minSampleShading; 5246 nullptr, // const VkSampleMask* pSampleMask; 5247 VK_FALSE, // VkBool32 alphaToCoverageEnable; 5248 VK_FALSE, // VkBool32 alphaToOneEnable; 5249 }; 5250 5251 std::vector<GraphicsPipelineWrapper> outputPipelines; 5252 outputPipelines.reserve(m_params.subpassCounts.size()); 5253 for (const auto samples : m_params.subpassCounts) 5254 { 5255 const auto colorBlendStatePtr = (unusedAttachmentSubpass ? &colorBlendStateCreateInfoOneAttachment : &colorBlendStateCreateInfoNoAttachments); 5256 5257 multisampleStateCreateInfo.rasterizationSamples = samples; 5258 5259 outputPipelines.emplace_back(vki, vkd, physDevice, device, m_context.getDeviceExtensions(), m_params.pipelineConstructionType); 5260 outputPipelines.back() 5261 .setDefaultDepthStencilState() 5262 .setDefaultRasterizationState() 5263 .setupVertexInputState(&vertexInputStateCreateInfo) 5264 .setupPreRasterizationShaderState(viewport, 5265 scissor, 5266 pipelineLayout, 5267 *renderPassSingleSubpass, 5268 0u, 5269 vertModule) 5270 .setupFragmentShaderState(pipelineLayout, *renderPassSingleSubpass, 0u, fragModule, DE_NULL, &multisampleStateCreateInfo) 5271 .setupFragmentOutputState(*renderPassSingleSubpass, 0u, colorBlendStatePtr, &multisampleStateCreateInfo) 5272 .setMonolithicPipelineLayout(pipelineLayout) 5273 .buildPipeline(); 5274 } 5275 5276 // Graphics pipelines with variable rate but using several subpasses. 5277 std::vector<GraphicsPipelineWrapper> referencePipelines; 5278 referencePipelines.reserve(m_params.subpassCounts.size()); 5279 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i) 5280 { 5281 multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i]; 5282 5283 deUint32 subpass = static_cast<deUint32>(i); 5284 referencePipelines.emplace_back(vki, vkd, physDevice, device, m_context.getDeviceExtensions(), m_params.pipelineConstructionType); 5285 referencePipelines.back() 5286 .setDefaultDepthStencilState() 5287 .setDefaultRasterizationState() 5288 .setupVertexInputState(&vertexInputStateCreateInfo) 5289 .setupPreRasterizationShaderState(viewport, 5290 scissor, 5291 pipelineLayout, 5292 *renderPassMultiplePasses, 5293 subpass, 5294 vertModule) 5295 .setupFragmentShaderState(pipelineLayout, *renderPassMultiplePasses, subpass, fragModule, DE_NULL, &multisampleStateCreateInfo) 5296 .setupFragmentOutputState(*renderPassMultiplePasses, subpass, &colorBlendStateCreateInfoNoAttachments, &multisampleStateCreateInfo) 5297 .setMonolithicPipelineLayout(pipelineLayout) 5298 .buildPipeline(); 5299 } 5300 5301 // Prepare vertex, reference and output buffers. 5302 const auto vertexBufferSize = vertices.size() * sizeof(decltype(vertices)::value_type); 5303 const auto vertexBufferCreateInfo = vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 5304 vk::BufferWithMemory vertexBuffer {vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible}; 5305 auto& vertexAlloc = vertexBuffer.getAllocation(); 5306 5307 deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize); 5308 vk::flushAlloc(vkd, device, vertexAlloc); 5309 5310 for (size_t i = 0; i < referenceBuffers.size(); ++i) 5311 { 5312 zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]); 5313 zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]); 5314 } 5315 5316 // Prepare descriptor sets. 5317 const deUint32 totalSets = static_cast<deUint32>(referenceBuffers.size() * 2u); 5318 vk::DescriptorPoolBuilder poolBuilder; 5319 poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u)); 5320 const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets); 5321 5322 std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets (referenceBuffers.size()); 5323 std::vector<vk::Move<vk::VkDescriptorSet>> outputSets (outputBuffers.size()); 5324 5325 for (auto& set : referenceSets) 5326 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get()); 5327 for (auto& set : outputSets) 5328 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get()); 5329 5330 vk::DescriptorSetUpdateBuilder updateBuilder; 5331 5332 for (size_t i = 0; i < referenceSets.size(); ++i) 5333 { 5334 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]); 5335 updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo); 5336 } 5337 for (size_t i = 0; i < outputSets.size(); ++i) 5338 { 5339 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]); 5340 updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo); 5341 } 5342 5343 updateBuilder.update(vkd, device); 5344 5345 // Prepare command pool. 5346 const auto cmdPool = vk::makeCommandPool(vkd, device, queueIndex); 5347 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY); 5348 const auto cmdBuffer = cmdBufferPtr.get(); 5349 5350 vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier = 5351 { 5352 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 5353 nullptr, // const void* pNext; 5354 vk::VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 5355 vk::VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 5356 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 5357 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 5358 DE_NULL, // VkBuffer buffer; 5359 0u, // VkDeviceSize offset; 5360 VK_WHOLE_SIZE, // VkDeviceSize size; 5361 }; 5362 5363 // Record command buffer. 5364 const vk::VkDeviceSize vertexBufferOffset = 0u; 5365 const auto renderArea = vk::makeRect2D(kWidth32, kHeight32); 5366 PushConstants pushConstants = { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 }; 5367 5368 vk::beginCommandBuffer(vkd, cmdBuffer); 5369 5370 // Render output buffers. 5371 renderPassSingleSubpass.begin(vkd, cmdBuffer, renderArea); 5372 for (size_t i = 0; i < outputBuffers.size(); ++i) 5373 { 5374 outputPipelines[i].bind(cmdBuffer); 5375 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr); 5376 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 5377 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]); 5378 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants); 5379 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u); 5380 } 5381 renderPassSingleSubpass.end(vkd, cmdBuffer); 5382 for (size_t i = 0; i < outputBuffers.size(); ++i) 5383 { 5384 storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get(); 5385 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr); 5386 } 5387 5388 // Render reference buffers. 5389 renderPassMultiplePasses.begin(vkd, cmdBuffer, renderArea); 5390 for (size_t i = 0; i < referenceBuffers.size(); ++i) 5391 { 5392 if (i > 0) 5393 renderPassMultiplePasses.nextSubpass(vkd, cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE); 5394 referencePipelines[i].bind(cmdBuffer); 5395 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr); 5396 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 5397 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]); 5398 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants); 5399 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u); 5400 } 5401 renderPassMultiplePasses.end(vkd, cmdBuffer); 5402 for (size_t i = 0; i < referenceBuffers.size(); ++i) 5403 { 5404 storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get(); 5405 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr); 5406 } 5407 5408 vk::endCommandBuffer(vkd, cmdBuffer); 5409 5410 // Run all pipelines. 5411 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer); 5412 5413 // Invalidate reference allocs. 5414#undef LOG_BUFFER_CONTENTS 5415#ifdef LOG_BUFFER_CONTENTS 5416 auto& log = m_context.getTestContext().getLog(); 5417#endif 5418 for (size_t i = 0; i < referenceBuffers.size(); ++i) 5419 { 5420 auto& buffer = referenceBuffers[i]; 5421 auto& alloc = buffer->getAllocation(); 5422 vk::invalidateAlloc(vkd, device, alloc); 5423 5424#ifdef LOG_BUFFER_CONTENTS 5425 std::vector<deInt32> bufferValues(bufferNumElements[i]); 5426 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]); 5427 5428 std::ostringstream msg; 5429 for (const auto value : bufferValues) 5430 msg << " " << value; 5431 log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage; 5432#endif 5433 } 5434 5435 for (size_t i = 0; i < outputBuffers.size(); ++i) 5436 { 5437 auto& buffer = outputBuffers[i]; 5438 auto& alloc = buffer->getAllocation(); 5439 vk::invalidateAlloc(vkd, device, alloc); 5440 5441#ifdef LOG_BUFFER_CONTENTS 5442 std::vector<deInt32> bufferValues(bufferNumElements[i]); 5443 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]); 5444 5445 std::ostringstream msg; 5446 for (const auto value : bufferValues) 5447 msg << " " << value; 5448 log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage; 5449#endif 5450 5451 if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0) 5452 return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i)); 5453 } 5454 5455 return tcu::TestStatus::pass("Pass"); 5456} 5457 5458using ElementsVector = std::vector<vk::VkSampleCountFlagBits>; 5459using CombinationVector = std::vector<ElementsVector>; 5460 5461void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial) 5462{ 5463 if (partial.size() == requestedSize) 5464 solutions.push_back(partial); 5465 else 5466 { 5467 for (const auto& elem : elements) 5468 { 5469 partial.push_back(elem); 5470 combinationsRecursive(elements, requestedSize, solutions, partial); 5471 partial.pop_back(); 5472 } 5473 } 5474} 5475 5476CombinationVector combinations(const ElementsVector& elements, size_t requestedSize) 5477{ 5478 CombinationVector solutions; 5479 ElementsVector partial; 5480 5481 combinationsRecursive(elements, requestedSize, solutions, partial); 5482 return solutions; 5483} 5484 5485/******** 5486Z EXPORT TESTS 5487 5488The tests enable alpha to coverage statically or dynamically, and play with 3 other parameters, which we can be testing or not as 5489outputs from the frag shader. 5490 5491* Depth value 5492* Stencil reference value 5493* Sample mask 5494 5495Alpha values on the left side of the framebuffer will be 0.0. On the right side they will be 1.0. This means the left side should 5496not have coverage, and the right side should have. 5497 5498Depth value will be cleared to 1.0 and we expect to obtain 0.0 for covered pixels at the end. We will activate the depth test with a 5499depth compare op of "less". 5500 5501* If we are testing this, we will set 0.5 from the vertex shader and 0.0 from the frag shader. 5502* If we are not testing this, we will set 0.0 directly from the vertex shader. 5503 5504Stencil will be cleared to 0 and we expect to obtain 255 for covered pixels at the end. We will activate the stencil test with a 5505stencil op of "replace" for front-facing pixels, compare op "always", keep and "never" for back-facing pixels. 5506 5507* If we are testing this, the stencil ref value will be 128 in the pipeline, then 255 from the frag shader. 5508* If we are not testing this, the reference value will be set to 255 directly in the pipeline. 5509 5510Sample mask is a bit special: we'll always set it to 0xFF in the pipeline, and we normally expect all pixels to be covered. 5511 5512* If we are testing this, we'll set it to 0x00 on the lower half of the framebuffer. 5513* If we are not testing this, we'll leave it as it is. 5514 5515Expected result: 5516 5517* The left side of the framebuffer will have: 5518 - The clear color. 5519 - The clear depth value. 5520 - The clear stencil value. 5521 5522* The right side of the framebuffer will have: 5523 - The geometry color (typically blue). 5524 - The expected depth value. 5525 - The expected stencil value. 5526 - But, if we are testing the sample mask, the lower half of the right side will be like the left side. 5527 5528********/ 5529enum ZExportTestBits 5530{ 5531 ZEXP_DEPTH_BIT = 0x1, 5532 ZEXP_STENCIL_BIT = 0x2, // Requires VK_EXT_shader_stencil_export 5533 ZEXP_SAMPLE_MASK_BIT = 0x4, 5534}; 5535 5536using ZExportFlags = uint32_t; 5537 5538struct ZExportParams 5539{ 5540 const PipelineConstructionType pipelineConstructionType; 5541 const ZExportFlags testFlags; 5542 const bool dynamicAlphaToCoverage; 5543 5544 ZExportParams (PipelineConstructionType pipelineConstructionType_, ZExportFlags testFlags_, bool dynamicAlphaToCoverage_) 5545 : pipelineConstructionType (pipelineConstructionType_) 5546 , testFlags (testFlags_) 5547 , dynamicAlphaToCoverage (dynamicAlphaToCoverage_) 5548 {} 5549 5550 bool testDepth (void) const { return hasFlag(ZEXP_DEPTH_BIT); } 5551 bool testStencil (void) const { return hasFlag(ZEXP_STENCIL_BIT); } 5552 bool testSampleMask (void) const { return hasFlag(ZEXP_SAMPLE_MASK_BIT); } 5553 5554 static constexpr float kClearDepth = 1.0f; 5555 static constexpr float kExpectedDepth = 0.0f; 5556 static constexpr float kBadDepth = 0.5f; 5557 5558 static constexpr uint32_t kClearStencil = 0u; 5559 static constexpr uint32_t kExpectedStencil = 255u; 5560 static constexpr uint32_t kBadStencil = 128u; 5561 5562 static constexpr uint32_t kWidth = 4u; 5563 static constexpr uint32_t kHeight = 4u; 5564 5565private: 5566 bool hasFlag (ZExportTestBits bit) const 5567 { 5568 return ((testFlags & static_cast<ZExportFlags>(bit)) != 0u); 5569 } 5570}; 5571 5572void ZExportCheckSupport (Context& context, const ZExportParams params) 5573{ 5574 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), params.pipelineConstructionType); 5575 5576 context.requireDeviceFunctionality("VK_KHR_create_renderpass2"); 5577 context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve"); 5578 5579 const auto& dsResolveProperties = context.getDepthStencilResolveProperties(); 5580 5581 if ((dsResolveProperties.supportedDepthResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) == 0u) 5582 TCU_THROW(NotSupportedError, "VK_RESOLVE_MODE_SAMPLE_ZERO_BIT not supported for depth"); 5583 5584 if ((dsResolveProperties.supportedStencilResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) == 0u) 5585 TCU_THROW(NotSupportedError, "VK_RESOLVE_MODE_SAMPLE_ZERO_BIT not supported for stencil"); 5586 5587 if (params.testStencil()) 5588 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export"); 5589 5590 if (params.dynamicAlphaToCoverage) 5591 { 5592#ifndef CTS_USES_VULKANSC 5593 const auto& eds3Features = context.getExtendedDynamicState3FeaturesEXT(); 5594 if (!eds3Features.extendedDynamicState3AlphaToCoverageEnable) 5595 TCU_THROW(NotSupportedError, "extendedDynamicState3AlphaToCoverageEnable not supported"); 5596#else 5597 DE_ASSERT(false); 5598#endif // CTS_USES_VULKANSC 5599 } 5600} 5601 5602void ZExportInitPrograms (SourceCollections& programCollection, const ZExportParams params) 5603{ 5604 { 5605 const auto vertDepth = (params.testDepth() ? ZExportParams::kBadDepth : ZExportParams::kExpectedDepth); 5606 5607 std::ostringstream vert; 5608 vert 5609 << "#version 460\n" 5610 << "vec2 positions[3] = vec2[](\n" 5611 << " vec2(-1.0, -1.0),\n" 5612 << " vec2(-1.0, 3.0),\n" 5613 << " vec2(3.0, -1.0)\n" 5614 << ");\n" 5615 << "void main (void) {\n" 5616 << " gl_Position = vec4(positions[gl_VertexIndex % 3], " << vertDepth << ", 1.0);\n" 5617 << "}\n" 5618 ; 5619 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str()); 5620 } 5621 5622 { 5623 std::ostringstream frag; 5624 frag 5625 << "#version 460\n" 5626 << "layout (location=0) out vec4 outColor;\n" 5627 << (params.testStencil() ? "#extension GL_ARB_shader_stencil_export: require\n" : "") 5628 << "void main (void) {\n" 5629 << " const float alphaValue = ((int(gl_FragCoord.x) < " << (ZExportParams::kWidth / 2u) << ") ? 0.0 : 1.0);\n" 5630 << " outColor = vec4(0.0, 0.0, 1.0, alphaValue);\n" 5631 << (params.testDepth() ? (" gl_FragDepth = " + std::to_string(ZExportParams::kExpectedDepth) + ";\n") : "") 5632 << (params.testStencil() ? (" gl_FragStencilRefARB = " + std::to_string(ZExportParams::kExpectedStencil) + ";\n") : "") 5633 ; 5634 5635 if (params.testSampleMask()) 5636 frag << " gl_SampleMask[0] = ((int(gl_FragCoord.y) >= " << (ZExportParams::kHeight / 2u) << ") ? 0 : 0xFF);\n"; 5637 5638 frag << "}\n"; 5639 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str()); 5640 } 5641} 5642 5643tcu::TestStatus ZExportIterate (Context& context, const ZExportParams params) 5644{ 5645 const auto& ctx = context.getContextCommonData(); 5646 5647 // Choose depth/stencil format. 5648 const auto dsFormat = findSupportedDepthStencilFormat(context, true, true); 5649 if (dsFormat == VK_FORMAT_UNDEFINED) 5650 TCU_FAIL("Unable to find supported depth/stencil format"); 5651 5652 const auto fbExtent = makeExtent3D(ZExportParams::kWidth, ZExportParams::kHeight, 1u); 5653 const auto colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 5654 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 5655 const auto dsUsage = (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 5656 const auto colorAspect = VK_IMAGE_ASPECT_COLOR_BIT; 5657 const auto dsAspect = (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); 5658 const auto colorSRR = makeImageSubresourceRange(colorAspect, 0u, 1u, 0u, 1u); 5659 const auto dsSRR = makeImageSubresourceRange(dsAspect, 0u, 1u, 0u, 1u); 5660 const auto imageType = VK_IMAGE_TYPE_2D; 5661 const auto viewType = VK_IMAGE_VIEW_TYPE_2D; 5662 const auto sampleCount = VK_SAMPLE_COUNT_4_BIT; 5663 const auto bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 5664 5665 // Multisample color attachment. 5666 const VkImageCreateInfo colorAttachmentCreateInfo = 5667 { 5668 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 5669 nullptr, // const void* pNext; 5670 0u, // VkImageCreateFlags flags; 5671 imageType, // VkImageType imageType; 5672 colorFormat, // VkFormat format; 5673 fbExtent, // VkExtent3D extent; 5674 1u, // uint32_t mipLevels; 5675 1u, // uint32_t arrayLayers; 5676 sampleCount, // VkSampleCountFlagBits samples; 5677 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 5678 colorUsage, // VkImageUsageFlags usage; 5679 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 5680 0u, // uint32_t queueFamilyIndexCount; 5681 nullptr, // const uint32_t* pQueueFamilyIndices; 5682 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5683 }; 5684 ImageWithMemory colorAttachment (ctx.vkd, ctx.device, ctx.allocator, colorAttachmentCreateInfo, MemoryRequirement::Any); 5685 const auto colorAttachmentView = makeImageView(ctx.vkd, ctx.device, colorAttachment.get(), viewType, colorFormat, colorSRR); 5686 5687 // Multisample depth/stencil attachment. 5688 const VkImageCreateInfo dsAttachmentCreateInfo = 5689 { 5690 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 5691 nullptr, // const void* pNext; 5692 0u, // VkImageCreateFlags flags; 5693 imageType, // VkImageType imageType; 5694 dsFormat, // VkFormat format; 5695 fbExtent, // VkExtent3D extent; 5696 1u, // uint32_t mipLevels; 5697 1u, // uint32_t arrayLayers; 5698 sampleCount, // VkSampleCountFlagBits samples; 5699 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 5700 dsUsage, // VkImageUsageFlags usage; 5701 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 5702 0u, // uint32_t queueFamilyIndexCount; 5703 nullptr, // const uint32_t* pQueueFamilyIndices; 5704 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5705 }; 5706 ImageWithMemory dsAttachment (ctx.vkd, ctx.device, ctx.allocator, dsAttachmentCreateInfo, MemoryRequirement::Any); 5707 const auto dsAttachmentView = makeImageView(ctx.vkd, ctx.device, dsAttachment.get(), viewType, dsFormat, dsSRR); 5708 5709 // Resolve attachments. 5710 VkImageCreateInfo colorResolveAttachmentCreateInfo = colorAttachmentCreateInfo; 5711 colorResolveAttachmentCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; 5712 VkImageCreateInfo dsResolveAttachmentCreateInfo = dsAttachmentCreateInfo; 5713 dsResolveAttachmentCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; 5714 5715 ImageWithMemory colorResolveAttachment (ctx.vkd, ctx.device, ctx.allocator, colorResolveAttachmentCreateInfo, MemoryRequirement::Any); 5716 ImageWithMemory dsResolveAttachment (ctx.vkd, ctx.device, ctx.allocator, dsResolveAttachmentCreateInfo, MemoryRequirement::Any); 5717 const auto colorResolveAttachmentView = makeImageView(ctx.vkd, ctx.device, colorResolveAttachment.get(), viewType, colorFormat, colorSRR); 5718 const auto dsResolveAttachmentView = makeImageView(ctx.vkd, ctx.device, dsResolveAttachment.get(), viewType, dsFormat, dsSRR); 5719 5720 // Render pass and framebuffer. 5721 const VkAttachmentDescription2 colorAttachmentDesc = 5722 { 5723 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 5724 nullptr, 5725 0u, // VkAttachmentDescriptionFlags flags; 5726 colorFormat, // VkFormat format; 5727 sampleCount, // VkSampleCountFlagBits samples; 5728 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 5729 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 5730 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 5731 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 5732 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5733 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 5734 }; 5735 const VkAttachmentDescription2 dsAttachmentDesc = 5736 { 5737 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 5738 nullptr, 5739 0u, // VkAttachmentDescriptionFlags flags; 5740 dsFormat, // VkFormat format; 5741 sampleCount, // VkSampleCountFlagBits samples; 5742 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 5743 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 5744 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 5745 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 5746 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5747 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 5748 }; 5749 const VkAttachmentDescription2 colorResolveAttachmentDesc = 5750 { 5751 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 5752 nullptr, 5753 0u, // VkAttachmentDescriptionFlags flags; 5754 colorFormat, // VkFormat format; 5755 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 5756 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 5757 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 5758 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 5759 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 5760 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5761 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 5762 }; 5763 const VkAttachmentDescription2 dsResolveAttachmentDesc = 5764 { 5765 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 5766 nullptr, 5767 0u, // VkAttachmentDescriptionFlags flags; 5768 dsFormat, // VkFormat format; 5769 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 5770 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 5771 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 5772 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 5773 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 5774 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 5775 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 5776 }; 5777 5778 std::vector<VkAttachmentDescription2> attachmentDescriptions; 5779 attachmentDescriptions.reserve(4u); 5780 attachmentDescriptions.push_back(colorAttachmentDesc); 5781 attachmentDescriptions.push_back(dsAttachmentDesc); 5782 attachmentDescriptions.push_back(colorResolveAttachmentDesc); 5783 attachmentDescriptions.push_back(dsResolveAttachmentDesc); 5784 5785 const VkAttachmentReference2 colorAttachmentReference = 5786 { 5787 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 5788 nullptr, 5789 0u, 5790 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5791 colorAspect, 5792 }; 5793 const VkAttachmentReference2 dsAttachmentReference = 5794 { 5795 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 5796 nullptr, 5797 1u, 5798 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5799 dsAspect, 5800 }; 5801 const VkAttachmentReference2 colorResolveAttachmentReference = 5802 { 5803 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 5804 nullptr, 5805 2u, 5806 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5807 colorAspect, 5808 }; 5809 const VkAttachmentReference2 dsResolveAttachmentReference = 5810 { 5811 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 5812 nullptr, 5813 3u, 5814 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5815 dsAspect, 5816 }; 5817 5818 const VkSubpassDescriptionDepthStencilResolve dsResolveDescription = 5819 { 5820 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, // VkStructureType sType; 5821 nullptr, // const void* pNext; 5822 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, // VkResolveModeFlagBits depthResolveMode; 5823 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, // VkResolveModeFlagBits stencilResolveMode; 5824 &dsResolveAttachmentReference, // const VkAttachmentReference2* pDepthStencilResolveAttachment; 5825 }; 5826 5827 const VkSubpassDescription2 subpassDescription = 5828 { 5829 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, 5830 &dsResolveDescription, 5831 0u, // VkSubpassDescriptionFlags flags; 5832 bindPoint, // VkPipelineBindPoint pipelineBindPoint; 5833 0u, // uint32_t viewMask; 5834 0u, // uint32_t inputAttachmentCount; 5835 nullptr, // const VkAttachmentReference* pInputAttachments; 5836 1u, // uint32_t colorAttachmentCount; 5837 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 5838 &colorResolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments; 5839 &dsAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 5840 0u, // uint32_t preserveAttachmentCount; 5841 nullptr, // const uint32_t* pPreserveAttachments; 5842 }; 5843 5844 const VkRenderPassCreateInfo2 renderPassCreateInfo = 5845 { 5846 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // VkStructureType sType; 5847 nullptr, // const void* pNext; 5848 0u, // VkRenderPassCreateFlags flags; 5849 de::sizeU32(attachmentDescriptions), // uint32_t attachmentCount; 5850 de::dataOrNull(attachmentDescriptions), // const VkAttachmentDescription* pAttachments; 5851 1u, // uint32_t subpassCount; 5852 &subpassDescription, // const VkSubpassDescription* pSubpasses; 5853 0u, // uint32_t dependencyCount; 5854 nullptr, // const VkSubpassDependency* pDependencies; 5855 0u, // uint32_t correlatedViewMaskCount; 5856 nullptr, // const uint32_t* pCorrelatedViewMasks; 5857 }; 5858 5859 const std::vector<VkImage> images 5860 { 5861 *colorAttachment, 5862 *dsAttachment, 5863 *colorResolveAttachment, 5864 *dsResolveAttachment, 5865 }; 5866 5867 const std::vector<VkImageView> attachmentViews 5868 { 5869 colorAttachmentView.get(), 5870 dsAttachmentView.get(), 5871 colorResolveAttachmentView.get(), 5872 dsResolveAttachmentView.get(), 5873 }; 5874 5875 RenderPassWrapper renderPass (params.pipelineConstructionType, ctx.vkd, ctx.device, &renderPassCreateInfo); 5876 renderPass.createFramebuffer(ctx.vkd, ctx.device, de::sizeU32(attachmentViews), de::dataOrNull(images), de::dataOrNull(attachmentViews), fbExtent.width, fbExtent.height); 5877 5878 // Pipeline layout. 5879 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, ctx.vkd, ctx.device); 5880 5881 // Shaders. 5882 const auto& binaries = context.getBinaryCollection(); 5883 const auto vertShader = ShaderWrapper(ctx.vkd, ctx.device, binaries.get("vert")); 5884 const auto fragShader = ShaderWrapper(ctx.vkd, ctx.device, binaries.get("frag")); 5885 5886 // Viewports and scissors. 5887 const std::vector<VkViewport> viewports (1u, makeViewport(fbExtent)); 5888 const std::vector<VkRect2D> scissors (1u, makeRect2D(fbExtent)); 5889 5890 const auto frontStencilRef = (params.testStencil() ? ZExportParams::kBadStencil : ZExportParams::kExpectedStencil); 5891 const VkStencilOpState frontStencilOpState 5892 { 5893 VK_STENCIL_OP_KEEP, // VkStencilOp failOp 5894 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp 5895 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp 5896 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp 5897 0xFFu, // deUint32 compareMask 5898 0xFFu, // deUint32 writeMask 5899 frontStencilRef, // deUint32 reference 5900 }; 5901 const auto backStencilOpState = makeStencilOpState(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0xFFu, 0xFFu, 0u); 5902 5903 const VkPipelineDepthStencilStateCreateInfo dsStateInfo 5904 { 5905 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType 5906 DE_NULL, // const void* pNext 5907 0u, // VkPipelineDepthStencilStateCreateFlags flags 5908 VK_TRUE, // VkBool32 depthTestEnable 5909 VK_TRUE, // VkBool32 depthWriteEnable 5910 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp 5911 VK_FALSE, // VkBool32 depthBoundsTestEnable 5912 VK_TRUE, // VkBool32 stencilTestEnable 5913 frontStencilOpState, // VkStencilOpState front 5914 backStencilOpState, // VkStencilOpState back 5915 0.0f, // float minDepthBounds 5916 1.0f, // float maxDepthBounds 5917 }; 5918 5919 // Multisample state, including alpha to coverage, which is key for these tests. 5920 const auto staticAlphaToCoverage = (params.dynamicAlphaToCoverage ? VK_FALSE : VK_TRUE); 5921 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo 5922 { 5923 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType 5924 nullptr, // const void* pNext 5925 0u, // VkPipelineMultisampleStateCreateFlags flags 5926 sampleCount, // VkSampleCountFlagBits rasterizationSamples 5927 VK_FALSE, // VkBool32 sampleShadingEnable 5928 1.0f, // float minSampleShading 5929 nullptr, // const VkSampleMask* pSampleMask 5930 staticAlphaToCoverage, // VkBool32 alphaToCoverageEnable 5931 VK_FALSE, // VkBool32 alphaToOneEnable 5932 }; 5933 5934 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = initVulkanStructure(); 5935 5936 std::vector<VkDynamicState> dynamicStates; 5937#ifndef CTS_USES_VULKANSC 5938 if (params.dynamicAlphaToCoverage) 5939 dynamicStates.push_back(VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT); 5940#else 5941 DE_ASSERT(false); 5942#endif // CTS_USES_VULKANSC 5943 5944 const VkPipelineDynamicStateCreateInfo dynamicStateInfo = 5945 { 5946 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; 5947 nullptr, // const void* pNext; 5948 0u, // VkPipelineDynamicStateCreateFlags flags; 5949 de::sizeU32(dynamicStates), // uint32_t dynamicStateCount; 5950 de::dataOrNull(dynamicStates), // const VkDynamicState* pDynamicStates; 5951 }; 5952 5953 GraphicsPipelineWrapper pipelineWrapper (ctx.vki, ctx.vkd, ctx.physicalDevice, ctx.device, context.getDeviceExtensions(), params.pipelineConstructionType); 5954 pipelineWrapper 5955 .setDefaultRasterizationState() 5956 .setDefaultColorBlendState() 5957 .setDynamicState(&dynamicStateInfo) 5958 .setupVertexInputState(&vertexInputStateCreateInfo) 5959 .setupPreRasterizationShaderState(viewports, 5960 scissors, 5961 pipelineLayout, 5962 *renderPass, 5963 0u, 5964 vertShader) 5965 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragShader, &dsStateInfo, &multisampleStateCreateInfo) 5966 .setupFragmentOutputState(*renderPass, 0u, nullptr, &multisampleStateCreateInfo) 5967 .setMonolithicPipelineLayout(pipelineLayout) 5968 .buildPipeline(); 5969 5970 CommandPoolWithBuffer cmd (ctx.vkd, ctx.device, ctx.qfIndex); 5971 const auto cmdBuffer = *cmd.cmdBuffer; 5972 5973 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f); 5974 const tcu::Vec4 geometryColor (0.0f, 0.0f, 1.0f, 1.0f); // For pixels with coverage. Must match frag shader. 5975 5976 const std::vector<VkClearValue> clearValues 5977 { 5978 makeClearValueColor(clearColor), 5979 makeClearValueDepthStencil(ZExportParams::kClearDepth, ZExportParams::kClearStencil), 5980 }; 5981 5982 beginCommandBuffer(ctx.vkd, cmdBuffer); 5983 renderPass.begin(ctx.vkd, cmdBuffer, scissors.at(0u), de::sizeU32(clearValues), de::dataOrNull(clearValues)); 5984 pipelineWrapper.bind(cmdBuffer); 5985#ifndef CTS_USES_VULKANSC 5986 if (params.dynamicAlphaToCoverage) 5987 ctx.vkd.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_TRUE); 5988#else 5989 DE_ASSERT(false); 5990#endif // CTS_USES_VULKANSC 5991 ctx.vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u); 5992 renderPass.end(ctx.vkd, cmdBuffer); 5993 endCommandBuffer(ctx.vkd, cmdBuffer); 5994 submitCommandsAndWait(ctx.vkd, ctx.device, ctx.queue, cmdBuffer); 5995 5996 const tcu::UVec2 renderSize (fbExtent.width, fbExtent.height); 5997 const auto colorLevel = readColorAttachment(ctx.vkd, ctx.device, ctx.queue, ctx.qfIndex, ctx.allocator, colorResolveAttachment.get(), colorFormat, renderSize); 5998 const auto depthLevel = readDepthAttachment(ctx.vkd, ctx.device, ctx.queue, ctx.qfIndex, ctx.allocator, dsResolveAttachment.get(), dsFormat, renderSize); 5999 const auto stencilLevel = readStencilAttachment(ctx.vkd, ctx.device, ctx.queue, ctx.qfIndex, ctx.allocator, dsResolveAttachment.get(), dsFormat, renderSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 6000 6001 const auto colorAccess = colorLevel->getAccess(); 6002 const auto depthAccess = depthLevel->getAccess(); 6003 const auto stencilAccess = stencilLevel->getAccess(); 6004 6005 const tcu::IVec3 iExtent (static_cast<int>(fbExtent.width), static_cast<int>(fbExtent.height), static_cast<int>(fbExtent.depth)); 6006 tcu::TextureLevel refColor (mapVkFormat(colorFormat), iExtent.x(), iExtent.y()); 6007 tcu::TextureLevel refDepth (getDepthCopyFormat(dsFormat), iExtent.x(), iExtent.y()); 6008 tcu::TextureLevel refStencil (getStencilCopyFormat(dsFormat), iExtent.x(), iExtent.y()); 6009 6010 auto refColorAccess = refColor.getAccess(); 6011 auto refDepthAccess = refDepth.getAccess(); 6012 auto refStencilAccess = refStencil.getAccess(); 6013 6014 const auto halfWidth = iExtent.x() / 2; 6015 const auto halfHeight = iExtent.y() / 2; 6016 6017 const tcu::Vec4 geometryColorNoAlpha (geometryColor.x(), geometryColor.y(), geometryColor.z(), 0.0f); // For pixels with coverage but alpha set to 0 6018 6019 // allow skipping alpha to coverage if sample mask output is used 6020 std::vector<bool> skipAlphaToCoverageBehaviors = (params.testSampleMask() ? std::vector<bool>({false, true}) : std::vector<bool>({false})); 6021 6022 for (bool skipAlphaToCoverage : skipAlphaToCoverageBehaviors) 6023 { 6024 6025 // Prepare color reference. 6026 { 6027 auto topLeft = tcu::getSubregion(refColorAccess, 0, 0, halfWidth, halfHeight); 6028 auto bottomLeft = tcu::getSubregion(refColorAccess, 0, halfHeight, halfWidth, halfHeight); 6029 auto topRight = tcu::getSubregion(refColorAccess, halfWidth, 0, halfWidth, halfHeight); 6030 auto bottomRight = tcu::getSubregion(refColorAccess, halfWidth, halfHeight, halfWidth, halfHeight); 6031 6032 tcu::clear(topLeft, (skipAlphaToCoverage ? geometryColorNoAlpha : clearColor)); 6033 tcu::clear(bottomLeft, (skipAlphaToCoverage ? (params.testSampleMask() ? clearColor : geometryColorNoAlpha) : clearColor)); 6034 tcu::clear(topRight, geometryColor); 6035 tcu::clear(bottomRight, (params.testSampleMask() ? clearColor : geometryColor)); 6036 } 6037 // Prepare depth reference. 6038 { 6039 auto topLeft = tcu::getSubregion(refDepthAccess, 0, 0, halfWidth, halfHeight); 6040 auto bottomLeft = tcu::getSubregion(refDepthAccess, 0, halfHeight, halfWidth, halfHeight); 6041 auto topRight = tcu::getSubregion(refDepthAccess, halfWidth, 0, halfWidth, halfHeight); 6042 auto bottomRight = tcu::getSubregion(refDepthAccess, halfWidth, halfHeight, halfWidth, halfHeight); 6043 6044 tcu::clearDepth(topLeft, (skipAlphaToCoverage ? ZExportParams::kExpectedDepth : ZExportParams::kClearDepth)); 6045 tcu::clearDepth(bottomLeft, (skipAlphaToCoverage ? (params.testSampleMask() ? ZExportParams::kClearDepth : ZExportParams::kExpectedDepth) : ZExportParams::kClearDepth)); 6046 tcu::clearDepth(topRight, ZExportParams::kExpectedDepth); 6047 tcu::clearDepth(bottomRight, (params.testSampleMask() ? ZExportParams::kClearDepth : ZExportParams::kExpectedDepth)); 6048 } 6049 // Prepare stencil reference. 6050 { 6051 const auto clearStencil = static_cast<int>(ZExportParams::kClearStencil); 6052 const auto expectedStencil = static_cast<int>(ZExportParams::kExpectedStencil); 6053 6054 auto topLeft = tcu::getSubregion(refStencilAccess, 0, 0, halfWidth, halfHeight); 6055 auto bottomLeft = tcu::getSubregion(refStencilAccess, 0, halfHeight, halfWidth, halfHeight); 6056 auto topRight = tcu::getSubregion(refStencilAccess, halfWidth, 0, halfWidth, halfHeight); 6057 auto bottomRight = tcu::getSubregion(refStencilAccess, halfWidth, halfHeight, halfWidth, halfHeight); 6058 6059 tcu::clearStencil(topLeft, (skipAlphaToCoverage ? expectedStencil : clearStencil)); 6060 tcu::clearStencil(bottomLeft, (skipAlphaToCoverage ? (params.testSampleMask() ? clearStencil : expectedStencil) : clearStencil)); 6061 tcu::clearStencil(topRight, expectedStencil); 6062 tcu::clearStencil(bottomRight, (params.testSampleMask() ? clearStencil : expectedStencil)); 6063 } 6064 6065 // Compare results and references. 6066 auto& log = context.getTestContext().getLog(); 6067 const auto colorOK = tcu::floatThresholdCompare(log, "Color", "Color Result", refColorAccess, colorAccess, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::COMPARE_LOG_ON_ERROR); 6068 const auto depthOK = tcu::dsThresholdCompare(log, "Depth", "Depth Result", refDepthAccess, depthAccess, 0.0f, tcu::COMPARE_LOG_ON_ERROR); 6069 const auto stencilOK = tcu::dsThresholdCompare(log, "Stencil", "Stencil Result", refStencilAccess, stencilAccess, 0.0f, tcu::COMPARE_LOG_ON_ERROR); 6070 6071 if (colorOK && depthOK && stencilOK) 6072 return tcu::TestStatus::pass("Pass"); 6073 } 6074 6075 return tcu::TestStatus::fail("Unexpected color, depth or stencil result; check log for details"); 6076} 6077 6078} // anonymous 6079 6080tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, bool useFragmentShadingRate) 6081{ 6082 using TestCaseGroupPtr = de::MovePtr<tcu::TestCaseGroup>; 6083 6084 const VkSampleCountFlagBits samples[] = 6085 { 6086 VK_SAMPLE_COUNT_2_BIT, 6087 VK_SAMPLE_COUNT_4_BIT, 6088 VK_SAMPLE_COUNT_8_BIT, 6089 VK_SAMPLE_COUNT_16_BIT, 6090 VK_SAMPLE_COUNT_32_BIT, 6091 VK_SAMPLE_COUNT_64_BIT 6092 }; 6093 6094 const char* groupName[] { "multisample", "multisample_with_fragment_shading_rate" }; 6095 TestCaseGroupPtr multisampleTests (new tcu::TestCaseGroup(testCtx, groupName[useFragmentShadingRate])); 6096 6097 // Rasterization samples tests 6098 { 6099 TestCaseGroupPtr rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples")); 6100 6101 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6102 { 6103 std::ostringstream caseName; 6104 caseName << "samples_" << samples[samplesNdx]; 6105 6106 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6107 6108 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate)); 6109 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate)); 6110 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate)); 6111 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate)); 6112 6113 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT, useFragmentShadingRate)); 6114 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT, useFragmentShadingRate)); 6115 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT, useFragmentShadingRate)); 6116 6117#ifndef CTS_USES_VULKANSC 6118 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate)); 6119 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate)); 6120 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate)); 6121 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate)); 6122 6123 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT, useFragmentShadingRate)); 6124 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT, useFragmentShadingRate)); 6125 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT, useFragmentShadingRate)); 6126#endif // CTS_USES_VULKANSC 6127 rasterizationSamplesTests->addChild(samplesTests.release()); 6128 } 6129 6130 multisampleTests->addChild(rasterizationSamplesTests.release()); 6131 } 6132 6133 // Raster samples consistency check 6134#ifndef CTS_USES_VULKANSC 6135 { 6136 TestCaseGroupPtr rasterSamplesConsistencyTests (new tcu::TestCaseGroup(testCtx, "raster_samples_consistency")); 6137 MultisampleTestParams paramsRegular = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate }; 6138 MultisampleTestParams paramsSparse = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate }; 6139 6140 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(), 6141 "unique_colors_check", 6142 checkSupport, 6143 initMultisamplePrograms, 6144 testRasterSamplesConsistency, 6145 paramsRegular); 6146 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(), 6147 "unique_colors_check_sparse", 6148 checkSupport, 6149 initMultisamplePrograms, 6150 testRasterSamplesConsistency, 6151 paramsSparse); 6152 multisampleTests->addChild(rasterSamplesConsistencyTests.release()); 6153 6154 } 6155#endif // CTS_USES_VULKANSC 6156 6157 // minSampleShading tests 6158 { 6159 struct TestConfig 6160 { 6161 const char* name; 6162 float minSampleShading; 6163 }; 6164 6165 const TestConfig testConfigs[] = 6166 { 6167 { "min_0_0", 0.0f }, 6168 { "min_0_25", 0.25f }, 6169 { "min_0_5", 0.5f }, 6170 { "min_0_75", 0.75f }, 6171 { "min_1_0", 1.0f } 6172 }; 6173 6174 // Input attachments are not supported with dynamic rendering and shader objects 6175 if (!isConstructionTypeShaderObject(pipelineConstructionType)) 6176 { 6177 TestCaseGroupPtr minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading")); 6178 { 6179 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 6180 { 6181 const TestConfig& testConfig = testConfigs[configNdx]; 6182 6183 // minSampleShading is not supported by shader objects 6184 if (testConfig.minSampleShading != 1.0f && isConstructionTypeShaderObject(pipelineConstructionType)) 6185 continue; 6186 6187 TestCaseGroupPtr minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name)); 6188 6189 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6190 { 6191 std::ostringstream caseName; 6192 caseName << "samples_" << samples[samplesNdx]; 6193 6194 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6195 6196 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate)); 6197 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate)); 6198 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate)); 6199 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate)); 6200 #ifndef CTS_USES_VULKANSC 6201 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate)); 6202 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate)); 6203 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate)); 6204 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate)); 6205 #endif // CTS_USES_VULKANSC 6206 6207 minShadingValueTests->addChild(samplesTests.release()); 6208 } 6209 6210 minSampleShadingTests->addChild(minShadingValueTests.release()); 6211 } 6212 6213 multisampleTests->addChild(minSampleShadingTests.release()); 6214 } 6215 } 6216 6217 // Input attachments are not supported with dynamic rendering and shader objects 6218 if (!isConstructionTypeShaderObject(pipelineConstructionType)) 6219 { 6220 TestCaseGroupPtr minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled")); 6221 6222 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 6223 { 6224 const TestConfig& testConfig = testConfigs[configNdx]; 6225 TestCaseGroupPtr minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name)); 6226 6227 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6228 { 6229 std::ostringstream caseName; 6230 caseName << "samples_" << samples[samplesNdx]; 6231 6232 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6233 6234 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate)); 6235 6236 minShadingValueTests->addChild(samplesTests.release()); 6237 } 6238 6239 minSampleShadingTests->addChild(minShadingValueTests.release()); 6240 } 6241 6242 multisampleTests->addChild(minSampleShadingTests.release()); 6243 } 6244 6245 // Input attachments are not supported with dynamic rendering and shader objects 6246 if (!isConstructionTypeShaderObject(pipelineConstructionType)) 6247 { 6248 TestCaseGroupPtr minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled")); 6249 6250 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 6251 { 6252 const TestConfig& testConfig = testConfigs[configNdx]; 6253 TestCaseGroupPtr minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name)); 6254 6255 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6256 { 6257 std::ostringstream caseName; 6258 caseName << "samples_" << samples[samplesNdx]; 6259 6260 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6261 6262 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false, useFragmentShadingRate)); 6263 6264 minShadingValueTests->addChild(samplesTests.release()); 6265 } 6266 6267 minSampleShadingTests->addChild(minShadingValueTests.release()); 6268 } 6269 6270 multisampleTests->addChild(minSampleShadingTests.release()); 6271 } 6272 } 6273 6274 // SampleMask tests 6275 { 6276 struct TestConfig 6277 { 6278 const char* name; 6279 VkSampleMask sampleMask; 6280 }; 6281 6282 const TestConfig testConfigs[] = 6283 { 6284 // All mask bits are off 6285 { "mask_all_on",0x0 }, 6286 // All mask bits are on 6287 { "mask_all_off",0xFFFFFFFF }, 6288 // All mask elements are 0x1 6289 { "mask_one",0x1}, 6290 // All mask elements are 0xAAAAAAAA 6291 { "mask_random",0xAAAAAAAA }, 6292 }; 6293 6294 TestCaseGroupPtr sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask")); 6295 6296 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 6297 { 6298 const TestConfig& testConfig = testConfigs[configNdx]; 6299 TestCaseGroupPtr sampleMaskValueTests (new tcu::TestCaseGroup(testCtx, testConfig.name)); 6300 6301 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6302 { 6303 std::ostringstream caseName; 6304 caseName << "samples_" << samples[samplesNdx]; 6305 6306 const deUint32 sampleMaskCount = samples[samplesNdx] / 32; 6307 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6308 6309 std::vector<VkSampleMask> mask; 6310 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++) 6311 mask.push_back(testConfig.sampleMask); 6312 6313 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6314 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6315 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6316 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6317#ifndef CTS_USES_VULKANSC 6318 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6319 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6320 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6321 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6322#endif // CTS_USES_VULKANSC 6323 6324 sampleMaskValueTests->addChild(samplesTests.release()); 6325 } 6326 6327 sampleMaskTests->addChild(sampleMaskValueTests.release()); 6328 } 6329 6330 multisampleTests->addChild(sampleMaskTests.release()); 6331 6332 } 6333 6334 // AlphaToOne tests 6335 { 6336 const VkSampleCountFlagBits samplesForAlphaToOne[] = 6337 { 6338 VK_SAMPLE_COUNT_1_BIT, 6339 VK_SAMPLE_COUNT_2_BIT, 6340 VK_SAMPLE_COUNT_4_BIT, 6341 VK_SAMPLE_COUNT_8_BIT, 6342 VK_SAMPLE_COUNT_16_BIT, 6343 VK_SAMPLE_COUNT_32_BIT, 6344 VK_SAMPLE_COUNT_64_BIT 6345 }; 6346 TestCaseGroupPtr alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one")); 6347 6348 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samplesForAlphaToOne); samplesNdx++) 6349 { 6350 std::ostringstream caseName; 6351 caseName << "samples_" << samplesForAlphaToOne[samplesNdx]; 6352 6353 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6354#ifndef CTS_USES_VULKANSC 6355 caseName << "_sparse"; 6356 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6357#endif // CTS_USES_VULKANSC 6358 } 6359 6360 multisampleTests->addChild(alphaToOneTests.release()); 6361 } 6362 6363 // AlphaToCoverageEnable tests 6364 { 6365 TestCaseGroupPtr alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage")); 6366 6367 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6368 { 6369 std::ostringstream caseName; 6370 caseName << "samples_" << samples[samplesNdx]; 6371 6372 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6373 6374 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate, false)); 6375 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate, false)); 6376 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate, false)); 6377 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_check_depth", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate, true)); 6378#ifndef CTS_USES_VULKANSC 6379 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate, false)); 6380 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate, false)); 6381 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate, false)); 6382 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse_check_depth", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate, true)); 6383#endif // CTS_USES_VULKANSC 6384 6385 alphaToCoverageTests->addChild(samplesTests.release()); 6386 } 6387 multisampleTests->addChild(alphaToCoverageTests.release()); 6388 } 6389 6390 // AlphaToCoverageEnable without color buffer tests 6391 { 6392 TestCaseGroupPtr alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment")); 6393 6394 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6395 { 6396 std::ostringstream caseName; 6397 caseName << "samples_" << samples[samplesNdx]; 6398 6399 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6400 6401 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6402#ifndef CTS_USES_VULKANSC 6403 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6404#endif // CTS_USES_VULKANSC 6405 6406 alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release()); 6407 } 6408 multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release()); 6409 } 6410 6411 // AlphaToCoverageEnable with unused color attachment: 6412 // Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1. 6413 { 6414 TestCaseGroupPtr alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment")); 6415 6416 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 6417 { 6418 std::ostringstream caseName; 6419 caseName << "samples_" << samples[samplesNdx]; 6420 6421 TestCaseGroupPtr samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 6422 6423 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6424#ifndef CTS_USES_VULKANSC 6425 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6426#endif // CTS_USES_VULKANSC 6427 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate)); 6428#ifndef CTS_USES_VULKANSC 6429 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate)); 6430#endif // CTS_USES_VULKANSC 6431 6432 alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release()); 6433 } 6434 multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release()); 6435 } 6436 6437#ifndef CTS_USES_VULKANSC 6438 // not all tests need to be repeated for FSR 6439 if (useFragmentShadingRate == false) 6440 { 6441 // Sampling from a multisampled image texture (texelFetch) 6442 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx, pipelineConstructionType)); 6443 6444 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.) 6445 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx, pipelineConstructionType)); 6446 6447 // Sampling from a multisampled image texture (texelFetch), checking supersample positions 6448 multisampleTests->addChild(createMultisampleStandardSamplePositionTests(testCtx, pipelineConstructionType)); 6449 6450 // VK_AMD_shader_fragment_mask 6451 multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx, pipelineConstructionType)); 6452 6453 // Multisample resolve tests where a render area is less than an attachment size. 6454 multisampleTests->addChild(createMultisampleResolveRenderpassRenderAreaTests(testCtx, pipelineConstructionType)); 6455 6456 // VK_EXT_multisampled_render_to_single_sampled 6457 { 6458 multisampleTests->addChild(createMultisampledRenderToSingleSampledTests(testCtx, pipelineConstructionType)); 6459 // Take advantage of the code for this extension's tests to add some normal multisampling tests 6460 multisampleTests->addChild(createMultisampledMiscTests(testCtx, pipelineConstructionType)); 6461 } 6462 } 6463 6464 // VK_EXT_sample_locations 6465 multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx, pipelineConstructionType, useFragmentShadingRate)); 6466 6467 // VK_AMD_mixed_attachment 6468 multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx, pipelineConstructionType, useFragmentShadingRate)); 6469 6470 // Sample mask with and without vk_ext_post_depth_coverage 6471 { 6472 const vk::VkSampleCountFlagBits standardSamplesSet[] = 6473 { 6474 vk::VK_SAMPLE_COUNT_2_BIT, 6475 vk::VK_SAMPLE_COUNT_4_BIT, 6476 vk::VK_SAMPLE_COUNT_8_BIT, 6477 vk::VK_SAMPLE_COUNT_16_BIT 6478 }; 6479 6480 TestCaseGroupPtr sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test")); 6481 6482 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx) 6483 { 6484 std::ostringstream caseName; 6485 caseName << "samples_" << standardSamplesSet[ndx]; 6486 6487 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), pipelineConstructionType, standardSamplesSet[ndx], false, useFragmentShadingRate)); 6488 6489 caseName << "_post_depth_coverage"; 6490 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), pipelineConstructionType, standardSamplesSet[ndx], true, useFragmentShadingRate)); 6491 6492 } 6493 multisampleTests->addChild(sampleMaskWithDepthTestGroup.release()); 6494 } 6495#endif // CTS_USES_VULKANSC 6496 6497 // Input attachments are not supported with dynamic rendering and shader objects 6498 if (!isConstructionTypeShaderObject(pipelineConstructionType)) 6499 { 6500 //Conservative rasterization test 6501 struct TestConfig 6502 { 6503 const char* name; 6504 bool enableMinSampleShading; 6505 const float minSampleShading; 6506 const bool enableSampleMask; 6507 VkSampleMask sampleMask; 6508 bool enablePostDepthCoverage; 6509 }; 6510 6511 const TestConfig testConfigs[] = 6512 { 6513 // Only conservative rendering applied 6514 { "plain_conservative",false, 0.0f, false, 0x0, false }, 6515 // Post depth coverage enabled 6516 { "post_depth_coverage",false, 0.0f, false, 0x0, true }, 6517 // minSampleMask set to 0.25f 6518 { "min_0_25",true, 0.25f, false, 0x0, false }, 6519 // minSampleMask set to 0.5f 6520 { "min_0_5",true, 0.5f, false, 0x0, false }, 6521 // minSampleMask set to 0.75f 6522 { "min_0_75",true, 0.75f, false, 0x0, false }, 6523 // minSampleMask set to 1.0f 6524 { "min_0_1_0",true, 1.0f, false, 0x0, false }, 6525 // All mask bits are on 6526 { "mask_all_off",false, 0.0f, true, 0x0, false }, 6527 // All mask bits are off 6528 { "mask_all_on",false, 0.0f, true, 0xFFFFFFFF, false }, 6529 // All mask elements are 0xAAAAAAAA 6530 { "mask_half_on",false, 0.0f, true, 0xAAAAAAAA, false }, 6531 }; 6532 6533 const vk::VkSampleCountFlagBits standardSamplesSet[] = 6534 { 6535 vk::VK_SAMPLE_COUNT_2_BIT, 6536 vk::VK_SAMPLE_COUNT_4_BIT, 6537 vk::VK_SAMPLE_COUNT_8_BIT, 6538 vk::VK_SAMPLE_COUNT_16_BIT 6539 }; 6540 6541 enum vk::VkConservativeRasterizationModeEXT rasterizationMode[] = 6542 { 6543 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, 6544 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT 6545 }; 6546 6547 // Conservative rendering 6548 TestCaseGroupPtr conservativeGroup(new tcu::TestCaseGroup(testCtx, "conservative_with_full_coverage")); 6549 6550 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(rasterizationMode); ++modeNdx) 6551 { 6552 const char* modeName = (modeNdx == 0 ? "overestimate" : "underestimate"); 6553 TestCaseGroupPtr modesGroup (new tcu::TestCaseGroup(testCtx, modeName)); 6554 6555 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++samplesNdx) 6556 { 6557 std::string caseName = "samples_" + std::to_string(standardSamplesSet[samplesNdx]) + "_"; 6558 6559 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 6560 { 6561 const TestConfig& testConfig = testConfigs[configNdx]; 6562 6563 modesGroup->addChild(new SampleMaskWithConservativeTest(testCtx, caseName + testConfig.name, pipelineConstructionType, standardSamplesSet[samplesNdx], 6564 rasterizationMode[modeNdx], testConfig.enableMinSampleShading, testConfig.minSampleShading, testConfig.enableSampleMask, 6565 testConfig.sampleMask, testConfig.enablePostDepthCoverage, useFragmentShadingRate)); 6566 } 6567 6568 } 6569 6570 conservativeGroup->addChild(modesGroup.release()); 6571 } 6572 6573 multisampleTests->addChild(conservativeGroup.release()); 6574 } 6575 6576 { 6577 static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts = 6578 { 6579 vk::VK_SAMPLE_COUNT_1_BIT, 6580 vk::VK_SAMPLE_COUNT_2_BIT, 6581 vk::VK_SAMPLE_COUNT_4_BIT, 6582 vk::VK_SAMPLE_COUNT_8_BIT, 6583 vk::VK_SAMPLE_COUNT_16_BIT, 6584 vk::VK_SAMPLE_COUNT_32_BIT, 6585 vk::VK_SAMPLE_COUNT_64_BIT, 6586 }; 6587 6588 6589 static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }}; 6590 6591 { 6592 // Tests for multisample variable rate in subpasses 6593 TestCaseGroupPtr variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate")); 6594 6595 // 2 and 3 subpasses should be good enough. 6596 static const std::vector<size_t> combinationSizes = { 2, 3 }; 6597 6598 // Basic cases. 6599 for (const auto size : combinationSizes) 6600 { 6601 const auto combs = combinations(kSampleCounts, size); 6602 for (const auto& comb : combs) 6603 { 6604 // Check sample counts actually vary between some of the subpasses. 6605 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb)); 6606 if (uniqueVals.size() < 2) 6607 continue; 6608 6609 std::ostringstream name; 6610 6611 bool first = true; 6612 for (const auto& count : comb) 6613 { 6614 name << (first ? "" : "_") << count; 6615 first = false; 6616 } 6617 6618 const VariableRateTestCase::TestParams params = 6619 { 6620 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType; 6621 false, // bool nonEmptyFramebuffer; 6622 vk::VK_SAMPLE_COUNT_1_BIT, // vk::VkSampleCountFlagBits fbCount; 6623 false, // bool unusedAttachment; 6624 comb, // SampleCounts subpassCounts; 6625 useFragmentShadingRate, // bool useFragmentShadingRate; 6626 }; 6627 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), params)); 6628 } 6629 } 6630 6631 // Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations. 6632 { 6633 // Use one more sample count for the framebuffer attachment. It will be taken from the last item. 6634 auto combs = combinations(kSampleCounts, 2 + 1); 6635 for (auto& comb : combs) 6636 { 6637 // Framebuffer sample count. 6638 const auto fbCount = comb.back(); 6639 comb.pop_back(); 6640 6641 // Check sample counts actually vary between some of the subpasses. 6642 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb)); 6643 if (uniqueVals.size() < 2) 6644 continue; 6645 6646 for (const auto flag : unusedAttachmentFlag) 6647 { 6648 std::ostringstream name; 6649 6650 bool first = true; 6651 for (const auto& count : comb) 6652 { 6653 name << (first ? "" : "_") << count; 6654 first = false; 6655 } 6656 6657 name << "_fb_" << fbCount; 6658 6659 if (flag) 6660 { 6661 name << "_unused"; 6662 } 6663 6664 const VariableRateTestCase::TestParams params = 6665 { 6666 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType; 6667 true, // bool nonEmptyFramebuffer; 6668 fbCount, // vk::VkSampleCountFlagBits fbCount; 6669 flag, // bool unusedAttachment; 6670 comb, // SampleCounts subpassCounts; 6671 useFragmentShadingRate, // bool useFragmentShadingRate; 6672 }; 6673 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), params)); 6674 } 6675 } 6676 } 6677 6678 multisampleTests->addChild(variableRateGroup.release()); 6679 } 6680 6681 { 6682 TestCaseGroupPtr mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer")); 6683 6684 const auto combs = combinations(kSampleCounts, 2); 6685 for (const auto& comb : combs) 6686 { 6687 // Check different sample count. 6688 DE_ASSERT(comb.size() == 2u); 6689 const auto& fbCount = comb[0]; 6690 const auto& emptyCount = comb[1]; 6691 6692 if (fbCount == emptyCount) 6693 continue; 6694 6695 const std::string fbCountStr = de::toString(fbCount); 6696 const std::string emptyCountStr = de::toString(emptyCount); 6697 6698 for (const auto flag : unusedAttachmentFlag) 6699 { 6700 const std::string nameSuffix = (flag ? "unused" : ""); 6701 const std::string descSuffix = (flag ? "one unused attachment reference" : "no attachment references"); 6702 const std::string name = fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix; 6703 6704 const VariableRateTestCase::TestParams params 6705 { 6706 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType; 6707 true, // bool nonEmptyFramebuffer; 6708 fbCount, // vk::VkSampleCountFlagBits fbCount; 6709 flag, // bool unusedAttachment; 6710 VariableRateTestCase::SampleCounts(1u, emptyCount), // SampleCounts subpassCounts; 6711 useFragmentShadingRate, // bool useFragmentShadingRate; 6712 }; 6713 mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, params)); 6714 } 6715 } 6716 6717 multisampleTests->addChild(mixedCountGroup.release()); 6718 } 6719 6720 if (!useFragmentShadingRate) 6721 { 6722 // Tests using alpha to coverage combined with depth/stencil/mask writes in the frag shader 6723 TestCaseGroupPtr zExportGroup (new tcu::TestCaseGroup(testCtx, "z_export")); 6724 6725 const struct 6726 { 6727 ZExportFlags flags; 6728 const char* name; 6729 } flagsCases[] = 6730 { 6731 { (ZEXP_DEPTH_BIT), "depth" }, 6732 { (ZEXP_STENCIL_BIT), "stencil" }, 6733 { (ZEXP_SAMPLE_MASK_BIT), "sample_mask" }, 6734 { (ZEXP_DEPTH_BIT | ZEXP_STENCIL_BIT | ZEXP_SAMPLE_MASK_BIT), "write_all" }, 6735 }; 6736 6737 for (const auto& flagsCase : flagsCases) 6738 { 6739 for (int i = 0; i < 2; ++i) 6740 { 6741 const bool dynamicAlphaToCoverage = (i > 0); 6742 6743#ifdef CTS_USES_VULKANSC 6744 if (dynamicAlphaToCoverage) 6745 continue; 6746#endif // CTS_USES_VULKANSC 6747 6748 const auto testName = std::string(flagsCase.name) + "_" + (dynamicAlphaToCoverage ? "dynamic" : "static") + "_atc"; // atc = alpha to coverage 6749 const ZExportParams params (pipelineConstructionType, flagsCase.flags, dynamicAlphaToCoverage); 6750 6751 addFunctionCaseWithPrograms(zExportGroup.get(), testName, ZExportCheckSupport, ZExportInitPrograms, ZExportIterate, params); 6752 } 6753 } 6754 6755 multisampleTests->addChild(zExportGroup.release()); 6756 } 6757 } 6758 6759 return multisampleTests.release(); 6760} 6761 6762} // pipeline 6763} // vkt 6764