1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies Ltd. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Multisample Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktPipelineMultisampleTests.hpp" 26 #include "vktPipelineMultisampleImageTests.hpp" 27 #include "vktPipelineClearUtil.hpp" 28 #include "vktPipelineImageUtil.hpp" 29 #include "vktPipelineVertexUtil.hpp" 30 #include "vktPipelineReferenceRenderer.hpp" 31 #include "vktTestCase.hpp" 32 #include "vktTestCaseUtil.hpp" 33 #include "vkImageUtil.hpp" 34 #include "vkMemUtil.hpp" 35 #include "vkPrograms.hpp" 36 #include "vkQueryUtil.hpp" 37 #include "vkRef.hpp" 38 #include "vkRefUtil.hpp" 39 #include "tcuImageCompare.hpp" 40 #include "tcuTestLog.hpp" 41 #include "deUniquePtr.hpp" 42 #include "deSharedPtr.hpp" 43 #include "deStringUtil.hpp" 44 #include "deMemory.h" 45 46 #include <sstream> 47 #include <vector> 48 #include <map> 49 50 namespace vkt 51 { 52 namespace pipeline 53 { 54 55 using namespace vk; 56 57 namespace 58 { 59 enum GeometryType 60 { 61 GEOMETRY_TYPE_OPAQUE_TRIANGLE, 62 GEOMETRY_TYPE_OPAQUE_LINE, 63 GEOMETRY_TYPE_OPAQUE_POINT, 64 GEOMETRY_TYPE_OPAQUE_QUAD, 65 GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH, //!< placed at z = 0.5 66 GEOMETRY_TYPE_TRANSLUCENT_QUAD, 67 GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 68 GEOMETRY_TYPE_INVISIBLE_QUAD, 69 GEOMETRY_TYPE_GRADIENT_QUAD 70 }; 71 72 enum TestModeBits 73 { 74 TEST_MODE_DEPTH_BIT = 1u, 75 TEST_MODE_STENCIL_BIT = 2u, 76 }; 77 typedef deUint32 TestModeFlags; 78 79 enum RenderType 80 { 81 // resolve multisample rendering to single sampled image 82 RENDER_TYPE_RESOLVE = 0u, 83 84 // copy samples to an array of single sampled images 85 RENDER_TYPE_COPY_SAMPLES 86 }; 87 88 void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType); 89 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples); 90 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format); 91 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void); 92 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image); 93 VkImageAspectFlags getImageAspectFlags (const VkFormat format); 94 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType); 95 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType); 96 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil); 97 98 class MultisampleTest : public vkt::TestCase 99 { 100 public: 101 102 MultisampleTest (tcu::TestContext& testContext, 103 const std::string& name, 104 const std::string& description, 105 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 106 const VkPipelineColorBlendAttachmentState& blendState, 107 GeometryType geometryType); 108 virtual ~MultisampleTest (void) {} 109 110 virtual void initPrograms (SourceCollections& programCollection) const; 111 virtual TestInstance* createInstance (Context& context) const; 112 113 protected: 114 virtual TestInstance* createMultisampleTestInstance (Context& context, 115 VkPrimitiveTopology topology, 116 const std::vector<Vertex4RGBA>& vertices, 117 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 118 const VkPipelineColorBlendAttachmentState& colorBlendState) const = 0; 119 VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 120 const VkPipelineColorBlendAttachmentState m_colorBlendState; 121 const GeometryType m_geometryType; 122 std::vector<VkSampleMask> m_sampleMask; 123 }; 124 125 class RasterizationSamplesTest : public MultisampleTest 126 { 127 public: 128 RasterizationSamplesTest (tcu::TestContext& testContext, 129 const std::string& name, 130 const std::string& description, 131 VkSampleCountFlagBits rasterizationSamples, 132 GeometryType geometryType, 133 TestModeFlags modeFlags = 0u); 134 virtual ~RasterizationSamplesTest (void) {} 135 136 protected: 137 virtual TestInstance* createMultisampleTestInstance (Context& context, 138 VkPrimitiveTopology topology, 139 const std::vector<Vertex4RGBA>& vertices, 140 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 141 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 142 143 static VkPipelineMultisampleStateCreateInfo getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples); 144 145 const TestModeFlags m_modeFlags; 146 }; 147 148 class MinSampleShadingTest : public MultisampleTest 149 { 150 public: 151 MinSampleShadingTest (tcu::TestContext& testContext, 152 const std::string& name, 153 const std::string& description, 154 VkSampleCountFlagBits rasterizationSamples, 155 float minSampleShading, 156 GeometryType geometryType); 157 virtual ~MinSampleShadingTest (void) {} 158 159 protected: 160 virtual void initPrograms (SourceCollections& programCollection) const; 161 virtual TestInstance* createMultisampleTestInstance (Context& context, 162 VkPrimitiveTopology topology, 163 const std::vector<Vertex4RGBA>& vertices, 164 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 165 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 166 167 static VkPipelineMultisampleStateCreateInfo getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading); 168 }; 169 170 class SampleMaskTest : public MultisampleTest 171 { 172 public: 173 SampleMaskTest (tcu::TestContext& testContext, 174 const std::string& name, 175 const std::string& description, 176 VkSampleCountFlagBits rasterizationSamples, 177 const std::vector<VkSampleMask>& sampleMask, 178 GeometryType geometryType); 179 180 virtual ~SampleMaskTest (void) {} 181 182 protected: 183 virtual TestInstance* createMultisampleTestInstance (Context& context, 184 VkPrimitiveTopology topology, 185 const std::vector<Vertex4RGBA>& vertices, 186 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 187 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 188 189 static VkPipelineMultisampleStateCreateInfo getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask); 190 }; 191 192 class AlphaToOneTest : public MultisampleTest 193 { 194 public: 195 AlphaToOneTest (tcu::TestContext& testContext, 196 const std::string& name, 197 const std::string& description, 198 VkSampleCountFlagBits rasterizationSamples); 199 200 virtual ~AlphaToOneTest (void) {} 201 202 protected: 203 virtual TestInstance* createMultisampleTestInstance (Context& context, 204 VkPrimitiveTopology topology, 205 const std::vector<Vertex4RGBA>& vertices, 206 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 207 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 208 209 static VkPipelineMultisampleStateCreateInfo getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples); 210 static VkPipelineColorBlendAttachmentState getAlphaToOneBlendState (void); 211 }; 212 213 class AlphaToCoverageTest : public MultisampleTest 214 { 215 public: 216 AlphaToCoverageTest (tcu::TestContext& testContext, 217 const std::string& name, 218 const std::string& description, 219 VkSampleCountFlagBits rasterizationSamples, 220 GeometryType geometryType); 221 222 virtual ~AlphaToCoverageTest (void) {} 223 224 protected: 225 virtual TestInstance* createMultisampleTestInstance (Context& context, 226 VkPrimitiveTopology topology, 227 const std::vector<Vertex4RGBA>& vertices, 228 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 229 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 230 231 static VkPipelineMultisampleStateCreateInfo getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples); 232 233 GeometryType m_geometryType; 234 }; 235 236 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp; 237 238 class MultisampleRenderer 239 { 240 public: 241 MultisampleRenderer (Context& context, 242 const VkFormat colorFormat, 243 const tcu::IVec2& renderSize, 244 const VkPrimitiveTopology topology, 245 const std::vector<Vertex4RGBA>& vertices, 246 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 247 const VkPipelineColorBlendAttachmentState& blendState, 248 const RenderType renderType); 249 250 MultisampleRenderer (Context& context, 251 const VkFormat colorFormat, 252 const VkFormat depthStencilFormat, 253 const tcu::IVec2& renderSize, 254 const bool useDepth, 255 const bool useStencil, 256 const deUint32 numTopologies, 257 const VkPrimitiveTopology* pTopology, 258 const std::vector<Vertex4RGBA>* pVertices, 259 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 260 const VkPipelineColorBlendAttachmentState& blendState, 261 const RenderType renderType); 262 263 virtual ~MultisampleRenderer (void); 264 265 de::MovePtr<tcu::TextureLevel> render (void); 266 de::MovePtr<tcu::TextureLevel> getSingleSampledImage (deUint32 sampleId); 267 268 protected: 269 void initialize (Context& context, 270 const deUint32 numTopologies, 271 const VkPrimitiveTopology* pTopology, 272 const std::vector<Vertex4RGBA>* pVertices); 273 274 Context& m_context; 275 276 const VkFormat m_colorFormat; 277 const VkFormat m_depthStencilFormat; 278 tcu::IVec2 m_renderSize; 279 const bool m_useDepth; 280 const bool m_useStencil; 281 282 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 283 const VkPipelineColorBlendAttachmentState m_colorBlendState; 284 285 const RenderType m_renderType; 286 287 Move<VkImage> m_colorImage; 288 de::MovePtr<Allocation> m_colorImageAlloc; 289 Move<VkImageView> m_colorAttachmentView; 290 291 Move<VkImage> m_resolveImage; 292 de::MovePtr<Allocation> m_resolveImageAlloc; 293 Move<VkImageView> m_resolveAttachmentView; 294 295 struct PerSampleImage 296 { 297 Move<VkImage> m_image; 298 de::MovePtr<Allocation> m_imageAlloc; 299 Move<VkImageView> m_attachmentView; 300 }; 301 std::vector<de::SharedPtr<PerSampleImage> > m_perSampleImages; 302 303 Move<VkImage> m_depthStencilImage; 304 de::MovePtr<Allocation> m_depthStencilImageAlloc; 305 Move<VkImageView> m_depthStencilAttachmentView; 306 307 Move<VkRenderPass> m_renderPass; 308 Move<VkFramebuffer> m_framebuffer; 309 310 Move<VkShaderModule> m_vertexShaderModule; 311 Move<VkShaderModule> m_fragmentShaderModule; 312 313 Move<VkShaderModule> m_copySampleVertexShaderModule; 314 Move<VkShaderModule> m_copySampleFragmentShaderModule; 315 316 Move<VkBuffer> m_vertexBuffer; 317 de::MovePtr<Allocation> m_vertexBufferAlloc; 318 319 Move<VkPipelineLayout> m_pipelineLayout; 320 std::vector<VkPipelineSp> m_graphicsPipelines; 321 322 Move<VkDescriptorSetLayout> m_copySampleDesciptorLayout; 323 Move<VkDescriptorPool> m_copySampleDesciptorPool; 324 Move<VkDescriptorSet> m_copySampleDesciptorSet; 325 326 Move<VkPipelineLayout> m_copySamplePipelineLayout; 327 std::vector<VkPipelineSp> m_copySamplePipelines; 328 329 Move<VkCommandPool> m_cmdPool; 330 Move<VkCommandBuffer> m_cmdBuffer; 331 332 Move<VkFence> m_fence; 333 }; 334 335 class RasterizationSamplesInstance : public vkt::TestInstance 336 { 337 public: 338 RasterizationSamplesInstance (Context& context, 339 VkPrimitiveTopology topology, 340 const std::vector<Vertex4RGBA>& vertices, 341 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 342 const VkPipelineColorBlendAttachmentState& blendState, 343 const TestModeFlags modeFlags); 344 virtual ~RasterizationSamplesInstance (void) {} 345 346 virtual tcu::TestStatus iterate (void); 347 348 protected: 349 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 350 351 const VkFormat m_colorFormat; 352 const tcu::IVec2 m_renderSize; 353 const VkPrimitiveTopology m_primitiveTopology; 354 const std::vector<Vertex4RGBA> m_vertices; 355 const std::vector<Vertex4RGBA> m_fullQuadVertices; //!< used by depth/stencil case 356 const TestModeFlags m_modeFlags; 357 de::MovePtr<MultisampleRenderer> m_multisampleRenderer; 358 }; 359 360 class MinSampleShadingInstance : public vkt::TestInstance 361 { 362 public: 363 MinSampleShadingInstance (Context& context, 364 VkPrimitiveTopology topology, 365 const std::vector<Vertex4RGBA>& vertices, 366 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 367 const VkPipelineColorBlendAttachmentState& blendState); 368 virtual ~MinSampleShadingInstance (void) {} 369 370 virtual tcu::TestStatus iterate (void); 371 372 protected: 373 virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& testShadingImages, 374 const tcu::ConstPixelBufferAccess& noSampleshadingImage); 375 376 const VkFormat m_colorFormat; 377 const tcu::IVec2 m_renderSize; 378 const VkPrimitiveTopology m_primitiveTopology; 379 const std::vector<Vertex4RGBA> m_vertices; 380 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 381 const VkPipelineColorBlendAttachmentState m_colorBlendState; 382 }; 383 384 class SampleMaskInstance : public vkt::TestInstance 385 { 386 public: 387 SampleMaskInstance (Context& context, 388 VkPrimitiveTopology topology, 389 const std::vector<Vertex4RGBA>& vertices, 390 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 391 const VkPipelineColorBlendAttachmentState& blendState); 392 virtual ~SampleMaskInstance (void) {} 393 394 virtual tcu::TestStatus iterate (void); 395 396 protected: 397 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, 398 const tcu::ConstPixelBufferAccess& minShadingImage, 399 const tcu::ConstPixelBufferAccess& maxShadingImage); 400 const VkFormat m_colorFormat; 401 const tcu::IVec2 m_renderSize; 402 const VkPrimitiveTopology m_primitiveTopology; 403 const std::vector<Vertex4RGBA> m_vertices; 404 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 405 const VkPipelineColorBlendAttachmentState m_colorBlendState; 406 }; 407 408 class AlphaToOneInstance : public vkt::TestInstance 409 { 410 public: 411 AlphaToOneInstance (Context& context, 412 VkPrimitiveTopology topology, 413 const std::vector<Vertex4RGBA>& vertices, 414 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 415 const VkPipelineColorBlendAttachmentState& blendState); 416 virtual ~AlphaToOneInstance (void) {} 417 418 virtual tcu::TestStatus iterate (void); 419 420 protected: 421 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 422 const tcu::ConstPixelBufferAccess& noAlphaOneImage); 423 const VkFormat m_colorFormat; 424 const tcu::IVec2 m_renderSize; 425 const VkPrimitiveTopology m_primitiveTopology; 426 const std::vector<Vertex4RGBA> m_vertices; 427 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 428 const VkPipelineColorBlendAttachmentState m_colorBlendState; 429 }; 430 431 class AlphaToCoverageInstance : public vkt::TestInstance 432 { 433 public: 434 AlphaToCoverageInstance (Context& context, 435 VkPrimitiveTopology topology, 436 const std::vector<Vertex4RGBA>& vertices, 437 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 438 const VkPipelineColorBlendAttachmentState& blendState, 439 GeometryType geometryType); 440 virtual ~AlphaToCoverageInstance (void) {} 441 442 virtual tcu::TestStatus iterate (void); 443 444 protected: 445 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 446 const VkFormat m_colorFormat; 447 const tcu::IVec2 m_renderSize; 448 const VkPrimitiveTopology m_primitiveTopology; 449 const std::vector<Vertex4RGBA> m_vertices; 450 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 451 const VkPipelineColorBlendAttachmentState m_colorBlendState; 452 const GeometryType m_geometryType; 453 }; 454 455 456 // Helper functions 457 458 void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType) 459 { 460 std::ostringstream vertexSource; 461 462 vertexSource << 463 "#version 310 es\n" 464 "layout(location = 0) in vec4 position;\n" 465 "layout(location = 1) in vec4 color;\n" 466 "layout(location = 0) out highp vec4 vtxColor;\n" 467 "void main (void)\n" 468 "{\n" 469 " gl_Position = position;\n" 470 " vtxColor = color;\n" 471 << (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? " gl_PointSize = 3.0f;\n" 472 : "") 473 << "}\n"; 474 475 static const char* fragmentSource = 476 "#version 310 es\n" 477 "layout(location = 0) in highp vec4 vtxColor;\n" 478 "layout(location = 0) out highp vec4 fragColor;\n" 479 "void main (void)\n" 480 "{\n" 481 " fragColor = vtxColor;\n" 482 "}\n"; 483 484 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 485 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); 486 } 487 488 void initSampleShadingPrograms (SourceCollections& sources, GeometryType geometryType) 489 { 490 { 491 std::ostringstream vertexSource; 492 493 vertexSource << 494 "#version 440\n" 495 "layout(location = 0) in vec4 position;\n" 496 "layout(location = 1) in vec4 color;\n" 497 "void main (void)\n" 498 "{\n" 499 " gl_Position = position;\n" 500 << (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? " gl_PointSize = 3.0f;\n" 501 : "") 502 << "}\n"; 503 504 static const char* fragmentSource = 505 "#version 440\n" 506 "layout(location = 0) out highp vec4 fragColor;\n" 507 "void main (void)\n" 508 "{\n" 509 " fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n" 510 "}\n"; 511 512 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 513 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); 514 } 515 516 { 517 static const char* vertexSource = 518 "#version 440\n" 519 "void main (void)\n" 520 "{\n" 521 " const vec4 positions[4] = vec4[4](\n" 522 " vec4(-1.0, -1.0, 0.0, 1.0),\n" 523 " vec4(-1.0, 1.0, 0.0, 1.0),\n" 524 " vec4( 1.0, -1.0, 0.0, 1.0),\n" 525 " vec4( 1.0, 1.0, 0.0, 1.0)\n" 526 " );\n" 527 " gl_Position = positions[gl_VertexIndex];\n" 528 "}\n"; 529 530 static const char* fragmentSource = 531 "#version 440\n" 532 "precision highp float;\n" 533 "layout(location = 0) out highp vec4 fragColor;\n" 534 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n" 535 "layout(push_constant) uniform PushConstantsBlock\n" 536 "{\n" 537 " int sampleId;\n" 538 "} pushConstants;\n" 539 "void main (void)\n" 540 "{\n" 541 " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n" 542 "}\n"; 543 544 sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource); 545 sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource); 546 } 547 } 548 549 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples) 550 { 551 VkPhysicalDeviceProperties deviceProperties; 552 553 instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties); 554 555 return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples); 556 } 557 558 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void) 559 { 560 const VkPipelineColorBlendAttachmentState colorBlendState = 561 { 562 false, // VkBool32 blendEnable; 563 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 564 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 565 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 566 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 567 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 568 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 569 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 570 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 571 }; 572 573 return colorBlendState; 574 } 575 576 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image) 577 { 578 DE_ASSERT(image.getFormat().getPixelSize() == 4); 579 580 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> 581 const deUint32 pixelCount = image.getWidth() * image.getHeight() * image.getDepth(); 582 583 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) 584 { 585 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx); 586 587 if (histogram.find(pixelValue) != histogram.end()) 588 histogram[pixelValue]++; 589 else 590 histogram[pixelValue] = 1; 591 } 592 593 return (deUint32)histogram.size(); 594 } 595 596 VkImageAspectFlags getImageAspectFlags (const VkFormat format) 597 { 598 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 599 600 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 601 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; 602 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; 603 604 DE_ASSERT(false); 605 return 0u; 606 } 607 608 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType) 609 { 610 std::vector<Vertex4RGBA> vertices; 611 612 switch (geometryType) 613 { 614 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 615 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: 616 { 617 Vertex4RGBA vertexData[3] = 618 { 619 { 620 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 621 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 622 }, 623 { 624 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 625 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 626 }, 627 { 628 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 629 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 630 } 631 }; 632 633 if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE) 634 { 635 for (int i = 0; i < 3; i++) 636 vertexData[i].color = tcu::Vec4(); 637 } 638 639 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3); 640 break; 641 } 642 643 case GEOMETRY_TYPE_OPAQUE_LINE: 644 { 645 const Vertex4RGBA vertexData[2] = 646 { 647 { 648 tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f), 649 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 650 }, 651 { 652 tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f), 653 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 654 } 655 }; 656 657 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2); 658 break; 659 } 660 661 case GEOMETRY_TYPE_OPAQUE_POINT: 662 { 663 const Vertex4RGBA vertex = 664 { 665 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 666 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 667 }; 668 669 vertices = std::vector<Vertex4RGBA>(1, vertex); 670 break; 671 } 672 673 case GEOMETRY_TYPE_OPAQUE_QUAD: 674 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 675 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 676 case GEOMETRY_TYPE_INVISIBLE_QUAD: 677 case GEOMETRY_TYPE_GRADIENT_QUAD: 678 { 679 Vertex4RGBA vertexData[4] = 680 { 681 { 682 tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), 683 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 684 }, 685 { 686 tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), 687 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 688 }, 689 { 690 tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), 691 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 692 }, 693 { 694 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), 695 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 696 } 697 }; 698 699 if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD) 700 { 701 for (int i = 0; i < 4; i++) 702 vertexData[i].color.w() = 0.25f; 703 } 704 else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD) 705 { 706 for (int i = 0; i < 4; i++) 707 vertexData[i].color.w() = 0.0f; 708 } 709 else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD) 710 { 711 vertexData[0].color.w() = 0.0f; 712 vertexData[2].color.w() = 0.0f; 713 } 714 else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH) 715 { 716 for (int i = 0; i < 4; i++) 717 vertexData[i].position.z() = 0.5f; 718 } 719 720 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4); 721 break; 722 } 723 724 default: 725 DE_ASSERT(false); 726 } 727 return vertices; 728 } 729 730 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType) 731 { 732 switch (geometryType) 733 { 734 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 735 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 736 737 case GEOMETRY_TYPE_OPAQUE_LINE: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 738 case GEOMETRY_TYPE_OPAQUE_POINT: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 739 740 case GEOMETRY_TYPE_OPAQUE_QUAD: 741 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 742 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 743 case GEOMETRY_TYPE_INVISIBLE_QUAD: 744 case GEOMETRY_TYPE_GRADIENT_QUAD: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 745 746 default: 747 DE_ASSERT(false); 748 return VK_PRIMITIVE_TOPOLOGY_LAST; 749 } 750 } 751 752 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format) 753 { 754 VkFormatProperties formatProps; 755 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps); 756 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; 757 } 758 759 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil) 760 { 761 if (useDepth && !useStencil) 762 return VK_FORMAT_D16_UNORM; // must be supported 763 764 const InstanceInterface& vki = context.getInstanceInterface(); 765 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 766 767 // One of these formats must be supported. 768 769 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT)) 770 return VK_FORMAT_D24_UNORM_S8_UINT; 771 772 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT)) 773 return VK_FORMAT_D32_SFLOAT_S8_UINT; 774 775 return VK_FORMAT_UNDEFINED; 776 } 777 778 779 // MultisampleTest 780 781 MultisampleTest::MultisampleTest (tcu::TestContext& testContext, 782 const std::string& name, 783 const std::string& description, 784 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 785 const VkPipelineColorBlendAttachmentState& blendState, 786 GeometryType geometryType) 787 : vkt::TestCase (testContext, name, description) 788 , m_multisampleStateParams (multisampleStateParams) 789 , m_colorBlendState (blendState) 790 , m_geometryType (geometryType) 791 { 792 if (m_multisampleStateParams.pSampleMask) 793 { 794 // Copy pSampleMask to avoid dependencies with other classes 795 796 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32); 797 798 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++) 799 m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]); 800 801 m_multisampleStateParams.pSampleMask = m_sampleMask.data(); 802 } 803 } 804 805 void MultisampleTest::initPrograms (SourceCollections& programCollection) const 806 { 807 initMultisamplePrograms(programCollection, m_geometryType); 808 } 809 810 TestInstance* MultisampleTest::createInstance (Context& context) const 811 { 812 return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState); 813 } 814 815 816 // RasterizationSamplesTest 817 818 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext& testContext, 819 const std::string& name, 820 const std::string& description, 821 VkSampleCountFlagBits rasterizationSamples, 822 GeometryType geometryType, 823 TestModeFlags modeFlags) 824 : MultisampleTest (testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType) 825 , m_modeFlags (modeFlags) 826 { 827 } 828 829 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples) 830 { 831 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 832 { 833 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 834 DE_NULL, // const void* pNext; 835 0u, // VkPipelineMultisampleStateCreateFlags flags; 836 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 837 false, // VkBool32 sampleShadingEnable; 838 0.0f, // float minSampleShading; 839 DE_NULL, // const VkSampleMask* pSampleMask; 840 false, // VkBool32 alphaToCoverageEnable; 841 false // VkBool32 alphaToOneEnable; 842 }; 843 844 return multisampleStateParams; 845 } 846 847 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context& context, 848 VkPrimitiveTopology topology, 849 const std::vector<Vertex4RGBA>& vertices, 850 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 851 const VkPipelineColorBlendAttachmentState& colorBlendState) const 852 { 853 return new RasterizationSamplesInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_modeFlags); 854 } 855 856 857 // MinSampleShadingTest 858 859 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext& testContext, 860 const std::string& name, 861 const std::string& description, 862 VkSampleCountFlagBits rasterizationSamples, 863 float minSampleShading, 864 GeometryType geometryType) 865 : MultisampleTest (testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType) 866 { 867 } 868 869 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const 870 { 871 initSampleShadingPrograms(programCollection, m_geometryType); 872 } 873 874 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context, 875 VkPrimitiveTopology topology, 876 const std::vector<Vertex4RGBA>& vertices, 877 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 878 const VkPipelineColorBlendAttachmentState& colorBlendState) const 879 { 880 return new MinSampleShadingInstance(context, topology, vertices, multisampleStateParams, colorBlendState); 881 } 882 883 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading) 884 { 885 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 886 { 887 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 888 DE_NULL, // const void* pNext; 889 0u, // VkPipelineMultisampleStateCreateFlags flags; 890 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 891 true, // VkBool32 sampleShadingEnable; 892 minSampleShading, // float minSampleShading; 893 DE_NULL, // const VkSampleMask* pSampleMask; 894 false, // VkBool32 alphaToCoverageEnable; 895 false // VkBool32 alphaToOneEnable; 896 }; 897 898 return multisampleStateParams; 899 } 900 901 902 // SampleMaskTest 903 904 SampleMaskTest::SampleMaskTest (tcu::TestContext& testContext, 905 const std::string& name, 906 const std::string& description, 907 VkSampleCountFlagBits rasterizationSamples, 908 const std::vector<VkSampleMask>& sampleMask, 909 GeometryType geometryType) 910 : MultisampleTest (testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType) 911 { 912 } 913 914 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context& context, 915 VkPrimitiveTopology topology, 916 const std::vector<Vertex4RGBA>& vertices, 917 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 918 const VkPipelineColorBlendAttachmentState& colorBlendState) const 919 { 920 return new SampleMaskInstance(context, topology,vertices, multisampleStateParams, colorBlendState); 921 } 922 923 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask) 924 { 925 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 926 { 927 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 928 DE_NULL, // const void* pNext; 929 0u, // VkPipelineMultisampleStateCreateFlags flags; 930 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 931 false, // VkBool32 sampleShadingEnable; 932 0.0f, // float minSampleShading; 933 sampleMask.data(), // const VkSampleMask* pSampleMask; 934 false, // VkBool32 alphaToCoverageEnable; 935 false // VkBool32 alphaToOneEnable; 936 }; 937 938 return multisampleStateParams; 939 } 940 941 942 // AlphaToOneTest 943 944 AlphaToOneTest::AlphaToOneTest (tcu::TestContext& testContext, 945 const std::string& name, 946 const std::string& description, 947 VkSampleCountFlagBits rasterizationSamples) 948 : MultisampleTest (testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD) 949 { 950 } 951 952 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context& context, 953 VkPrimitiveTopology topology, 954 const std::vector<Vertex4RGBA>& vertices, 955 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 956 const VkPipelineColorBlendAttachmentState& colorBlendState) const 957 { 958 return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState); 959 } 960 961 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples) 962 { 963 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 964 { 965 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 966 DE_NULL, // const void* pNext; 967 0u, // VkPipelineMultisampleStateCreateFlags flags; 968 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 969 false, // VkBool32 sampleShadingEnable; 970 0.0f, // float minSampleShading; 971 DE_NULL, // const VkSampleMask* pSampleMask; 972 false, // VkBool32 alphaToCoverageEnable; 973 true // VkBool32 alphaToOneEnable; 974 }; 975 976 return multisampleStateParams; 977 } 978 979 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void) 980 { 981 const VkPipelineColorBlendAttachmentState colorBlendState = 982 { 983 true, // VkBool32 blendEnable; 984 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 985 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 986 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 987 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 988 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor; 989 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 990 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 991 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 992 }; 993 994 return colorBlendState; 995 } 996 997 998 // AlphaToCoverageTest 999 1000 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext& testContext, 1001 const std::string& name, 1002 const std::string& description, 1003 VkSampleCountFlagBits rasterizationSamples, 1004 GeometryType geometryType) 1005 : MultisampleTest (testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType) 1006 , m_geometryType (geometryType) 1007 { 1008 } 1009 1010 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context& context, 1011 VkPrimitiveTopology topology, 1012 const std::vector<Vertex4RGBA>& vertices, 1013 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1014 const VkPipelineColorBlendAttachmentState& colorBlendState) const 1015 { 1016 return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType); 1017 } 1018 1019 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples) 1020 { 1021 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1022 { 1023 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1024 DE_NULL, // const void* pNext; 1025 0u, // VkPipelineMultisampleStateCreateFlags flags; 1026 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 1027 false, // VkBool32 sampleShadingEnable; 1028 0.0f, // float minSampleShading; 1029 DE_NULL, // const VkSampleMask* pSampleMask; 1030 true, // VkBool32 alphaToCoverageEnable; 1031 false // VkBool32 alphaToOneEnable; 1032 }; 1033 1034 return multisampleStateParams; 1035 } 1036 1037 // RasterizationSamplesInstance 1038 1039 RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context, 1040 VkPrimitiveTopology topology, 1041 const std::vector<Vertex4RGBA>& vertices, 1042 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1043 const VkPipelineColorBlendAttachmentState& blendState, 1044 const TestModeFlags modeFlags) 1045 : vkt::TestInstance (context) 1046 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1047 , m_renderSize (32, 32) 1048 , m_primitiveTopology (topology) 1049 , m_vertices (vertices) 1050 , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)) 1051 , m_modeFlags (modeFlags) 1052 { 1053 if (m_modeFlags != 0) 1054 { 1055 const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0; 1056 const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0; 1057 const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil); 1058 1059 if (depthStencilFormat == VK_FORMAT_UNDEFINED) 1060 TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported"); 1061 1062 const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }; 1063 const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices }; 1064 1065 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 1066 new MultisampleRenderer( 1067 context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE)); 1068 } 1069 else 1070 { 1071 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 1072 new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE)); 1073 } 1074 } 1075 1076 tcu::TestStatus RasterizationSamplesInstance::iterate (void) 1077 { 1078 de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render()); 1079 return verifyImage(level->getAccess()); 1080 } 1081 1082 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 1083 { 1084 // Verify range of unique pixels 1085 { 1086 const deUint32 numUniqueColors = getUniqueColorsCount(result); 1087 const deUint32 minUniqueColors = 3; 1088 1089 tcu::TestLog& log = m_context.getTestContext().getLog(); 1090 1091 log << tcu::TestLog::Message 1092 << "\nMin. unique colors expected: " << minUniqueColors << "\n" 1093 << "Unique colors found: " << numUniqueColors << "\n" 1094 << tcu::TestLog::EndMessage; 1095 1096 if (numUniqueColors < minUniqueColors) 1097 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 1098 } 1099 1100 // Verify shape of the rendered primitive (fuzzy-compare) 1101 { 1102 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 1103 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); 1104 const ColorVertexShader vertexShader; 1105 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); 1106 const rr::Program program (&vertexShader, &fragmentShader); 1107 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 1108 rr::RenderState renderState (refRenderer.getViewportState()); 1109 1110 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) 1111 { 1112 VkPhysicalDeviceProperties deviceProperties; 1113 1114 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties); 1115 1116 // gl_PointSize is clamped to pointSizeRange 1117 renderState.point.pointSize = deFloatMin(3.0f, deviceProperties.limits.pointSizeRange[1]); 1118 } 1119 1120 if (m_modeFlags == 0) 1121 { 1122 refRenderer.colorClear(tcu::Vec4(0.0f)); 1123 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 1124 } 1125 else 1126 { 1127 // For depth/stencil case the primitive is invisible and the surroundings are filled red. 1128 refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1129 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 1130 } 1131 1132 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT)) 1133 return tcu::TestStatus::fail("Primitive has unexpected shape"); 1134 } 1135 1136 return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds"); 1137 } 1138 1139 1140 // MinSampleShadingInstance 1141 1142 MinSampleShadingInstance::MinSampleShadingInstance (Context& context, 1143 VkPrimitiveTopology topology, 1144 const std::vector<Vertex4RGBA>& vertices, 1145 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1146 const VkPipelineColorBlendAttachmentState& colorBlendState) 1147 : vkt::TestInstance (context) 1148 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1149 , m_renderSize (32, 32) 1150 , m_primitiveTopology (topology) 1151 , m_vertices (vertices) 1152 , m_multisampleStateParams (multisampleStateParams) 1153 , m_colorBlendState (colorBlendState) 1154 { 1155 VkPhysicalDeviceFeatures deviceFeatures; 1156 1157 m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures); 1158 1159 if (!deviceFeatures.sampleRateShading) 1160 throw tcu::NotSupportedError("Sample shading is not supported"); 1161 } 1162 1163 tcu::TestStatus MinSampleShadingInstance::iterate (void) 1164 { 1165 de::MovePtr<tcu::TextureLevel> noSampleshadingImage; 1166 std::vector<tcu::TextureLevel> sampleShadedImages; 1167 1168 // Render and resolve without sample shading 1169 { 1170 VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams; 1171 multisampleStateParms.sampleShadingEnable = VK_FALSE; 1172 multisampleStateParms.minSampleShading = 0.0; 1173 1174 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE); 1175 noSampleshadingImage = renderer.render(); 1176 } 1177 1178 // Render with test minSampleShading and collect per-sample images 1179 { 1180 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES); 1181 renderer.render(); 1182 1183 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples); 1184 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) 1185 { 1186 sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId); 1187 } 1188 } 1189 1190 // Log images 1191 { 1192 tcu::TestLog& testLog = m_context.getTestContext().getLog(); 1193 1194 testLog << tcu::TestLog::ImageSet("Images", "Images") 1195 << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess()); 1196 1197 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++) 1198 { 1199 testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess()); 1200 } 1201 testLog << tcu::TestLog::EndImageSet; 1202 } 1203 1204 return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess()); 1205 } 1206 1207 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage) 1208 { 1209 const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth(); 1210 1211 bool anyPixelCovered = false; 1212 1213 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) 1214 { 1215 const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx); 1216 1217 if (noSampleShadingValue == 0) 1218 { 1219 // non-covered pixel, continue 1220 continue; 1221 } 1222 else 1223 { 1224 anyPixelCovered = true; 1225 } 1226 1227 int numNotCoveredSamples = 0; 1228 1229 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> 1230 1231 // Collect histogram of occurrences or each pixel across all samples 1232 for (size_t i = 0; i < sampleShadedImages.size(); ++i) 1233 { 1234 const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx); 1235 1236 if (sampleShadedValue == 0) 1237 { 1238 numNotCoveredSamples++; 1239 continue; 1240 } 1241 1242 if (histogram.find(sampleShadedValue) != histogram.end()) 1243 histogram[sampleShadedValue]++; 1244 else 1245 histogram[sampleShadedValue] = 1; 1246 } 1247 1248 if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size())) 1249 { 1250 return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected"); 1251 } 1252 1253 const int uniqueColorsCount = (int)histogram.size(); 1254 const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f); 1255 1256 if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount) 1257 { 1258 return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading"); 1259 } 1260 } 1261 1262 if (!anyPixelCovered) 1263 { 1264 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading"); 1265 } 1266 1267 return tcu::TestStatus::pass("Got proper count of unique colors"); 1268 } 1269 1270 SampleMaskInstance::SampleMaskInstance (Context& context, 1271 VkPrimitiveTopology topology, 1272 const std::vector<Vertex4RGBA>& vertices, 1273 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1274 const VkPipelineColorBlendAttachmentState& blendState) 1275 : vkt::TestInstance (context) 1276 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1277 , m_renderSize (32, 32) 1278 , m_primitiveTopology (topology) 1279 , m_vertices (vertices) 1280 , m_multisampleStateParams (multisampleStateParams) 1281 , m_colorBlendState (blendState) 1282 { 1283 } 1284 1285 tcu::TestStatus SampleMaskInstance::iterate (void) 1286 { 1287 de::MovePtr<tcu::TextureLevel> testSampleMaskImage; 1288 de::MovePtr<tcu::TextureLevel> minSampleMaskImage; 1289 de::MovePtr<tcu::TextureLevel> maxSampleMaskImage; 1290 1291 // Render with test flags 1292 { 1293 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1294 testSampleMaskImage = renderer.render(); 1295 } 1296 1297 // Render with all flags off 1298 { 1299 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1300 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0); 1301 1302 multisampleParams.pSampleMask = sampleMask.data(); 1303 1304 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1305 minSampleMaskImage = renderer.render(); 1306 } 1307 1308 // Render with all flags on 1309 { 1310 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1311 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0)); 1312 1313 multisampleParams.pSampleMask = sampleMask.data(); 1314 1315 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1316 maxSampleMaskImage = renderer.render(); 1317 } 1318 1319 return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess()); 1320 } 1321 1322 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage, 1323 const tcu::ConstPixelBufferAccess& minSampleMaskImage, 1324 const tcu::ConstPixelBufferAccess& maxSampleMaskImage) 1325 { 1326 const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage); 1327 const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage); 1328 const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage); 1329 1330 tcu::TestLog& log = m_context.getTestContext().getLog(); 1331 1332 log << tcu::TestLog::Message 1333 << "\nColors found: " << testColorCount << "\n" 1334 << "Min. colors expected: " << minColorCount << "\n" 1335 << "Max. colors expected: " << maxColorCount << "\n" 1336 << tcu::TestLog::EndMessage; 1337 1338 if (minColorCount > testColorCount || testColorCount > maxColorCount) 1339 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 1340 else 1341 return tcu::TestStatus::pass("Unique colors within expected bounds"); 1342 } 1343 1344 tcu::TestStatus testRasterSamplesConsistency (Context& context, GeometryType geometryType) 1345 { 1346 // Use triangle only. 1347 DE_UNREF(geometryType); 1348 1349 const VkSampleCountFlagBits samples[] = 1350 { 1351 VK_SAMPLE_COUNT_1_BIT, 1352 VK_SAMPLE_COUNT_2_BIT, 1353 VK_SAMPLE_COUNT_4_BIT, 1354 VK_SAMPLE_COUNT_8_BIT, 1355 VK_SAMPLE_COUNT_16_BIT, 1356 VK_SAMPLE_COUNT_32_BIT, 1357 VK_SAMPLE_COUNT_64_BIT 1358 }; 1359 1360 const Vertex4RGBA vertexData[3] = 1361 { 1362 { 1363 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 1364 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1365 }, 1366 { 1367 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 1368 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1369 }, 1370 { 1371 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 1372 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1373 } 1374 }; 1375 1376 const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3); 1377 deUint32 prevUniqueColors = 2; 1378 int renderCount = 0; 1379 1380 // Do not render with 1 sample (start with samplesNdx = 1). 1381 for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 1382 { 1383 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx])) 1384 continue; 1385 1386 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1387 { 1388 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1389 DE_NULL, // const void* pNext; 1390 0u, // VkPipelineMultisampleStateCreateFlags flags; 1391 samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples; 1392 false, // VkBool32 sampleShadingEnable; 1393 0.0f, // float minSampleShading; 1394 DE_NULL, // const VkSampleMask* pSampleMask; 1395 false, // VkBool32 alphaToCoverageEnable; 1396 false // VkBool32 alphaToOneEnable; 1397 }; 1398 1399 MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE); 1400 de::MovePtr<tcu::TextureLevel> result = renderer.render(); 1401 const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess()); 1402 1403 renderCount++; 1404 1405 if (prevUniqueColors > uniqueColors) 1406 { 1407 std::ostringstream message; 1408 1409 message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx]; 1410 return tcu::TestStatus::fail(message.str()); 1411 } 1412 1413 prevUniqueColors = uniqueColors; 1414 } 1415 1416 if (renderCount == 0) 1417 throw tcu::NotSupportedError("Multisampling is unsupported"); 1418 1419 return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases"); 1420 } 1421 1422 1423 // AlphaToOneInstance 1424 1425 AlphaToOneInstance::AlphaToOneInstance (Context& context, 1426 VkPrimitiveTopology topology, 1427 const std::vector<Vertex4RGBA>& vertices, 1428 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1429 const VkPipelineColorBlendAttachmentState& blendState) 1430 : vkt::TestInstance (context) 1431 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1432 , m_renderSize (32, 32) 1433 , m_primitiveTopology (topology) 1434 , m_vertices (vertices) 1435 , m_multisampleStateParams (multisampleStateParams) 1436 , m_colorBlendState (blendState) 1437 { 1438 VkPhysicalDeviceFeatures deviceFeatures; 1439 1440 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures); 1441 1442 if (!deviceFeatures.alphaToOne) 1443 throw tcu::NotSupportedError("Alpha-to-one is not supported"); 1444 } 1445 1446 tcu::TestStatus AlphaToOneInstance::iterate (void) 1447 { 1448 DE_ASSERT(m_multisampleStateParams.alphaToOneEnable); 1449 DE_ASSERT(m_colorBlendState.blendEnable); 1450 1451 de::MovePtr<tcu::TextureLevel> alphaOneImage; 1452 de::MovePtr<tcu::TextureLevel> noAlphaOneImage; 1453 1454 // Render with blend enabled and alpha to one on 1455 { 1456 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1457 alphaOneImage = renderer.render(); 1458 } 1459 1460 // Render with blend enabled and alpha to one off 1461 { 1462 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1463 multisampleParams.alphaToOneEnable = false; 1464 1465 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1466 noAlphaOneImage = renderer.render(); 1467 } 1468 1469 return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess()); 1470 } 1471 1472 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 1473 const tcu::ConstPixelBufferAccess& noAlphaOneImage) 1474 { 1475 for (int y = 0; y < m_renderSize.y(); y++) 1476 { 1477 for (int x = 0; x < m_renderSize.x(); x++) 1478 { 1479 if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y)))) 1480 { 1481 std::ostringstream message; 1482 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y); 1483 return tcu::TestStatus::fail(message.str()); 1484 } 1485 } 1486 } 1487 1488 return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one"); 1489 } 1490 1491 1492 // AlphaToCoverageInstance 1493 1494 AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context, 1495 VkPrimitiveTopology topology, 1496 const std::vector<Vertex4RGBA>& vertices, 1497 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1498 const VkPipelineColorBlendAttachmentState& blendState, 1499 GeometryType geometryType) 1500 : vkt::TestInstance (context) 1501 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1502 , m_renderSize (32, 32) 1503 , m_primitiveTopology (topology) 1504 , m_vertices (vertices) 1505 , m_multisampleStateParams (multisampleStateParams) 1506 , m_colorBlendState (blendState) 1507 , m_geometryType (geometryType) 1508 { 1509 } 1510 1511 tcu::TestStatus AlphaToCoverageInstance::iterate (void) 1512 { 1513 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); 1514 1515 de::MovePtr<tcu::TextureLevel> result; 1516 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE); 1517 1518 result = renderer.render(); 1519 1520 return verifyImage(result->getAccess()); 1521 } 1522 1523 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 1524 { 1525 float maxColorValue; 1526 1527 switch (m_geometryType) 1528 { 1529 case GEOMETRY_TYPE_OPAQUE_QUAD: 1530 maxColorValue = 1.01f; 1531 break; 1532 1533 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 1534 maxColorValue = 0.52f; 1535 break; 1536 1537 case GEOMETRY_TYPE_INVISIBLE_QUAD: 1538 maxColorValue = 0.01f; 1539 break; 1540 1541 default: 1542 maxColorValue = 0.0f; 1543 DE_ASSERT(false); 1544 } 1545 1546 for (int y = 0; y < m_renderSize.y(); y++) 1547 { 1548 for (int x = 0; x < m_renderSize.x(); x++) 1549 { 1550 if (result.getPixel(x, y).x() > maxColorValue) 1551 { 1552 std::ostringstream message; 1553 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")"; 1554 return tcu::TestStatus::fail(message.str()); 1555 } 1556 } 1557 } 1558 1559 return tcu::TestStatus::pass("Image matches reference value"); 1560 } 1561 1562 1563 // MultisampleRenderer 1564 1565 MultisampleRenderer::MultisampleRenderer (Context& context, 1566 const VkFormat colorFormat, 1567 const tcu::IVec2& renderSize, 1568 const VkPrimitiveTopology topology, 1569 const std::vector<Vertex4RGBA>& vertices, 1570 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1571 const VkPipelineColorBlendAttachmentState& blendState, 1572 const RenderType renderType) 1573 : m_context (context) 1574 , m_colorFormat (colorFormat) 1575 , m_depthStencilFormat (VK_FORMAT_UNDEFINED) 1576 , m_renderSize (renderSize) 1577 , m_useDepth (false) 1578 , m_useStencil (false) 1579 , m_multisampleStateParams (multisampleStateParams) 1580 , m_colorBlendState (blendState) 1581 , m_renderType (renderType) 1582 { 1583 initialize(context, 1u, &topology, &vertices); 1584 } 1585 1586 MultisampleRenderer::MultisampleRenderer (Context& context, 1587 const VkFormat colorFormat, 1588 const VkFormat depthStencilFormat, 1589 const tcu::IVec2& renderSize, 1590 const bool useDepth, 1591 const bool useStencil, 1592 const deUint32 numTopologies, 1593 const VkPrimitiveTopology* pTopology, 1594 const std::vector<Vertex4RGBA>* pVertices, 1595 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1596 const VkPipelineColorBlendAttachmentState& blendState, 1597 const RenderType renderType) 1598 : m_context (context) 1599 , m_colorFormat (colorFormat) 1600 , m_depthStencilFormat (depthStencilFormat) 1601 , m_renderSize (renderSize) 1602 , m_useDepth (useDepth) 1603 , m_useStencil (useStencil) 1604 , m_multisampleStateParams (multisampleStateParams) 1605 , m_colorBlendState (blendState) 1606 , m_renderType (renderType) 1607 { 1608 initialize(context, numTopologies, pTopology, pVertices); 1609 } 1610 1611 void MultisampleRenderer::initialize (Context& context, 1612 const deUint32 numTopologies, 1613 const VkPrimitiveTopology* pTopology, 1614 const std::vector<Vertex4RGBA>* pVertices) 1615 { 1616 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples)) 1617 throw tcu::NotSupportedError("Unsupported number of rasterization samples"); 1618 1619 const DeviceInterface& vk = context.getDeviceInterface(); 1620 const VkDevice vkDevice = context.getDevice(); 1621 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1622 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 1623 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 1624 1625 // Create color image 1626 { 1627 1628 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1629 (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u); 1630 1631 const VkImageCreateInfo colorImageParams = 1632 { 1633 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1634 DE_NULL, // const void* pNext; 1635 0u, // VkImageCreateFlags flags; 1636 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1637 m_colorFormat, // VkFormat format; 1638 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1639 1u, // deUint32 mipLevels; 1640 1u, // deUint32 arrayLayers; 1641 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1642 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1643 imageUsageFlags, // VkImageUsageFlags usage; 1644 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1645 1u, // deUint32 queueFamilyIndexCount; 1646 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1647 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1648 }; 1649 1650 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 1651 1652 // Allocate and bind color image memory 1653 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 1654 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 1655 } 1656 1657 // Create resolve image 1658 if (m_renderType == RENDER_TYPE_RESOLVE) 1659 { 1660 const VkImageCreateInfo resolveImageParams = 1661 { 1662 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1663 DE_NULL, // const void* pNext; 1664 0u, // VkImageCreateFlags flags; 1665 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1666 m_colorFormat, // VkFormat format; 1667 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1668 1u, // deUint32 mipLevels; 1669 1u, // deUint32 arrayLayers; 1670 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1671 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1672 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; 1673 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1674 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1675 1u, // deUint32 queueFamilyIndexCount; 1676 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1677 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1678 }; 1679 1680 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams); 1681 1682 // Allocate and bind resolve image memory 1683 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any); 1684 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset())); 1685 1686 // Create resolve attachment view 1687 { 1688 const VkImageViewCreateInfo resolveAttachmentViewParams = 1689 { 1690 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1691 DE_NULL, // const void* pNext; 1692 0u, // VkImageViewCreateFlags flags; 1693 *m_resolveImage, // VkImage image; 1694 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1695 m_colorFormat, // VkFormat format; 1696 componentMappingRGBA, // VkComponentMapping components; 1697 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1698 }; 1699 1700 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams); 1701 } 1702 } 1703 1704 // Create per-sample output images 1705 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 1706 { 1707 const VkImageCreateInfo perSampleImageParams = 1708 { 1709 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1710 DE_NULL, // const void* pNext; 1711 0u, // VkImageCreateFlags flags; 1712 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1713 m_colorFormat, // VkFormat format; 1714 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1715 1u, // deUint32 mipLevels; 1716 1u, // deUint32 arrayLayers; 1717 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1718 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1719 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; 1720 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1721 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1722 1u, // deUint32 queueFamilyIndexCount; 1723 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1724 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1725 }; 1726 1727 m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples)); 1728 1729 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 1730 { 1731 m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage); 1732 PerSampleImage& image = *m_perSampleImages[i]; 1733 1734 image.m_image = createImage(vk, vkDevice, &perSampleImageParams); 1735 1736 // Allocate and bind image memory 1737 image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any); 1738 VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset())); 1739 1740 // Create per-sample attachment view 1741 { 1742 const VkImageViewCreateInfo perSampleAttachmentViewParams = 1743 { 1744 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1745 DE_NULL, // const void* pNext; 1746 0u, // VkImageViewCreateFlags flags; 1747 *image.m_image, // VkImage image; 1748 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1749 m_colorFormat, // VkFormat format; 1750 componentMappingRGBA, // VkComponentMapping components; 1751 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1752 }; 1753 1754 image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams); 1755 } 1756 } 1757 } 1758 1759 // Create a depth/stencil image 1760 if (m_useDepth || m_useStencil) 1761 { 1762 const VkImageCreateInfo depthStencilImageParams = 1763 { 1764 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1765 DE_NULL, // const void* pNext; 1766 0u, // VkImageCreateFlags flags; 1767 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1768 m_depthStencilFormat, // VkFormat format; 1769 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1770 1u, // deUint32 mipLevels; 1771 1u, // deUint32 arrayLayers; 1772 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1773 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1774 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage; 1775 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1776 1u, // deUint32 queueFamilyIndexCount; 1777 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1778 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1779 }; 1780 1781 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams); 1782 1783 // Allocate and bind depth/stencil image memory 1784 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any); 1785 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset())); 1786 } 1787 1788 // Create color attachment view 1789 { 1790 const VkImageViewCreateInfo colorAttachmentViewParams = 1791 { 1792 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1793 DE_NULL, // const void* pNext; 1794 0u, // VkImageViewCreateFlags flags; 1795 *m_colorImage, // VkImage image; 1796 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1797 m_colorFormat, // VkFormat format; 1798 componentMappingRGBA, // VkComponentMapping components; 1799 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1800 }; 1801 1802 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 1803 } 1804 1805 VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0; 1806 1807 // Create depth/stencil attachment view 1808 if (m_useDepth || m_useStencil) 1809 { 1810 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat); 1811 1812 const VkImageViewCreateInfo depthStencilAttachmentViewParams = 1813 { 1814 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1815 DE_NULL, // const void* pNext; 1816 0u, // VkImageViewCreateFlags flags; 1817 *m_depthStencilImage, // VkImage image; 1818 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1819 m_depthStencilFormat, // VkFormat format; 1820 componentMappingRGBA, // VkComponentMapping components; 1821 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1822 }; 1823 1824 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams); 1825 } 1826 1827 // Create render pass 1828 { 1829 std::vector<VkAttachmentDescription> attachmentDescriptions; 1830 { 1831 const VkAttachmentDescription colorAttachmentDescription = 1832 { 1833 0u, // VkAttachmentDescriptionFlags flags; 1834 m_colorFormat, // VkFormat format; 1835 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1836 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1837 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1838 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1839 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1840 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1841 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1842 }; 1843 attachmentDescriptions.push_back(colorAttachmentDescription); 1844 } 1845 1846 deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED; 1847 1848 if (m_renderType == RENDER_TYPE_RESOLVE) 1849 { 1850 resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 1851 1852 const VkAttachmentDescription resolveAttachmentDescription = 1853 { 1854 0u, // VkAttachmentDescriptionFlags flags; 1855 m_colorFormat, // VkFormat format; 1856 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1857 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1858 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1859 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1860 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1861 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1862 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1863 }; 1864 attachmentDescriptions.push_back(resolveAttachmentDescription); 1865 } 1866 1867 deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED; 1868 1869 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 1870 { 1871 perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 1872 1873 const VkAttachmentDescription perSampleAttachmentDescription = 1874 { 1875 0u, // VkAttachmentDescriptionFlags flags; 1876 m_colorFormat, // VkFormat format; 1877 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1878 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1879 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1880 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1881 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1882 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1883 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1884 }; 1885 1886 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 1887 { 1888 attachmentDescriptions.push_back(perSampleAttachmentDescription); 1889 } 1890 } 1891 1892 deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED; 1893 1894 if (m_useDepth || m_useStencil) 1895 { 1896 depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size()); 1897 1898 const VkAttachmentDescription depthStencilAttachmentDescription = 1899 { 1900 0u, // VkAttachmentDescriptionFlags flags; 1901 m_depthStencilFormat, // VkFormat format; 1902 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1903 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp; 1904 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp; 1905 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp; 1906 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp; 1907 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1908 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1909 }; 1910 attachmentDescriptions.push_back(depthStencilAttachmentDescription); 1911 }; 1912 1913 const VkAttachmentReference colorAttachmentReference = 1914 { 1915 0u, // deUint32 attachment; 1916 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1917 }; 1918 1919 const VkAttachmentReference inputAttachmentReference = 1920 { 1921 0u, // deUint32 attachment; 1922 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout; 1923 }; 1924 1925 const VkAttachmentReference resolveAttachmentReference = 1926 { 1927 resolveAttachmentIndex, // deUint32 attachment; 1928 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1929 }; 1930 1931 std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size()); 1932 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 1933 { 1934 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 1935 { 1936 const VkAttachmentReference perSampleAttachmentReference = 1937 { 1938 perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment; 1939 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1940 }; 1941 perSampleAttachmentReferences[i] = perSampleAttachmentReference; 1942 } 1943 } 1944 1945 const VkAttachmentReference depthStencilAttachmentReference = 1946 { 1947 depthStencilAttachmentIndex, // deUint32 attachment; 1948 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1949 }; 1950 1951 std::vector<VkSubpassDescription> subpassDescriptions; 1952 std::vector<VkSubpassDependency> subpassDependencies; 1953 1954 { 1955 const VkSubpassDescription renderSubpassDescription = 1956 { 1957 0u, // VkSubpassDescriptionFlags flags; 1958 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1959 0u, // deUint32 inputAttachmentCount; 1960 DE_NULL, // const VkAttachmentReference* pInputAttachments; 1961 1u, // deUint32 colorAttachmentCount; 1962 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 1963 (m_renderType == RENDER_TYPE_RESOLVE) ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments; 1964 (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment; 1965 0u, // deUint32 preserveAttachmentCount; 1966 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 1967 }; 1968 subpassDescriptions.push_back(renderSubpassDescription); 1969 } 1970 1971 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 1972 { 1973 1974 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 1975 { 1976 const VkSubpassDescription copySampleSubpassDescription = 1977 { 1978 0u, // VkSubpassDescriptionFlags flags; 1979 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1980 1u, // deUint32 inputAttachmentCount; 1981 &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments; 1982 1u, // deUint32 colorAttachmentCount; 1983 &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments; 1984 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 1985 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 1986 0u, // deUint32 preserveAttachmentCount; 1987 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 1988 }; 1989 subpassDescriptions.push_back(copySampleSubpassDescription); 1990 1991 const VkSubpassDependency copySampleSubpassDependency = 1992 { 1993 0u, // deUint32 srcSubpass 1994 1u + static_cast<deUint32>(i), // deUint32 dstSubpass 1995 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask 1996 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask 1997 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 1998 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask 1999 0u, // VkDependencyFlags dependencyFlags 2000 }; 2001 subpassDependencies.push_back(copySampleSubpassDependency); 2002 } 2003 } 2004 2005 const VkRenderPassCreateInfo renderPassParams = 2006 { 2007 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 2008 DE_NULL, // const void* pNext; 2009 0u, // VkRenderPassCreateFlags flags; 2010 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount; 2011 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; 2012 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount; 2013 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses; 2014 (deUint32)subpassDependencies.size(), // deUint32 dependencyCount; 2015 subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL 2016 }; 2017 2018 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 2019 } 2020 2021 // Create framebuffer 2022 { 2023 std::vector<VkImageView> attachments; 2024 attachments.push_back(*m_colorAttachmentView); 2025 if (m_renderType == RENDER_TYPE_RESOLVE) 2026 { 2027 attachments.push_back(*m_resolveAttachmentView); 2028 } 2029 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2030 { 2031 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 2032 { 2033 attachments.push_back(*m_perSampleImages[i]->m_attachmentView); 2034 } 2035 } 2036 2037 if (m_useDepth || m_useStencil) 2038 { 2039 attachments.push_back(*m_depthStencilAttachmentView); 2040 } 2041 2042 const VkFramebufferCreateInfo framebufferParams = 2043 { 2044 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 2045 DE_NULL, // const void* pNext; 2046 0u, // VkFramebufferCreateFlags flags; 2047 *m_renderPass, // VkRenderPass renderPass; 2048 (deUint32)attachments.size(), // deUint32 attachmentCount; 2049 &attachments[0], // const VkImageView* pAttachments; 2050 (deUint32)m_renderSize.x(), // deUint32 width; 2051 (deUint32)m_renderSize.y(), // deUint32 height; 2052 1u // deUint32 layers; 2053 }; 2054 2055 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 2056 } 2057 2058 // Create pipeline layout 2059 { 2060 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 2061 { 2062 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2063 DE_NULL, // const void* pNext; 2064 0u, // VkPipelineLayoutCreateFlags flags; 2065 0u, // deUint32 setLayoutCount; 2066 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 2067 0u, // deUint32 pushConstantRangeCount; 2068 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 2069 }; 2070 2071 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 2072 2073 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2074 { 2075 2076 // Create descriptor set layout 2077 const VkDescriptorSetLayoutBinding layoutBinding = 2078 { 2079 0u, // deUint32 binding; 2080 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType; 2081 1u, // deUint32 descriptorCount; 2082 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 2083 DE_NULL, // const VkSampler* pImmutableSamplers; 2084 }; 2085 2086 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = 2087 { 2088 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType 2089 DE_NULL, // const void* pNext 2090 0u, // VkDescriptorSetLayoutCreateFlags flags 2091 1u, // deUint32 bindingCount 2092 &layoutBinding // const VkDescriptorSetLayoutBinding* pBindings 2093 }; 2094 m_copySampleDesciptorLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams); 2095 2096 // Create pipeline layout 2097 2098 const VkPushConstantRange pushConstantRange = 2099 { 2100 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 2101 0u, // deUint32 offset; 2102 sizeof(deInt32) // deUint32 size; 2103 }; 2104 const VkPipelineLayoutCreateInfo copySamplePipelineLayoutParams = 2105 { 2106 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2107 DE_NULL, // const void* pNext; 2108 0u, // VkPipelineLayoutCreateFlags flags; 2109 1u, // deUint32 setLayoutCount; 2110 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 2111 1u, // deUint32 pushConstantRangeCount; 2112 &pushConstantRange // const VkPushConstantRange* pPushConstantRanges; 2113 }; 2114 m_copySamplePipelineLayout = createPipelineLayout(vk, vkDevice, ©SamplePipelineLayoutParams); 2115 } 2116 } 2117 2118 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 2119 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 2120 2121 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2122 { 2123 m_copySampleVertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0); 2124 m_copySampleFragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0); 2125 } 2126 2127 // Create pipeline 2128 { 2129 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 2130 { 2131 { 2132 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2133 DE_NULL, // const void* pNext; 2134 0u, // VkPipelineShaderStageCreateFlags flags; 2135 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 2136 *m_vertexShaderModule, // VkShaderModule module; 2137 "main", // const char* pName; 2138 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2139 }, 2140 { 2141 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2142 DE_NULL, // const void* pNext; 2143 0u, // VkPipelineShaderStageCreateFlags flags; 2144 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 2145 *m_fragmentShaderModule, // VkShaderModule module; 2146 "main", // const char* pName; 2147 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2148 } 2149 }; 2150 2151 const VkVertexInputBindingDescription vertexInputBindingDescription = 2152 { 2153 0u, // deUint32 binding; 2154 sizeof(Vertex4RGBA), // deUint32 stride; 2155 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; 2156 }; 2157 2158 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 2159 { 2160 { 2161 0u, // deUint32 location; 2162 0u, // deUint32 binding; 2163 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 2164 0u // deUint32 offset; 2165 }, 2166 { 2167 1u, // deUint32 location; 2168 0u, // deUint32 binding; 2169 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 2170 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset; 2171 } 2172 }; 2173 2174 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 2175 { 2176 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 2177 DE_NULL, // const void* pNext; 2178 0u, // VkPipelineVertexInputStateCreateFlags flags; 2179 1u, // deUint32 vertexBindingDescriptionCount; 2180 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2181 2u, // deUint32 vertexAttributeDescriptionCount; 2182 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 2183 }; 2184 2185 // Topology is set before the pipeline creation. 2186 VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 2187 { 2188 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 2189 DE_NULL, // const void* pNext; 2190 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 2191 VK_PRIMITIVE_TOPOLOGY_LAST, // VkPrimitiveTopology topology; 2192 false // VkBool32 primitiveRestartEnable; 2193 }; 2194 2195 const VkViewport viewport = 2196 { 2197 0.0f, // float x; 2198 0.0f, // float y; 2199 (float)m_renderSize.x(), // float width; 2200 (float)m_renderSize.y(), // float height; 2201 0.0f, // float minDepth; 2202 1.0f // float maxDepth; 2203 }; 2204 2205 const VkRect2D scissor = 2206 { 2207 { 0, 0 }, // VkOffset2D offset; 2208 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } // VkExtent2D extent; 2209 }; 2210 2211 const VkPipelineViewportStateCreateInfo viewportStateParams = 2212 { 2213 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 2214 DE_NULL, // const void* pNext; 2215 0u, // VkPipelineViewportStateCreateFlags flags; 2216 1u, // deUint32 viewportCount; 2217 &viewport, // const VkViewport* pViewports; 2218 1u, // deUint32 scissorCount; 2219 &scissor // const VkRect2D* pScissors; 2220 }; 2221 2222 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 2223 { 2224 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 2225 DE_NULL, // const void* pNext; 2226 0u, // VkPipelineRasterizationStateCreateFlags flags; 2227 false, // VkBool32 depthClampEnable; 2228 false, // VkBool32 rasterizerDiscardEnable; 2229 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 2230 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 2231 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 2232 VK_FALSE, // VkBool32 depthBiasEnable; 2233 0.0f, // float depthBiasConstantFactor; 2234 0.0f, // float depthBiasClamp; 2235 0.0f, // float depthBiasSlopeFactor; 2236 1.0f // float lineWidth; 2237 }; 2238 2239 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 2240 { 2241 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 2242 DE_NULL, // const void* pNext; 2243 0u, // VkPipelineColorBlendStateCreateFlags flags; 2244 false, // VkBool32 logicOpEnable; 2245 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 2246 1u, // deUint32 attachmentCount; 2247 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments; 2248 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 2249 }; 2250 2251 const VkStencilOpState stencilOpState = 2252 { 2253 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 2254 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp; 2255 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 2256 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp; 2257 1u, // deUint32 compareMask; 2258 1u, // deUint32 writeMask; 2259 1u, // deUint32 reference; 2260 }; 2261 2262 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 2263 { 2264 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 2265 DE_NULL, // const void* pNext; 2266 0u, // VkPipelineDepthStencilStateCreateFlags flags; 2267 m_useDepth, // VkBool32 depthTestEnable; 2268 m_useDepth, // VkBool32 depthWriteEnable; 2269 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 2270 false, // VkBool32 depthBoundsTestEnable; 2271 m_useStencil, // VkBool32 stencilTestEnable; 2272 stencilOpState, // VkStencilOpState front; 2273 stencilOpState, // VkStencilOpState back; 2274 0.0f, // float minDepthBounds; 2275 1.0f, // float maxDepthBounds; 2276 }; 2277 2278 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 2279 { 2280 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 2281 DE_NULL, // const void* pNext; 2282 0u, // VkPipelineCreateFlags flags; 2283 2u, // deUint32 stageCount; 2284 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 2285 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 2286 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 2287 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 2288 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 2289 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 2290 &m_multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 2291 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 2292 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 2293 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2294 *m_pipelineLayout, // VkPipelineLayout layout; 2295 *m_renderPass, // VkRenderPass renderPass; 2296 0u, // deUint32 subpass; 2297 0u, // VkPipeline basePipelineHandle; 2298 0u // deInt32 basePipelineIndex; 2299 }; 2300 2301 for (deUint32 i = 0u; i < numTopologies; ++i) 2302 { 2303 inputAssemblyStateParams.topology = pTopology[i]; 2304 m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams)))); 2305 } 2306 } 2307 2308 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2309 { 2310 // Create pipelines for copying samples to single sampled images 2311 { 2312 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 2313 { 2314 { 2315 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2316 DE_NULL, // const void* pNext; 2317 0u, // VkPipelineShaderStageCreateFlags flags; 2318 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 2319 *m_copySampleVertexShaderModule, // VkShaderModule module; 2320 "main", // const char* pName; 2321 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2322 }, 2323 { 2324 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2325 DE_NULL, // const void* pNext; 2326 0u, // VkPipelineShaderStageCreateFlags flags; 2327 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 2328 *m_copySampleFragmentShaderModule, // VkShaderModule module; 2329 "main", // const char* pName; 2330 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2331 } 2332 }; 2333 2334 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 2335 { 2336 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 2337 DE_NULL, // const void* pNext; 2338 0u, // VkPipelineVertexInputStateCreateFlags flags; 2339 0u, // deUint32 vertexBindingDescriptionCount; 2340 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2341 0u, // deUint32 vertexAttributeDescriptionCount; 2342 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 2343 }; 2344 2345 // Topology is set before the pipeline creation. 2346 VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 2347 { 2348 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 2349 DE_NULL, // const void* pNext; 2350 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 2351 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology; 2352 false // VkBool32 primitiveRestartEnable; 2353 }; 2354 2355 const VkViewport viewport = 2356 { 2357 0.0f, // float x; 2358 0.0f, // float y; 2359 (float)m_renderSize.x(), // float width; 2360 (float)m_renderSize.y(), // float height; 2361 0.0f, // float minDepth; 2362 1.0f // float maxDepth; 2363 }; 2364 2365 const VkRect2D scissor = 2366 { 2367 { 0, 0 }, // VkOffset2D offset; 2368 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } // VkExtent2D extent; 2369 }; 2370 2371 const VkPipelineViewportStateCreateInfo viewportStateParams = 2372 { 2373 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 2374 DE_NULL, // const void* pNext; 2375 0u, // VkPipelineViewportStateCreateFlags flags; 2376 1u, // deUint32 viewportCount; 2377 &viewport, // const VkViewport* pViewports; 2378 1u, // deUint32 scissorCount; 2379 &scissor // const VkRect2D* pScissors; 2380 }; 2381 2382 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 2383 { 2384 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 2385 DE_NULL, // const void* pNext; 2386 0u, // VkPipelineRasterizationStateCreateFlags flags; 2387 false, // VkBool32 depthClampEnable; 2388 false, // VkBool32 rasterizerDiscardEnable; 2389 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 2390 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 2391 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 2392 VK_FALSE, // VkBool32 depthBiasEnable; 2393 0.0f, // float depthBiasConstantFactor; 2394 0.0f, // float depthBiasClamp; 2395 0.0f, // float depthBiasSlopeFactor; 2396 1.0f // float lineWidth; 2397 }; 2398 2399 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 2400 { 2401 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 2402 DE_NULL, // const void* pNext; 2403 0u, // VkPipelineColorBlendStateCreateFlags flags; 2404 false, // VkBool32 logicOpEnable; 2405 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 2406 1u, // deUint32 attachmentCount; 2407 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments; 2408 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 2409 }; 2410 2411 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 2412 { 2413 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType 2414 DE_NULL, // const void* pNext 2415 0u, // VkPipelineMultisampleStateCreateFlags flags 2416 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples 2417 VK_FALSE, // VkBool32 sampleShadingEnable 2418 0.0f, // float minSampleShading 2419 DE_NULL, // const VkSampleMask* pSampleMask 2420 VK_FALSE, // VkBool32 alphaToCoverageEnable 2421 VK_FALSE, // VkBool32 alphaToOneEnable 2422 }; 2423 2424 const VkGraphicsPipelineCreateInfo graphicsPipelineTemplate = 2425 { 2426 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 2427 DE_NULL, // const void* pNext; 2428 0u, // VkPipelineCreateFlags flags; 2429 2u, // deUint32 stageCount; 2430 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 2431 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 2432 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 2433 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 2434 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 2435 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 2436 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 2437 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 2438 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 2439 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2440 *m_copySamplePipelineLayout, // VkPipelineLayout layout; 2441 *m_renderPass, // VkRenderPass renderPass; 2442 0u, // deUint32 subpass; 2443 0u, // VkPipeline basePipelineHandle; 2444 0u // deInt32 basePipelineIndex; 2445 }; 2446 2447 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 2448 { 2449 VkGraphicsPipelineCreateInfo graphicsPipelineParams = graphicsPipelineTemplate; 2450 2451 // Pipeline is to be used in subpasses subsequent to sample-shading subpass 2452 graphicsPipelineParams.subpass = 1u + (deUint32)i; 2453 2454 m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams)))); 2455 } 2456 } 2457 2458 2459 const VkDescriptorPoolSize descriptorPoolSize = 2460 { 2461 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type; 2462 1u // deUint32 descriptorCount; 2463 }; 2464 2465 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = 2466 { 2467 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType 2468 DE_NULL, // const void* pNext 2469 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags 2470 1u, // deUint32 maxSets 2471 1u, // deUint32 poolSizeCount 2472 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes 2473 }; 2474 2475 m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo); 2476 2477 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = 2478 { 2479 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType 2480 DE_NULL, // const void* pNext 2481 *m_copySampleDesciptorPool, // VkDescriptorPool descriptorPool 2482 1u, // deUint32 descriptorSetCount 2483 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts 2484 }; 2485 2486 m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo); 2487 2488 const VkDescriptorImageInfo imageInfo = 2489 { 2490 DE_NULL, 2491 *m_colorAttachmentView, 2492 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 2493 }; 2494 const VkWriteDescriptorSet descriptorWrite = 2495 { 2496 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 2497 DE_NULL, // const void* pNext; 2498 *m_copySampleDesciptorSet, // VkDescriptorSet dstSet; 2499 0u, // deUint32 dstBinding; 2500 0u, // deUint32 dstArrayElement; 2501 1u, // deUint32 descriptorCount; 2502 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType; 2503 &imageInfo, // const VkDescriptorImageInfo* pImageInfo; 2504 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo; 2505 DE_NULL, // const VkBufferView* pTexelBufferView; 2506 }; 2507 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL); 2508 } 2509 2510 // Create vertex buffer 2511 { 2512 const VkBufferCreateInfo vertexBufferParams = 2513 { 2514 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 2515 DE_NULL, // const void* pNext; 2516 0u, // VkBufferCreateFlags flags; 2517 1024u, // VkDeviceSize size; 2518 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 2519 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2520 1u, // deUint32 queueFamilyIndexCount; 2521 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 2522 }; 2523 2524 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 2525 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 2526 2527 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 2528 2529 // Load vertices into vertex buffer 2530 { 2531 Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr()); 2532 for (deUint32 i = 0u; i < numTopologies; ++i) 2533 { 2534 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA)); 2535 pDst += pVertices[i].size(); 2536 } 2537 } 2538 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size); 2539 } 2540 2541 // Create command pool 2542 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 2543 2544 // Create command buffer 2545 { 2546 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 2547 { 2548 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 2549 DE_NULL, // const void* pNext; 2550 0u, // VkCommandBufferUsageFlags flags; 2551 (const VkCommandBufferInheritanceInfo*)DE_NULL, 2552 }; 2553 2554 VkClearValue colorClearValue; 2555 colorClearValue.color.float32[0] = 0.0f; 2556 colorClearValue.color.float32[1] = 0.0f; 2557 colorClearValue.color.float32[2] = 0.0f; 2558 colorClearValue.color.float32[3] = 0.0f; 2559 2560 VkClearValue depthStencilClearValue; 2561 depthStencilClearValue.depthStencil.depth = 1.0f; 2562 depthStencilClearValue.depthStencil.stencil = 0u; 2563 2564 std::vector<VkClearValue> clearValues; 2565 clearValues.push_back(colorClearValue); 2566 if (m_renderType == RENDER_TYPE_RESOLVE) 2567 { 2568 clearValues.push_back(colorClearValue); 2569 } 2570 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2571 { 2572 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 2573 { 2574 clearValues.push_back(colorClearValue); 2575 } 2576 } 2577 if (m_useDepth || m_useStencil) 2578 { 2579 clearValues.push_back(depthStencilClearValue); 2580 } 2581 2582 const VkRenderPassBeginInfo renderPassBeginInfo = 2583 { 2584 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2585 DE_NULL, // const void* pNext; 2586 *m_renderPass, // VkRenderPass renderPass; 2587 *m_framebuffer, // VkFramebuffer framebuffer; 2588 { 2589 { 0, 0 }, 2590 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } 2591 }, // VkRect2D renderArea; 2592 (deUint32)clearValues.size(), // deUint32 clearValueCount; 2593 &clearValues[0] // const VkClearValue* pClearValues; 2594 }; 2595 2596 std::vector<VkImageMemoryBarrier> imageLayoutBarriers; 2597 2598 { 2599 const VkImageMemoryBarrier colorImageBarrier = 2600 // color attachment image 2601 { 2602 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2603 DE_NULL, // const void* pNext; 2604 0u, // VkAccessFlags srcAccessMask; 2605 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2606 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2607 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2608 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2609 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2610 *m_colorImage, // VkImage image; 2611 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2612 }; 2613 imageLayoutBarriers.push_back(colorImageBarrier); 2614 } 2615 if (m_renderType == RENDER_TYPE_RESOLVE) 2616 { 2617 const VkImageMemoryBarrier resolveImageBarrier = 2618 // resolve attachment image 2619 { 2620 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2621 DE_NULL, // const void* pNext; 2622 0u, // VkAccessFlags srcAccessMask; 2623 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2624 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2625 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2626 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2627 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2628 *m_resolveImage, // VkImage image; 2629 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2630 }; 2631 imageLayoutBarriers.push_back(resolveImageBarrier); 2632 } 2633 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2634 { 2635 for (size_t i = 0; i < m_perSampleImages.size(); ++i) 2636 { 2637 const VkImageMemoryBarrier perSampleImageBarrier = 2638 // resolve attachment image 2639 { 2640 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2641 DE_NULL, // const void* pNext; 2642 0u, // VkAccessFlags srcAccessMask; 2643 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2644 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2645 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2646 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2647 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2648 *m_perSampleImages[i]->m_image, // VkImage image; 2649 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2650 }; 2651 imageLayoutBarriers.push_back(perSampleImageBarrier); 2652 } 2653 } 2654 if (m_useDepth || m_useStencil) 2655 { 2656 const VkImageMemoryBarrier depthStencilImageBarrier = 2657 // depth/stencil attachment image 2658 { 2659 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2660 DE_NULL, // const void* pNext; 2661 0u, // VkAccessFlags srcAccessMask; 2662 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2663 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2664 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2665 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2666 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2667 *m_depthStencilImage, // VkImage image; 2668 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2669 }; 2670 imageLayoutBarriers.push_back(depthStencilImageBarrier); 2671 }; 2672 2673 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2674 2675 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 2676 2677 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 2678 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]); 2679 2680 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 2681 2682 VkDeviceSize vertexBufferOffset = 0u; 2683 2684 for (deUint32 i = 0u; i < numTopologies; ++i) 2685 { 2686 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]); 2687 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 2688 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0); 2689 2690 vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA)); 2691 } 2692 2693 if (m_renderType == RENDER_TYPE_COPY_SAMPLES) 2694 { 2695 // Copy each sample id to single sampled image 2696 for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId) 2697 { 2698 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 2699 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]); 2700 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL); 2701 vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId); 2702 vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); 2703 } 2704 } 2705 2706 vk.cmdEndRenderPass(*m_cmdBuffer); 2707 2708 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 2709 } 2710 2711 // Create fence 2712 m_fence = createFence(vk, vkDevice); 2713 } 2714 2715 MultisampleRenderer::~MultisampleRenderer (void) 2716 { 2717 } 2718 2719 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void) 2720 { 2721 const DeviceInterface& vk = m_context.getDeviceInterface(); 2722 const VkDevice vkDevice = m_context.getDevice(); 2723 const VkQueue queue = m_context.getUniversalQueue(); 2724 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 2725 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 2726 const VkSubmitInfo submitInfo = 2727 { 2728 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 2729 DE_NULL, // const void* pNext; 2730 0u, // deUint32 waitSemaphoreCount; 2731 DE_NULL, // const VkSemaphore* pWaitSemaphores; 2732 (const VkPipelineStageFlags*)DE_NULL, 2733 1u, // deUint32 commandBufferCount; 2734 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 2735 0u, // deUint32 signalSemaphoreCount; 2736 DE_NULL // const VkSemaphore* pSignalSemaphores; 2737 }; 2738 2739 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 2740 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 2741 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 2742 2743 if (m_renderType == RENDER_TYPE_RESOLVE) 2744 { 2745 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>()); 2746 } 2747 else 2748 { 2749 return de::MovePtr<tcu::TextureLevel>(); 2750 } 2751 } 2752 2753 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId) 2754 { 2755 const DeviceInterface& vk = m_context.getDeviceInterface(); 2756 const VkDevice vkDevice = m_context.getDevice(); 2757 const VkQueue queue = m_context.getUniversalQueue(); 2758 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 2759 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 2760 2761 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>()); 2762 } 2763 2764 } // anonymous 2765 2766 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx) 2767 { 2768 const VkSampleCountFlagBits samples[] = 2769 { 2770 VK_SAMPLE_COUNT_2_BIT, 2771 VK_SAMPLE_COUNT_4_BIT, 2772 VK_SAMPLE_COUNT_8_BIT, 2773 VK_SAMPLE_COUNT_16_BIT, 2774 VK_SAMPLE_COUNT_32_BIT, 2775 VK_SAMPLE_COUNT_64_BIT 2776 }; 2777 2778 de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", "")); 2779 2780 // Rasterization samples tests 2781 { 2782 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", "")); 2783 2784 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2785 { 2786 std::ostringstream caseName; 2787 caseName << "samples_" << samples[samplesNdx]; 2788 2789 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2790 2791 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2792 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE)); 2793 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT)); 2794 2795 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT)); 2796 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_STENCIL_BIT)); 2797 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT)); 2798 2799 rasterizationSamplesTests->addChild(samplesTests.release()); 2800 } 2801 2802 multisampleTests->addChild(rasterizationSamplesTests.release()); 2803 } 2804 2805 // Raster samples consistency check 2806 { 2807 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", "")); 2808 2809 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(), 2810 "unique_colors_check", 2811 "", 2812 initMultisamplePrograms, 2813 testRasterSamplesConsistency, 2814 GEOMETRY_TYPE_OPAQUE_TRIANGLE); 2815 2816 multisampleTests->addChild(rasterSamplesConsistencyTests.release()); 2817 } 2818 2819 // minSampleShading tests 2820 { 2821 struct TestConfig 2822 { 2823 const char* name; 2824 float minSampleShading; 2825 }; 2826 2827 const TestConfig testConfigs[] = 2828 { 2829 { "min_0_0", 0.0f }, 2830 { "min_0_25", 0.25f }, 2831 { "min_0_5", 0.5f }, 2832 { "min_0_75", 0.75f }, 2833 { "min_1_0", 1.0f } 2834 }; 2835 2836 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", "")); 2837 2838 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 2839 { 2840 const TestConfig& testConfig = testConfigs[configNdx]; 2841 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, "")); 2842 2843 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2844 { 2845 std::ostringstream caseName; 2846 caseName << "samples_" << samples[samplesNdx]; 2847 2848 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2849 2850 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2851 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE)); 2852 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT)); 2853 2854 minShadingValueTests->addChild(samplesTests.release()); 2855 } 2856 2857 minSampleShadingTests->addChild(minShadingValueTests.release()); 2858 } 2859 2860 multisampleTests->addChild(minSampleShadingTests.release()); 2861 } 2862 2863 // pSampleMask tests 2864 { 2865 struct TestConfig 2866 { 2867 const char* name; 2868 const char* description; 2869 VkSampleMask sampleMask; 2870 }; 2871 2872 const TestConfig testConfigs[] = 2873 { 2874 { "mask_all_on", "All mask bits are off", 0x0 }, 2875 { "mask_all_off", "All mask bits are on", 0xFFFFFFFF }, 2876 { "mask_one", "All mask elements are 0x1", 0x1}, 2877 { "mask_random", "All mask elements are 0xAAAAAAAA", 0xAAAAAAAA }, 2878 }; 2879 2880 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", "")); 2881 2882 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 2883 { 2884 const TestConfig& testConfig = testConfigs[configNdx]; 2885 de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description)); 2886 2887 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2888 { 2889 std::ostringstream caseName; 2890 caseName << "samples_" << samples[samplesNdx]; 2891 2892 const deUint32 sampleMaskCount = samples[samplesNdx] / 32; 2893 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2894 2895 std::vector<VkSampleMask> mask; 2896 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++) 2897 mask.push_back(testConfig.sampleMask); 2898 2899 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2900 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE)); 2901 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT)); 2902 2903 sampleMaskValueTests->addChild(samplesTests.release()); 2904 } 2905 2906 sampleMaskTests->addChild(sampleMaskValueTests.release()); 2907 } 2908 2909 multisampleTests->addChild(sampleMaskTests.release()); 2910 2911 } 2912 2913 // AlphaToOne tests 2914 { 2915 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", "")); 2916 2917 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2918 { 2919 std::ostringstream caseName; 2920 caseName << "samples_" << samples[samplesNdx]; 2921 2922 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx])); 2923 } 2924 2925 multisampleTests->addChild(alphaToOneTests.release()); 2926 } 2927 2928 // AlphaToCoverageEnable tests 2929 { 2930 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", "")); 2931 2932 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2933 { 2934 std::ostringstream caseName; 2935 caseName << "samples_" << samples[samplesNdx]; 2936 2937 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2938 2939 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD)); 2940 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD)); 2941 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD)); 2942 2943 alphaToCoverageTests->addChild(samplesTests.release()); 2944 } 2945 multisampleTests->addChild(alphaToCoverageTests.release()); 2946 } 2947 2948 // Sampling from a multisampled image texture (texelFetch) 2949 { 2950 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx)); 2951 } 2952 2953 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.) 2954 { 2955 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx)); 2956 } 2957 2958 return multisampleTests.release(); 2959 } 2960 2961 } // pipeline 2962 } // vkt 2963