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 "deUniquePtr.hpp" 41#include "deSharedPtr.hpp" 42#include "deStringUtil.hpp" 43#include "deMemory.h" 44 45#include <sstream> 46#include <vector> 47#include <map> 48 49namespace vkt 50{ 51namespace pipeline 52{ 53 54using namespace vk; 55 56namespace 57{ 58enum GeometryType 59{ 60 GEOMETRY_TYPE_OPAQUE_TRIANGLE, 61 GEOMETRY_TYPE_OPAQUE_LINE, 62 GEOMETRY_TYPE_OPAQUE_POINT, 63 GEOMETRY_TYPE_OPAQUE_QUAD, 64 GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH, //!< placed at z = 0.5 65 GEOMETRY_TYPE_TRANSLUCENT_QUAD, 66 GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 67 GEOMETRY_TYPE_INVISIBLE_QUAD, 68 GEOMETRY_TYPE_GRADIENT_QUAD 69}; 70 71enum TestModeBits 72{ 73 TEST_MODE_DEPTH_BIT = 1u, 74 TEST_MODE_STENCIL_BIT = 2u, 75}; 76typedef deUint32 TestModeFlags; 77 78void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType); 79bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples); 80bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format); 81VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void); 82deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image); 83VkImageAspectFlags getImageAspectFlags (const VkFormat format); 84VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType); 85std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType); 86VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil); 87 88class MultisampleTest : public vkt::TestCase 89{ 90public: 91 92 MultisampleTest (tcu::TestContext& testContext, 93 const std::string& name, 94 const std::string& description, 95 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 96 const VkPipelineColorBlendAttachmentState& blendState, 97 GeometryType geometryType); 98 virtual ~MultisampleTest (void) {} 99 100 virtual void initPrograms (SourceCollections& programCollection) const; 101 virtual TestInstance* createInstance (Context& context) const; 102 103protected: 104 virtual TestInstance* createMultisampleTestInstance (Context& context, 105 VkPrimitiveTopology topology, 106 const std::vector<Vertex4RGBA>& vertices, 107 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 108 const VkPipelineColorBlendAttachmentState& colorBlendState) const = 0; 109 VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 110 const VkPipelineColorBlendAttachmentState m_colorBlendState; 111 const GeometryType m_geometryType; 112 std::vector<VkSampleMask> m_sampleMask; 113}; 114 115class RasterizationSamplesTest : public MultisampleTest 116{ 117public: 118 RasterizationSamplesTest (tcu::TestContext& testContext, 119 const std::string& name, 120 const std::string& description, 121 VkSampleCountFlagBits rasterizationSamples, 122 GeometryType geometryType, 123 TestModeFlags modeFlags = 0u); 124 virtual ~RasterizationSamplesTest (void) {} 125 126protected: 127 virtual TestInstance* createMultisampleTestInstance (Context& context, 128 VkPrimitiveTopology topology, 129 const std::vector<Vertex4RGBA>& vertices, 130 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 131 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 132 133 static VkPipelineMultisampleStateCreateInfo getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples); 134 135 const TestModeFlags m_modeFlags; 136}; 137 138class MinSampleShadingTest : public MultisampleTest 139{ 140public: 141 MinSampleShadingTest (tcu::TestContext& testContext, 142 const std::string& name, 143 const std::string& description, 144 VkSampleCountFlagBits rasterizationSamples, 145 float minSampleShading, 146 GeometryType geometryType); 147 virtual ~MinSampleShadingTest (void) {} 148 149protected: 150 virtual TestInstance* createMultisampleTestInstance (Context& context, 151 VkPrimitiveTopology topology, 152 const std::vector<Vertex4RGBA>& vertices, 153 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 154 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 155 156 static VkPipelineMultisampleStateCreateInfo getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading); 157}; 158 159class SampleMaskTest : public MultisampleTest 160{ 161public: 162 SampleMaskTest (tcu::TestContext& testContext, 163 const std::string& name, 164 const std::string& description, 165 VkSampleCountFlagBits rasterizationSamples, 166 const std::vector<VkSampleMask>& sampleMask, 167 GeometryType geometryType); 168 169 virtual ~SampleMaskTest (void) {} 170 171protected: 172 virtual TestInstance* createMultisampleTestInstance (Context& context, 173 VkPrimitiveTopology topology, 174 const std::vector<Vertex4RGBA>& vertices, 175 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 176 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 177 178 static VkPipelineMultisampleStateCreateInfo getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask); 179}; 180 181class AlphaToOneTest : public MultisampleTest 182{ 183public: 184 AlphaToOneTest (tcu::TestContext& testContext, 185 const std::string& name, 186 const std::string& description, 187 VkSampleCountFlagBits rasterizationSamples); 188 189 virtual ~AlphaToOneTest (void) {} 190 191protected: 192 virtual TestInstance* createMultisampleTestInstance (Context& context, 193 VkPrimitiveTopology topology, 194 const std::vector<Vertex4RGBA>& vertices, 195 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 196 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 197 198 static VkPipelineMultisampleStateCreateInfo getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples); 199 static VkPipelineColorBlendAttachmentState getAlphaToOneBlendState (void); 200}; 201 202class AlphaToCoverageTest : public MultisampleTest 203{ 204public: 205 AlphaToCoverageTest (tcu::TestContext& testContext, 206 const std::string& name, 207 const std::string& description, 208 VkSampleCountFlagBits rasterizationSamples, 209 GeometryType geometryType); 210 211 virtual ~AlphaToCoverageTest (void) {} 212 213protected: 214 virtual TestInstance* createMultisampleTestInstance (Context& context, 215 VkPrimitiveTopology topology, 216 const std::vector<Vertex4RGBA>& vertices, 217 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 218 const VkPipelineColorBlendAttachmentState& colorBlendState) const; 219 220 static VkPipelineMultisampleStateCreateInfo getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples); 221 222 GeometryType m_geometryType; 223}; 224 225typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp; 226 227class MultisampleRenderer 228{ 229public: 230 MultisampleRenderer (Context& context, 231 const VkFormat colorFormat, 232 const tcu::IVec2& renderSize, 233 const VkPrimitiveTopology topology, 234 const std::vector<Vertex4RGBA>& vertices, 235 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 236 const VkPipelineColorBlendAttachmentState& blendState); 237 238 MultisampleRenderer (Context& context, 239 const VkFormat colorFormat, 240 const VkFormat depthStencilFormat, 241 const tcu::IVec2& renderSize, 242 const bool useDepth, 243 const bool useStencil, 244 const deUint32 numTopologies, 245 const VkPrimitiveTopology* pTopology, 246 const std::vector<Vertex4RGBA>* pVertices, 247 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 248 const VkPipelineColorBlendAttachmentState& blendState); 249 250 virtual ~MultisampleRenderer (void); 251 252 de::MovePtr<tcu::TextureLevel> render (void); 253 254protected: 255 void initialize (Context& context, 256 const deUint32 numTopologies, 257 const VkPrimitiveTopology* pTopology, 258 const std::vector<Vertex4RGBA>* pVertices); 259 260 Context& m_context; 261 262 const VkFormat m_colorFormat; 263 const VkFormat m_depthStencilFormat; 264 tcu::IVec2 m_renderSize; 265 const bool m_useDepth; 266 const bool m_useStencil; 267 268 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 269 const VkPipelineColorBlendAttachmentState m_colorBlendState; 270 271 Move<VkImage> m_colorImage; 272 de::MovePtr<Allocation> m_colorImageAlloc; 273 Move<VkImageView> m_colorAttachmentView; 274 275 Move<VkImage> m_resolveImage; 276 de::MovePtr<Allocation> m_resolveImageAlloc; 277 Move<VkImageView> m_resolveAttachmentView; 278 279 Move<VkImage> m_depthStencilImage; 280 de::MovePtr<Allocation> m_depthStencilImageAlloc; 281 Move<VkImageView> m_depthStencilAttachmentView; 282 283 Move<VkRenderPass> m_renderPass; 284 Move<VkFramebuffer> m_framebuffer; 285 286 Move<VkShaderModule> m_vertexShaderModule; 287 Move<VkShaderModule> m_fragmentShaderModule; 288 289 Move<VkBuffer> m_vertexBuffer; 290 de::MovePtr<Allocation> m_vertexBufferAlloc; 291 292 Move<VkPipelineLayout> m_pipelineLayout; 293 std::vector<VkPipelineSp> m_graphicsPipelines; 294 295 Move<VkCommandPool> m_cmdPool; 296 Move<VkCommandBuffer> m_cmdBuffer; 297 298 Move<VkFence> m_fence; 299}; 300 301class RasterizationSamplesInstance : public vkt::TestInstance 302{ 303public: 304 RasterizationSamplesInstance (Context& context, 305 VkPrimitiveTopology topology, 306 const std::vector<Vertex4RGBA>& vertices, 307 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 308 const VkPipelineColorBlendAttachmentState& blendState, 309 const TestModeFlags modeFlags); 310 virtual ~RasterizationSamplesInstance (void) {} 311 312 virtual tcu::TestStatus iterate (void); 313 314protected: 315 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 316 317 const VkFormat m_colorFormat; 318 const tcu::IVec2 m_renderSize; 319 const VkPrimitiveTopology m_primitiveTopology; 320 const std::vector<Vertex4RGBA> m_vertices; 321 const std::vector<Vertex4RGBA> m_fullQuadVertices; //!< used by depth/stencil case 322 const TestModeFlags m_modeFlags; 323 de::MovePtr<MultisampleRenderer> m_multisampleRenderer; 324}; 325 326class MinSampleShadingInstance : public vkt::TestInstance 327{ 328public: 329 MinSampleShadingInstance (Context& context, 330 VkPrimitiveTopology topology, 331 const std::vector<Vertex4RGBA>& vertices, 332 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 333 const VkPipelineColorBlendAttachmentState& blendState); 334 virtual ~MinSampleShadingInstance (void) {} 335 336 virtual tcu::TestStatus iterate (void); 337 338protected: 339 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, 340 const tcu::ConstPixelBufferAccess& minShadingImage, 341 const tcu::ConstPixelBufferAccess& maxShadingImage); 342 const VkFormat m_colorFormat; 343 const tcu::IVec2 m_renderSize; 344 const VkPrimitiveTopology m_primitiveTopology; 345 const std::vector<Vertex4RGBA> m_vertices; 346 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 347 const VkPipelineColorBlendAttachmentState m_colorBlendState; 348}; 349 350class SampleMaskInstance : public vkt::TestInstance 351{ 352public: 353 SampleMaskInstance (Context& context, 354 VkPrimitiveTopology topology, 355 const std::vector<Vertex4RGBA>& vertices, 356 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 357 const VkPipelineColorBlendAttachmentState& blendState); 358 virtual ~SampleMaskInstance (void) {} 359 360 virtual tcu::TestStatus iterate (void); 361 362protected: 363 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, 364 const tcu::ConstPixelBufferAccess& minShadingImage, 365 const tcu::ConstPixelBufferAccess& maxShadingImage); 366 const VkFormat m_colorFormat; 367 const tcu::IVec2 m_renderSize; 368 const VkPrimitiveTopology m_primitiveTopology; 369 const std::vector<Vertex4RGBA> m_vertices; 370 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 371 const VkPipelineColorBlendAttachmentState m_colorBlendState; 372}; 373 374class AlphaToOneInstance : public vkt::TestInstance 375{ 376public: 377 AlphaToOneInstance (Context& context, 378 VkPrimitiveTopology topology, 379 const std::vector<Vertex4RGBA>& vertices, 380 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 381 const VkPipelineColorBlendAttachmentState& blendState); 382 virtual ~AlphaToOneInstance (void) {} 383 384 virtual tcu::TestStatus iterate (void); 385 386protected: 387 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 388 const tcu::ConstPixelBufferAccess& noAlphaOneImage); 389 const VkFormat m_colorFormat; 390 const tcu::IVec2 m_renderSize; 391 const VkPrimitiveTopology m_primitiveTopology; 392 const std::vector<Vertex4RGBA> m_vertices; 393 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 394 const VkPipelineColorBlendAttachmentState m_colorBlendState; 395}; 396 397class AlphaToCoverageInstance : public vkt::TestInstance 398{ 399public: 400 AlphaToCoverageInstance (Context& context, 401 VkPrimitiveTopology topology, 402 const std::vector<Vertex4RGBA>& vertices, 403 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 404 const VkPipelineColorBlendAttachmentState& blendState, 405 GeometryType geometryType); 406 virtual ~AlphaToCoverageInstance (void) {} 407 408 virtual tcu::TestStatus iterate (void); 409 410protected: 411 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result); 412 const VkFormat m_colorFormat; 413 const tcu::IVec2 m_renderSize; 414 const VkPrimitiveTopology m_primitiveTopology; 415 const std::vector<Vertex4RGBA> m_vertices; 416 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; 417 const VkPipelineColorBlendAttachmentState m_colorBlendState; 418 const GeometryType m_geometryType; 419}; 420 421 422// Helper functions 423 424void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType) 425{ 426 std::ostringstream vertexSource; 427 428 vertexSource << 429 "#version 310 es\n" 430 "layout(location = 0) in vec4 position;\n" 431 "layout(location = 1) in vec4 color;\n" 432 "layout(location = 0) out highp vec4 vtxColor;\n" 433 "void main (void)\n" 434 "{\n" 435 " gl_Position = position;\n" 436 " vtxColor = color;\n" 437 << (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? " gl_PointSize = 3.0f;\n" 438 : "" ) 439 << "}\n"; 440 441 static const char* fragmentSource = 442 "#version 310 es\n" 443 "layout(location = 0) in highp vec4 vtxColor;\n" 444 "layout(location = 0) out highp vec4 fragColor;\n" 445 "void main (void)\n" 446 "{\n" 447 " fragColor = vtxColor;\n" 448 "}\n"; 449 450 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str()); 451 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource); 452} 453 454bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples) 455{ 456 VkPhysicalDeviceProperties deviceProperties; 457 458 instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties); 459 460 return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples); 461} 462 463VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void) 464{ 465 const VkPipelineColorBlendAttachmentState colorBlendState = 466 { 467 false, // VkBool32 blendEnable; 468 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 469 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 470 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 471 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 472 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 473 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 474 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 475 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 476 }; 477 478 return colorBlendState; 479} 480 481deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image) 482{ 483 DE_ASSERT(image.getFormat().getPixelSize() == 4); 484 485 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences> 486 const deUint32 pixelCount = image.getWidth() * image.getHeight() * image.getDepth(); 487 488 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++) 489 { 490 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx); 491 492 if (histogram.find(pixelValue) != histogram.end()) 493 histogram[pixelValue]++; 494 else 495 histogram[pixelValue] = 1; 496 } 497 498 return (deUint32)histogram.size(); 499} 500 501VkImageAspectFlags getImageAspectFlags (const VkFormat format) 502{ 503 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 504 505 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 506 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; 507 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; 508 509 DE_ASSERT(false); 510 return 0u; 511} 512 513std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType) 514{ 515 std::vector<Vertex4RGBA> vertices; 516 517 switch (geometryType) 518 { 519 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 520 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: 521 { 522 Vertex4RGBA vertexData[3] = 523 { 524 { 525 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 526 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 527 }, 528 { 529 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 530 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 531 }, 532 { 533 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 534 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 535 } 536 }; 537 538 if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE) 539 { 540 for (int i = 0; i < 3; i++) 541 vertexData[i].color = tcu::Vec4(); 542 } 543 544 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3); 545 break; 546 } 547 548 case GEOMETRY_TYPE_OPAQUE_LINE: 549 { 550 const Vertex4RGBA vertexData[2] = 551 { 552 { 553 tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f), 554 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 555 }, 556 { 557 tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f), 558 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 559 } 560 }; 561 562 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2); 563 break; 564 } 565 566 case GEOMETRY_TYPE_OPAQUE_POINT: 567 { 568 const Vertex4RGBA vertex = 569 { 570 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 571 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 572 }; 573 574 vertices = std::vector<Vertex4RGBA>(1, vertex); 575 break; 576 } 577 578 case GEOMETRY_TYPE_OPAQUE_QUAD: 579 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 580 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 581 case GEOMETRY_TYPE_INVISIBLE_QUAD: 582 case GEOMETRY_TYPE_GRADIENT_QUAD: 583 { 584 Vertex4RGBA vertexData[4] = 585 { 586 { 587 tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), 588 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 589 }, 590 { 591 tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), 592 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 593 }, 594 { 595 tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), 596 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 597 }, 598 { 599 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), 600 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 601 } 602 }; 603 604 if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD) 605 { 606 for (int i = 0; i < 4; i++) 607 vertexData[i].color.w() = 0.25f; 608 } 609 else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD) 610 { 611 for (int i = 0; i < 4; i++) 612 vertexData[i].color.w() = 0.0f; 613 } 614 else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD) 615 { 616 vertexData[0].color.w() = 0.0f; 617 vertexData[2].color.w() = 0.0f; 618 } 619 else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH) 620 { 621 for (int i = 0; i < 4; i++) 622 vertexData[i].position.z() = 0.5f; 623 } 624 625 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4); 626 break; 627 } 628 629 default: 630 DE_ASSERT(false); 631 } 632 return vertices; 633} 634 635VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType) 636{ 637 switch (geometryType) 638 { 639 case GEOMETRY_TYPE_OPAQUE_TRIANGLE: 640 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 641 642 case GEOMETRY_TYPE_OPAQUE_LINE: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 643 case GEOMETRY_TYPE_OPAQUE_POINT: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 644 645 case GEOMETRY_TYPE_OPAQUE_QUAD: 646 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH: 647 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 648 case GEOMETRY_TYPE_INVISIBLE_QUAD: 649 case GEOMETRY_TYPE_GRADIENT_QUAD: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 650 651 default: 652 DE_ASSERT(false); 653 return VK_PRIMITIVE_TOPOLOGY_LAST; 654 } 655} 656 657bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format) 658{ 659 VkFormatProperties formatProps; 660 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps); 661 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; 662} 663 664VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil) 665{ 666 if (useDepth && !useStencil) 667 return VK_FORMAT_D16_UNORM; // must be supported 668 669 const InstanceInterface& vki = context.getInstanceInterface(); 670 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 671 672 // One of these formats must be supported. 673 674 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT)) 675 return VK_FORMAT_D24_UNORM_S8_UINT; 676 677 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT)) 678 return VK_FORMAT_D32_SFLOAT_S8_UINT; 679 680 return VK_FORMAT_UNDEFINED; 681} 682 683 684// MultisampleTest 685 686MultisampleTest::MultisampleTest (tcu::TestContext& testContext, 687 const std::string& name, 688 const std::string& description, 689 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 690 const VkPipelineColorBlendAttachmentState& blendState, 691 GeometryType geometryType) 692 : vkt::TestCase (testContext, name, description) 693 , m_multisampleStateParams (multisampleStateParams) 694 , m_colorBlendState (blendState) 695 , m_geometryType (geometryType) 696{ 697 if (m_multisampleStateParams.pSampleMask) 698 { 699 // Copy pSampleMask to avoid dependencies with other classes 700 701 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32); 702 703 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++) 704 m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]); 705 706 m_multisampleStateParams.pSampleMask = m_sampleMask.data(); 707 } 708} 709 710void MultisampleTest::initPrograms (SourceCollections& programCollection) const 711{ 712 initMultisamplePrograms(programCollection, m_geometryType); 713} 714 715TestInstance* MultisampleTest::createInstance (Context& context) const 716{ 717 return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState); 718} 719 720 721// RasterizationSamplesTest 722 723RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext& testContext, 724 const std::string& name, 725 const std::string& description, 726 VkSampleCountFlagBits rasterizationSamples, 727 GeometryType geometryType, 728 TestModeFlags modeFlags) 729 : MultisampleTest (testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType) 730 , m_modeFlags (modeFlags) 731{ 732} 733 734VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples) 735{ 736 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 737 { 738 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 739 DE_NULL, // const void* pNext; 740 0u, // VkPipelineMultisampleStateCreateFlags flags; 741 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 742 false, // VkBool32 sampleShadingEnable; 743 0.0f, // float minSampleShading; 744 DE_NULL, // const VkSampleMask* pSampleMask; 745 false, // VkBool32 alphaToCoverageEnable; 746 false // VkBool32 alphaToOneEnable; 747 }; 748 749 return multisampleStateParams; 750} 751 752TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context& context, 753 VkPrimitiveTopology topology, 754 const std::vector<Vertex4RGBA>& vertices, 755 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 756 const VkPipelineColorBlendAttachmentState& colorBlendState) const 757{ 758 return new RasterizationSamplesInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_modeFlags); 759} 760 761 762// MinSampleShadingTest 763 764MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext& testContext, 765 const std::string& name, 766 const std::string& description, 767 VkSampleCountFlagBits rasterizationSamples, 768 float minSampleShading, 769 GeometryType geometryType) 770 : MultisampleTest (testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType) 771{ 772} 773 774TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context, 775 VkPrimitiveTopology topology, 776 const std::vector<Vertex4RGBA>& vertices, 777 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 778 const VkPipelineColorBlendAttachmentState& colorBlendState) const 779{ 780 return new MinSampleShadingInstance(context, topology, vertices, multisampleStateParams, colorBlendState); 781} 782 783VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading) 784{ 785 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 786 { 787 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 788 DE_NULL, // const void* pNext; 789 0u, // VkPipelineMultisampleStateCreateFlags flags; 790 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 791 true, // VkBool32 sampleShadingEnable; 792 minSampleShading, // float minSampleShading; 793 DE_NULL, // const VkSampleMask* pSampleMask; 794 false, // VkBool32 alphaToCoverageEnable; 795 false // VkBool32 alphaToOneEnable; 796 }; 797 798 return multisampleStateParams; 799} 800 801 802// SampleMaskTest 803 804SampleMaskTest::SampleMaskTest (tcu::TestContext& testContext, 805 const std::string& name, 806 const std::string& description, 807 VkSampleCountFlagBits rasterizationSamples, 808 const std::vector<VkSampleMask>& sampleMask, 809 GeometryType geometryType) 810 : MultisampleTest (testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType) 811{ 812} 813 814TestInstance* SampleMaskTest::createMultisampleTestInstance (Context& context, 815 VkPrimitiveTopology topology, 816 const std::vector<Vertex4RGBA>& vertices, 817 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 818 const VkPipelineColorBlendAttachmentState& colorBlendState) const 819{ 820 return new SampleMaskInstance(context, topology,vertices, multisampleStateParams, colorBlendState); 821} 822 823VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask) 824{ 825 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 826 { 827 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 828 DE_NULL, // const void* pNext; 829 0u, // VkPipelineMultisampleStateCreateFlags flags; 830 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 831 false, // VkBool32 sampleShadingEnable; 832 0.0f, // float minSampleShading; 833 sampleMask.data(), // const VkSampleMask* pSampleMask; 834 false, // VkBool32 alphaToCoverageEnable; 835 false // VkBool32 alphaToOneEnable; 836 }; 837 838 return multisampleStateParams; 839} 840 841 842// AlphaToOneTest 843 844AlphaToOneTest::AlphaToOneTest (tcu::TestContext& testContext, 845 const std::string& name, 846 const std::string& description, 847 VkSampleCountFlagBits rasterizationSamples) 848 : MultisampleTest (testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD) 849{ 850} 851 852TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context& context, 853 VkPrimitiveTopology topology, 854 const std::vector<Vertex4RGBA>& vertices, 855 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 856 const VkPipelineColorBlendAttachmentState& colorBlendState) const 857{ 858 return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState); 859} 860 861VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples) 862{ 863 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 864 { 865 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 866 DE_NULL, // const void* pNext; 867 0u, // VkPipelineMultisampleStateCreateFlags flags; 868 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 869 false, // VkBool32 sampleShadingEnable; 870 0.0f, // float minSampleShading; 871 DE_NULL, // const VkSampleMask* pSampleMask; 872 false, // VkBool32 alphaToCoverageEnable; 873 true // VkBool32 alphaToOneEnable; 874 }; 875 876 return multisampleStateParams; 877} 878 879VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void) 880{ 881 const VkPipelineColorBlendAttachmentState colorBlendState = 882 { 883 true, // VkBool32 blendEnable; 884 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 885 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor; 886 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 887 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 888 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor; 889 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 890 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 891 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 892 }; 893 894 return colorBlendState; 895} 896 897 898// AlphaToCoverageTest 899 900AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext& testContext, 901 const std::string& name, 902 const std::string& description, 903 VkSampleCountFlagBits rasterizationSamples, 904 GeometryType geometryType) 905 : MultisampleTest (testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType) 906 , m_geometryType (geometryType) 907{ 908} 909 910TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context& context, 911 VkPrimitiveTopology topology, 912 const std::vector<Vertex4RGBA>& vertices, 913 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 914 const VkPipelineColorBlendAttachmentState& colorBlendState) const 915{ 916 return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType); 917} 918 919VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples) 920{ 921 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 922 { 923 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 924 DE_NULL, // const void* pNext; 925 0u, // VkPipelineMultisampleStateCreateFlags flags; 926 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 927 false, // VkBool32 sampleShadingEnable; 928 0.0f, // float minSampleShading; 929 DE_NULL, // const VkSampleMask* pSampleMask; 930 true, // VkBool32 alphaToCoverageEnable; 931 false // VkBool32 alphaToOneEnable; 932 }; 933 934 return multisampleStateParams; 935} 936 937// RasterizationSamplesInstance 938 939RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context, 940 VkPrimitiveTopology topology, 941 const std::vector<Vertex4RGBA>& vertices, 942 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 943 const VkPipelineColorBlendAttachmentState& blendState, 944 const TestModeFlags modeFlags) 945 : vkt::TestInstance (context) 946 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 947 , m_renderSize (32, 32) 948 , m_primitiveTopology (topology) 949 , m_vertices (vertices) 950 , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)) 951 , m_modeFlags (modeFlags) 952{ 953 if (m_modeFlags != 0) 954 { 955 const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0; 956 const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0; 957 const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil); 958 959 if (depthStencilFormat == VK_FORMAT_UNDEFINED) 960 TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported"); 961 962 const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }; 963 const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices }; 964 965 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 966 new MultisampleRenderer( 967 context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState)); 968 } 969 else 970 { 971 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>( 972 new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState)); 973 } 974} 975 976tcu::TestStatus RasterizationSamplesInstance::iterate (void) 977{ 978 de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render()); 979 return verifyImage(level->getAccess()); 980} 981 982tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 983{ 984 // Verify range of unique pixels 985 { 986 const deUint32 numUniqueColors = getUniqueColorsCount(result); 987 const deUint32 minUniqueColors = 3; 988 989 tcu::TestLog& log = m_context.getTestContext().getLog(); 990 991 log << tcu::TestLog::Message 992 << "\nMin. unique colors expected: " << minUniqueColors << "\n" 993 << "Unique colors found: " << numUniqueColors << "\n" 994 << tcu::TestLog::EndMessage; 995 996 if (numUniqueColors < minUniqueColors) 997 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 998 } 999 1000 // Verify shape of the rendered primitive (fuzzy-compare) 1001 { 1002 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 1003 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); 1004 const ColorVertexShader vertexShader; 1005 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); 1006 const rr::Program program (&vertexShader, &fragmentShader); 1007 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 1008 rr::RenderState renderState (refRenderer.getViewportState()); 1009 1010 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) 1011 { 1012 VkPhysicalDeviceProperties deviceProperties; 1013 1014 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties); 1015 1016 // gl_PointSize is clamped to pointSizeRange 1017 renderState.point.pointSize = deFloatMin(3.0f, deviceProperties.limits.pointSizeRange[1]); 1018 } 1019 1020 if (m_modeFlags == 0) 1021 { 1022 refRenderer.colorClear(tcu::Vec4(0.0f)); 1023 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 1024 } 1025 else 1026 { 1027 // For depth/stencil case the primitive is invisible and the surroundings are filled red. 1028 refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1029 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices); 1030 } 1031 1032 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT)) 1033 return tcu::TestStatus::fail("Primitive has unexpected shape"); 1034 } 1035 1036 return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds"); 1037} 1038 1039 1040// MinSampleShadingInstance 1041 1042MinSampleShadingInstance::MinSampleShadingInstance (Context& context, 1043 VkPrimitiveTopology topology, 1044 const std::vector<Vertex4RGBA>& vertices, 1045 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1046 const VkPipelineColorBlendAttachmentState& colorBlendState) 1047 : vkt::TestInstance (context) 1048 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1049 , m_renderSize (32, 32) 1050 , m_primitiveTopology (topology) 1051 , m_vertices (vertices) 1052 , m_multisampleStateParams (multisampleStateParams) 1053 , m_colorBlendState (colorBlendState) 1054{ 1055 VkPhysicalDeviceFeatures deviceFeatures; 1056 1057 m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures); 1058 1059 if (!deviceFeatures.sampleRateShading) 1060 throw tcu::NotSupportedError("Sample shading is not supported"); 1061} 1062 1063tcu::TestStatus MinSampleShadingInstance::iterate (void) 1064{ 1065 de::MovePtr<tcu::TextureLevel> testShadingImage; 1066 de::MovePtr<tcu::TextureLevel> minShadingImage; 1067 de::MovePtr<tcu::TextureLevel> maxShadingImage; 1068 1069 // Render with test minSampleShading 1070 { 1071 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState); 1072 testShadingImage = renderer.render(); 1073 } 1074 1075 // Render with minSampleShading = 0.0f 1076 { 1077 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1078 multisampleParams.minSampleShading = 0.0f; 1079 1080 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState); 1081 minShadingImage = renderer.render(); 1082 } 1083 1084 // Render with minSampleShading = 1.0f 1085 { 1086 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1087 multisampleParams.minSampleShading = 1.0f; 1088 1089 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState); 1090 maxShadingImage = renderer.render(); 1091 } 1092 1093 return verifyImage(testShadingImage->getAccess(), minShadingImage->getAccess(), maxShadingImage->getAccess()); 1094} 1095 1096tcu::TestStatus MinSampleShadingInstance::verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, const tcu::ConstPixelBufferAccess& minShadingImage, const tcu::ConstPixelBufferAccess& maxShadingImage) 1097{ 1098 const deUint32 testColorCount = getUniqueColorsCount(testShadingImage); 1099 const deUint32 minColorCount = getUniqueColorsCount(minShadingImage); 1100 const deUint32 maxColorCount = getUniqueColorsCount(maxShadingImage); 1101 1102 tcu::TestLog& log = m_context.getTestContext().getLog(); 1103 1104 log << tcu::TestLog::Message 1105 << "\nColors found: " << testColorCount << "\n" 1106 << "Min. colors expected: " << minColorCount << "\n" 1107 << "Max. colors expected: " << maxColorCount << "\n" 1108 << tcu::TestLog::EndMessage; 1109 1110 if (minColorCount > testColorCount || testColorCount > maxColorCount) 1111 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 1112 else 1113 return tcu::TestStatus::pass("Unique colors within expected bounds"); 1114} 1115 1116SampleMaskInstance::SampleMaskInstance (Context& context, 1117 VkPrimitiveTopology topology, 1118 const std::vector<Vertex4RGBA>& vertices, 1119 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1120 const VkPipelineColorBlendAttachmentState& blendState) 1121 : vkt::TestInstance (context) 1122 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1123 , m_renderSize (32, 32) 1124 , m_primitiveTopology (topology) 1125 , m_vertices (vertices) 1126 , m_multisampleStateParams (multisampleStateParams) 1127 , m_colorBlendState (blendState) 1128{ 1129} 1130 1131tcu::TestStatus SampleMaskInstance::iterate (void) 1132{ 1133 de::MovePtr<tcu::TextureLevel> testSampleMaskImage; 1134 de::MovePtr<tcu::TextureLevel> minSampleMaskImage; 1135 de::MovePtr<tcu::TextureLevel> maxSampleMaskImage; 1136 1137 // Render with test flags 1138 { 1139 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState); 1140 testSampleMaskImage = renderer.render(); 1141 } 1142 1143 // Render with all flags off 1144 { 1145 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1146 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0); 1147 1148 multisampleParams.pSampleMask = sampleMask.data(); 1149 1150 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState); 1151 minSampleMaskImage = renderer.render(); 1152 } 1153 1154 // Render with all flags on 1155 { 1156 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1157 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0)); 1158 1159 multisampleParams.pSampleMask = sampleMask.data(); 1160 1161 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState); 1162 maxSampleMaskImage = renderer.render(); 1163 } 1164 1165 return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess()); 1166} 1167 1168tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage, 1169 const tcu::ConstPixelBufferAccess& minSampleMaskImage, 1170 const tcu::ConstPixelBufferAccess& maxSampleMaskImage) 1171{ 1172 const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage); 1173 const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage); 1174 const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage); 1175 1176 tcu::TestLog& log = m_context.getTestContext().getLog(); 1177 1178 log << tcu::TestLog::Message 1179 << "\nColors found: " << testColorCount << "\n" 1180 << "Min. colors expected: " << minColorCount << "\n" 1181 << "Max. colors expected: " << maxColorCount << "\n" 1182 << tcu::TestLog::EndMessage; 1183 1184 if (minColorCount > testColorCount || testColorCount > maxColorCount) 1185 return tcu::TestStatus::fail("Unique colors out of expected bounds"); 1186 else 1187 return tcu::TestStatus::pass("Unique colors within expected bounds"); 1188} 1189 1190tcu::TestStatus testRasterSamplesConsistency (Context& context, GeometryType geometryType) 1191{ 1192 // Use triangle only. 1193 DE_UNREF(geometryType); 1194 1195 const VkSampleCountFlagBits samples[] = 1196 { 1197 VK_SAMPLE_COUNT_1_BIT, 1198 VK_SAMPLE_COUNT_2_BIT, 1199 VK_SAMPLE_COUNT_4_BIT, 1200 VK_SAMPLE_COUNT_8_BIT, 1201 VK_SAMPLE_COUNT_16_BIT, 1202 VK_SAMPLE_COUNT_32_BIT, 1203 VK_SAMPLE_COUNT_64_BIT 1204 }; 1205 1206 const Vertex4RGBA vertexData[3] = 1207 { 1208 { 1209 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f), 1210 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1211 }, 1212 { 1213 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f), 1214 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1215 }, 1216 { 1217 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f), 1218 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f) 1219 } 1220 }; 1221 1222 const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3); 1223 deUint32 prevUniqueColors = 2; 1224 int renderCount = 0; 1225 1226 // Do not render with 1 sample (start with samplesNdx = 1). 1227 for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 1228 { 1229 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx])) 1230 continue; 1231 1232 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1233 { 1234 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1235 DE_NULL, // const void* pNext; 1236 0u, // VkPipelineMultisampleStateCreateFlags flags; 1237 samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples; 1238 false, // VkBool32 sampleShadingEnable; 1239 0.0f, // float minSampleShading; 1240 DE_NULL, // const VkSampleMask* pSampleMask; 1241 false, // VkBool32 alphaToCoverageEnable; 1242 false // VkBool32 alphaToOneEnable; 1243 }; 1244 1245 MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState()); 1246 de::MovePtr<tcu::TextureLevel> result = renderer.render(); 1247 const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess()); 1248 1249 renderCount++; 1250 1251 if (prevUniqueColors > uniqueColors) 1252 { 1253 std::ostringstream message; 1254 1255 message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx]; 1256 return tcu::TestStatus::fail(message.str()); 1257 } 1258 1259 prevUniqueColors = uniqueColors; 1260 } 1261 1262 if (renderCount == 0) 1263 throw tcu::NotSupportedError("Multisampling is unsupported"); 1264 1265 return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases"); 1266} 1267 1268 1269// AlphaToOneInstance 1270 1271AlphaToOneInstance::AlphaToOneInstance (Context& context, 1272 VkPrimitiveTopology topology, 1273 const std::vector<Vertex4RGBA>& vertices, 1274 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1275 const VkPipelineColorBlendAttachmentState& blendState) 1276 : vkt::TestInstance (context) 1277 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1278 , m_renderSize (32, 32) 1279 , m_primitiveTopology (topology) 1280 , m_vertices (vertices) 1281 , m_multisampleStateParams (multisampleStateParams) 1282 , m_colorBlendState (blendState) 1283{ 1284 VkPhysicalDeviceFeatures deviceFeatures; 1285 1286 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures); 1287 1288 if (!deviceFeatures.alphaToOne) 1289 throw tcu::NotSupportedError("Alpha-to-one is not supported"); 1290} 1291 1292tcu::TestStatus AlphaToOneInstance::iterate (void) 1293{ 1294 DE_ASSERT(m_multisampleStateParams.alphaToOneEnable); 1295 DE_ASSERT(m_colorBlendState.blendEnable); 1296 1297 de::MovePtr<tcu::TextureLevel> alphaOneImage; 1298 de::MovePtr<tcu::TextureLevel> noAlphaOneImage; 1299 1300 // Render with blend enabled and alpha to one on 1301 { 1302 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState); 1303 alphaOneImage = renderer.render(); 1304 } 1305 1306 // Render with blend enabled and alpha to one off 1307 { 1308 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams; 1309 multisampleParams.alphaToOneEnable = false; 1310 1311 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState); 1312 noAlphaOneImage = renderer.render(); 1313 } 1314 1315 return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess()); 1316} 1317 1318tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage, 1319 const tcu::ConstPixelBufferAccess& noAlphaOneImage) 1320{ 1321 for (int y = 0; y < m_renderSize.y(); y++) 1322 { 1323 for (int x = 0; x < m_renderSize.x(); x++) 1324 { 1325 if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y)))) 1326 { 1327 std::ostringstream message; 1328 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y); 1329 return tcu::TestStatus::fail(message.str()); 1330 } 1331 } 1332 } 1333 1334 return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one"); 1335} 1336 1337 1338// AlphaToCoverageInstance 1339 1340AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context, 1341 VkPrimitiveTopology topology, 1342 const std::vector<Vertex4RGBA>& vertices, 1343 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1344 const VkPipelineColorBlendAttachmentState& blendState, 1345 GeometryType geometryType) 1346 : vkt::TestInstance (context) 1347 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1348 , m_renderSize (32, 32) 1349 , m_primitiveTopology (topology) 1350 , m_vertices (vertices) 1351 , m_multisampleStateParams (multisampleStateParams) 1352 , m_colorBlendState (blendState) 1353 , m_geometryType (geometryType) 1354{ 1355} 1356 1357tcu::TestStatus AlphaToCoverageInstance::iterate (void) 1358{ 1359 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable); 1360 1361 de::MovePtr<tcu::TextureLevel> result; 1362 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState); 1363 1364 result = renderer.render(); 1365 1366 return verifyImage(result->getAccess()); 1367} 1368 1369tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result) 1370{ 1371 float maxColorValue; 1372 1373 switch (m_geometryType) 1374 { 1375 case GEOMETRY_TYPE_OPAQUE_QUAD: 1376 maxColorValue = 1.01f; 1377 break; 1378 1379 case GEOMETRY_TYPE_TRANSLUCENT_QUAD: 1380 maxColorValue = 0.52f; 1381 break; 1382 1383 case GEOMETRY_TYPE_INVISIBLE_QUAD: 1384 maxColorValue = 0.01f; 1385 break; 1386 1387 default: 1388 maxColorValue = 0.0f; 1389 DE_ASSERT(false); 1390 } 1391 1392 for (int y = 0; y < m_renderSize.y(); y++) 1393 { 1394 for (int x = 0; x < m_renderSize.x(); x++) 1395 { 1396 if (result.getPixel(x, y).x() > maxColorValue) 1397 { 1398 std::ostringstream message; 1399 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")"; 1400 return tcu::TestStatus::fail(message.str()); 1401 } 1402 } 1403 } 1404 1405 return tcu::TestStatus::pass("Image matches reference value"); 1406} 1407 1408 1409// MultisampleRenderer 1410 1411MultisampleRenderer::MultisampleRenderer (Context& context, 1412 const VkFormat colorFormat, 1413 const tcu::IVec2& renderSize, 1414 const VkPrimitiveTopology topology, 1415 const std::vector<Vertex4RGBA>& vertices, 1416 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1417 const VkPipelineColorBlendAttachmentState& blendState) 1418 : m_context (context) 1419 , m_colorFormat (colorFormat) 1420 , m_depthStencilFormat (VK_FORMAT_UNDEFINED) 1421 , m_renderSize (renderSize) 1422 , m_useDepth (false) 1423 , m_useStencil (false) 1424 , m_multisampleStateParams (multisampleStateParams) 1425 , m_colorBlendState (blendState) 1426{ 1427 initialize(context, 1u, &topology, &vertices); 1428} 1429 1430MultisampleRenderer::MultisampleRenderer (Context& context, 1431 const VkFormat colorFormat, 1432 const VkFormat depthStencilFormat, 1433 const tcu::IVec2& renderSize, 1434 const bool useDepth, 1435 const bool useStencil, 1436 const deUint32 numTopologies, 1437 const VkPrimitiveTopology* pTopology, 1438 const std::vector<Vertex4RGBA>* pVertices, 1439 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams, 1440 const VkPipelineColorBlendAttachmentState& blendState) 1441 : m_context (context) 1442 , m_colorFormat (colorFormat) 1443 , m_depthStencilFormat (depthStencilFormat) 1444 , m_renderSize (renderSize) 1445 , m_useDepth (useDepth) 1446 , m_useStencil (useStencil) 1447 , m_multisampleStateParams (multisampleStateParams) 1448 , m_colorBlendState (blendState) 1449{ 1450 initialize(context, numTopologies, pTopology, pVertices); 1451} 1452 1453void MultisampleRenderer::initialize (Context& context, 1454 const deUint32 numTopologies, 1455 const VkPrimitiveTopology* pTopology, 1456 const std::vector<Vertex4RGBA>* pVertices) 1457{ 1458 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples)) 1459 throw tcu::NotSupportedError("Unsupported number of rasterization samples"); 1460 1461 const DeviceInterface& vk = context.getDeviceInterface(); 1462 const VkDevice vkDevice = context.getDevice(); 1463 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1464 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 1465 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 1466 1467 // Create color image 1468 { 1469 const VkImageCreateInfo colorImageParams = 1470 { 1471 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1472 DE_NULL, // const void* pNext; 1473 0u, // VkImageCreateFlags flags; 1474 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1475 m_colorFormat, // VkFormat format; 1476 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1477 1u, // deUint32 mipLevels; 1478 1u, // deUint32 arrayLayers; 1479 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1480 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1481 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 1482 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1483 1u, // deUint32 queueFamilyIndexCount; 1484 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1485 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1486 }; 1487 1488 m_colorImage = createImage(vk, vkDevice, &colorImageParams); 1489 1490 // Allocate and bind color image memory 1491 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 1492 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 1493 } 1494 1495 // Create resolve image 1496 { 1497 const VkImageCreateInfo resolveImageParams = 1498 { 1499 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1500 DE_NULL, // const void* pNext; 1501 0u, // VkImageCreateFlags flags; 1502 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1503 m_colorFormat, // VkFormat format; 1504 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1505 1u, // deUint32 mipLevels; 1506 1u, // deUint32 arrayLayers; 1507 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1508 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1509 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage; 1510 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1511 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1512 1u, // deUint32 queueFamilyIndexCount; 1513 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1514 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1515 }; 1516 1517 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams); 1518 1519 // Allocate and bind resolve image memory 1520 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any); 1521 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset())); 1522 } 1523 1524 // Create a depth/stencil image 1525 if (m_useDepth || m_useStencil) 1526 { 1527 const VkImageCreateInfo depthStencilImageParams = 1528 { 1529 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1530 DE_NULL, // const void* pNext; 1531 0u, // VkImageCreateFlags flags; 1532 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1533 m_depthStencilFormat, // VkFormat format; 1534 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 1535 1u, // deUint32 mipLevels; 1536 1u, // deUint32 arrayLayers; 1537 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1538 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1539 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage; 1540 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1541 1u, // deUint32 queueFamilyIndexCount; 1542 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1543 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1544 }; 1545 1546 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams); 1547 1548 // Allocate and bind depth/stencil image memory 1549 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any); 1550 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset())); 1551 } 1552 1553 // Create color attachment view 1554 { 1555 const VkImageViewCreateInfo colorAttachmentViewParams = 1556 { 1557 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1558 DE_NULL, // const void* pNext; 1559 0u, // VkImageViewCreateFlags flags; 1560 *m_colorImage, // VkImage image; 1561 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1562 m_colorFormat, // VkFormat format; 1563 componentMappingRGBA, // VkComponentMapping components; 1564 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1565 }; 1566 1567 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 1568 } 1569 1570 // Create resolve attachment view 1571 { 1572 const VkImageViewCreateInfo resolveAttachmentViewParams = 1573 { 1574 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1575 DE_NULL, // const void* pNext; 1576 0u, // VkImageViewCreateFlags flags; 1577 *m_resolveImage, // VkImage image; 1578 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1579 m_colorFormat, // VkFormat format; 1580 componentMappingRGBA, // VkComponentMapping components; 1581 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1582 }; 1583 1584 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams); 1585 } 1586 1587 VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0; 1588 const deUint32 numUsedAttachments = (m_useDepth || m_useStencil ? 3u : 2u); 1589 1590 // Create depth/stencil attachment view 1591 if (m_useDepth || m_useStencil) 1592 { 1593 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat); 1594 1595 const VkImageViewCreateInfo depthStencilAttachmentViewParams = 1596 { 1597 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1598 DE_NULL, // const void* pNext; 1599 0u, // VkImageViewCreateFlags flags; 1600 *m_depthStencilImage, // VkImage image; 1601 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1602 m_depthStencilFormat, // VkFormat format; 1603 componentMappingRGBA, // VkComponentMapping components; 1604 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1605 }; 1606 1607 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams); 1608 } 1609 1610 // Create render pass 1611 { 1612 const VkAttachmentDescription attachmentDescriptions[3] = 1613 { 1614 { 1615 0u, // VkAttachmentDescriptionFlags flags; 1616 m_colorFormat, // VkFormat format; 1617 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1618 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1619 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1620 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1621 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1622 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1623 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1624 }, 1625 { 1626 0u, // VkAttachmentDescriptionFlags flags; 1627 m_colorFormat, // VkFormat format; 1628 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1629 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 1630 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1631 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1632 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1633 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1634 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1635 }, 1636 { 1637 0u, // VkAttachmentDescriptionFlags flags; 1638 m_depthStencilFormat, // VkFormat format; 1639 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples; 1640 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp; 1641 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp; 1642 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp; 1643 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp; 1644 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 1645 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 1646 }, 1647 }; 1648 1649 const VkAttachmentReference colorAttachmentReference = 1650 { 1651 0u, // deUint32 attachment; 1652 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1653 }; 1654 1655 const VkAttachmentReference resolveAttachmentReference = 1656 { 1657 1u, // deUint32 attachment; 1658 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1659 }; 1660 1661 const VkAttachmentReference depthStencilAttachmentReference = 1662 { 1663 2u, // deUint32 attachment; 1664 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; 1665 }; 1666 1667 const VkSubpassDescription subpassDescription = 1668 { 1669 0u, // VkSubpassDescriptionFlags flags; 1670 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1671 0u, // deUint32 inputAttachmentCount; 1672 DE_NULL, // const VkAttachmentReference* pInputAttachments; 1673 1u, // deUint32 colorAttachmentCount; 1674 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 1675 &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments; 1676 (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment; 1677 0u, // deUint32 preserveAttachmentCount; 1678 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 1679 }; 1680 1681 const VkRenderPassCreateInfo renderPassParams = 1682 { 1683 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 1684 DE_NULL, // const void* pNext; 1685 0u, // VkRenderPassCreateFlags flags; 1686 numUsedAttachments, // deUint32 attachmentCount; 1687 attachmentDescriptions, // const VkAttachmentDescription* pAttachments; 1688 1u, // deUint32 subpassCount; 1689 &subpassDescription, // const VkSubpassDescription* pSubpasses; 1690 0u, // deUint32 dependencyCount; 1691 DE_NULL // const VkSubpassDependency* pDependencies; 1692 }; 1693 1694 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 1695 } 1696 1697 // Create framebuffer 1698 { 1699 const VkImageView attachments[3] = 1700 { 1701 *m_colorAttachmentView, 1702 *m_resolveAttachmentView, 1703 *m_depthStencilAttachmentView 1704 }; 1705 1706 const VkFramebufferCreateInfo framebufferParams = 1707 { 1708 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 1709 DE_NULL, // const void* pNext; 1710 0u, // VkFramebufferCreateFlags flags; 1711 *m_renderPass, // VkRenderPass renderPass; 1712 numUsedAttachments, // deUint32 attachmentCount; 1713 attachments, // const VkImageView* pAttachments; 1714 (deUint32)m_renderSize.x(), // deUint32 width; 1715 (deUint32)m_renderSize.y(), // deUint32 height; 1716 1u // deUint32 layers; 1717 }; 1718 1719 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 1720 } 1721 1722 // Create pipeline layout 1723 { 1724 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1725 { 1726 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1727 DE_NULL, // const void* pNext; 1728 0u, // VkPipelineLayoutCreateFlags flags; 1729 0u, // deUint32 setLayoutCount; 1730 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 1731 0u, // deUint32 pushConstantRangeCount; 1732 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1733 }; 1734 1735 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1736 } 1737 1738 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 1739 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 1740 1741 // Create pipeline 1742 { 1743 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 1744 { 1745 { 1746 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1747 DE_NULL, // const void* pNext; 1748 0u, // VkPipelineShaderStageCreateFlags flags; 1749 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 1750 *m_vertexShaderModule, // VkShaderModule module; 1751 "main", // const char* pName; 1752 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1753 }, 1754 { 1755 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1756 DE_NULL, // const void* pNext; 1757 0u, // VkPipelineShaderStageCreateFlags flags; 1758 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 1759 *m_fragmentShaderModule, // VkShaderModule module; 1760 "main", // const char* pName; 1761 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1762 } 1763 }; 1764 1765 const VkVertexInputBindingDescription vertexInputBindingDescription = 1766 { 1767 0u, // deUint32 binding; 1768 sizeof(Vertex4RGBA), // deUint32 stride; 1769 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; 1770 }; 1771 1772 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 1773 { 1774 { 1775 0u, // deUint32 location; 1776 0u, // deUint32 binding; 1777 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1778 0u // deUint32 offset; 1779 }, 1780 { 1781 1u, // deUint32 location; 1782 0u, // deUint32 binding; 1783 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1784 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset; 1785 } 1786 }; 1787 1788 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1789 { 1790 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1791 DE_NULL, // const void* pNext; 1792 0u, // VkPipelineVertexInputStateCreateFlags flags; 1793 1u, // deUint32 vertexBindingDescriptionCount; 1794 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1795 2u, // deUint32 vertexAttributeDescriptionCount; 1796 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1797 }; 1798 1799 // Topology is set before the pipeline creation. 1800 VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1801 { 1802 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1803 DE_NULL, // const void* pNext; 1804 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 1805 VK_PRIMITIVE_TOPOLOGY_LAST, // VkPrimitiveTopology topology; 1806 false // VkBool32 primitiveRestartEnable; 1807 }; 1808 1809 const VkViewport viewport = 1810 { 1811 0.0f, // float x; 1812 0.0f, // float y; 1813 (float)m_renderSize.x(), // float width; 1814 (float)m_renderSize.y(), // float height; 1815 0.0f, // float minDepth; 1816 1.0f // float maxDepth; 1817 }; 1818 1819 const VkRect2D scissor = 1820 { 1821 { 0, 0 }, // VkOffset2D offset; 1822 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } // VkExtent2D extent; 1823 }; 1824 1825 const VkPipelineViewportStateCreateInfo viewportStateParams = 1826 { 1827 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1828 DE_NULL, // const void* pNext; 1829 0u, // VkPipelineViewportStateCreateFlags flags; 1830 1u, // deUint32 viewportCount; 1831 &viewport, // const VkViewport* pViewports; 1832 1u, // deUint32 scissorCount; 1833 &scissor // const VkRect2D* pScissors; 1834 }; 1835 1836 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1837 { 1838 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1839 DE_NULL, // const void* pNext; 1840 0u, // VkPipelineRasterizationStateCreateFlags flags; 1841 false, // VkBool32 depthClampEnable; 1842 false, // VkBool32 rasterizerDiscardEnable; 1843 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 1844 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 1845 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1846 VK_FALSE, // VkBool32 depthBiasEnable; 1847 0.0f, // float depthBiasConstantFactor; 1848 0.0f, // float depthBiasClamp; 1849 0.0f, // float depthBiasSlopeFactor; 1850 1.0f // float lineWidth; 1851 }; 1852 1853 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1854 { 1855 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1856 DE_NULL, // const void* pNext; 1857 0u, // VkPipelineColorBlendStateCreateFlags flags; 1858 false, // VkBool32 logicOpEnable; 1859 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1860 1u, // deUint32 attachmentCount; 1861 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1862 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 1863 }; 1864 1865 const VkStencilOpState stencilOpState = 1866 { 1867 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 1868 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp; 1869 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 1870 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp; 1871 1u, // deUint32 compareMask; 1872 1u, // deUint32 writeMask; 1873 1u, // deUint32 reference; 1874 }; 1875 1876 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 1877 { 1878 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 1879 DE_NULL, // const void* pNext; 1880 0u, // VkPipelineDepthStencilStateCreateFlags flags; 1881 m_useDepth, // VkBool32 depthTestEnable; 1882 m_useDepth, // VkBool32 depthWriteEnable; 1883 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 1884 false, // VkBool32 depthBoundsTestEnable; 1885 m_useStencil, // VkBool32 stencilTestEnable; 1886 stencilOpState, // VkStencilOpState front; 1887 stencilOpState, // VkStencilOpState back; 1888 0.0f, // float minDepthBounds; 1889 1.0f, // float maxDepthBounds; 1890 }; 1891 1892 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1893 { 1894 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1895 DE_NULL, // const void* pNext; 1896 0u, // VkPipelineCreateFlags flags; 1897 2u, // deUint32 stageCount; 1898 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 1899 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1900 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1901 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1902 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1903 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 1904 &m_multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1905 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1906 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1907 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1908 *m_pipelineLayout, // VkPipelineLayout layout; 1909 *m_renderPass, // VkRenderPass renderPass; 1910 0u, // deUint32 subpass; 1911 0u, // VkPipeline basePipelineHandle; 1912 0u // deInt32 basePipelineIndex; 1913 }; 1914 1915 for (deUint32 i = 0u; i < numTopologies; ++i) 1916 { 1917 inputAssemblyStateParams.topology = pTopology[i]; 1918 m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams)))); 1919 } 1920 } 1921 1922 // Create vertex buffer 1923 { 1924 const VkBufferCreateInfo vertexBufferParams = 1925 { 1926 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1927 DE_NULL, // const void* pNext; 1928 0u, // VkBufferCreateFlags flags; 1929 1024u, // VkDeviceSize size; 1930 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1931 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1932 1u, // deUint32 queueFamilyIndexCount; 1933 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1934 }; 1935 1936 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 1937 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 1938 1939 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 1940 1941 // Load vertices into vertex buffer 1942 { 1943 Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr()); 1944 for (deUint32 i = 0u; i < numTopologies; ++i) 1945 { 1946 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA)); 1947 pDst += pVertices[i].size(); 1948 } 1949 } 1950 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size); 1951 } 1952 1953 // Create command pool 1954 { 1955 const VkCommandPoolCreateInfo cmdPoolParams = 1956 { 1957 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1958 DE_NULL, // const void* pNext; 1959 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 1960 queueFamilyIndex, // deUint32 queueFamilyIndex; 1961 }; 1962 1963 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1964 } 1965 1966 // Create command buffer 1967 { 1968 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 1969 { 1970 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1971 DE_NULL, // const void* pNext; 1972 *m_cmdPool, // VkCommandPool commandPool; 1973 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1974 1u // deUint32 bufferCount; 1975 }; 1976 1977 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1978 { 1979 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1980 DE_NULL, // const void* pNext; 1981 0u, // VkCommandBufferUsageFlags flags; 1982 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1983 }; 1984 1985 VkClearValue colorClearValue; 1986 colorClearValue.color.float32[0] = 0.0f; 1987 colorClearValue.color.float32[1] = 0.0f; 1988 colorClearValue.color.float32[2] = 0.0f; 1989 colorClearValue.color.float32[3] = 0.0f; 1990 1991 VkClearValue depthStencilClearValue; 1992 depthStencilClearValue.depthStencil.depth = 1.0f; 1993 depthStencilClearValue.depthStencil.stencil = 0u; 1994 1995 const VkClearValue clearValues[3] = 1996 { 1997 colorClearValue, 1998 colorClearValue, 1999 depthStencilClearValue 2000 }; 2001 2002 const VkRenderPassBeginInfo renderPassBeginInfo = 2003 { 2004 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2005 DE_NULL, // const void* pNext; 2006 *m_renderPass, // VkRenderPass renderPass; 2007 *m_framebuffer, // VkFramebuffer framebuffer; 2008 { 2009 { 0, 0 }, 2010 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } 2011 }, // VkRect2D renderArea; 2012 numUsedAttachments, // deUint32 clearValueCount; 2013 clearValues // const VkClearValue* pClearValues; 2014 }; 2015 2016 const VkImageMemoryBarrier imageLayoutBarriers[] = 2017 { 2018 // color attachment image 2019 { 2020 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2021 DE_NULL, // const void* pNext; 2022 0u, // VkAccessFlags srcAccessMask; 2023 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2024 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2025 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2026 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2027 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2028 *m_colorImage, // VkImage image; 2029 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2030 }, 2031 // resolve attachment image 2032 { 2033 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2034 DE_NULL, // const void* pNext; 2035 0u, // VkAccessFlags srcAccessMask; 2036 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2037 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2038 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2039 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2040 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2041 *m_resolveImage, // VkImage image; 2042 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2043 }, 2044 // depth/stencil attachment image 2045 { 2046 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2047 DE_NULL, // const void* pNext; 2048 0u, // VkAccessFlags srcAccessMask; 2049 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 2050 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2051 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 2052 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2053 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2054 *m_depthStencilImage, // VkImage image; 2055 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 2056 }, 2057 }; 2058 2059 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 2060 2061 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 2062 2063 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 2064 0u, DE_NULL, 0u, DE_NULL, numUsedAttachments, imageLayoutBarriers); 2065 2066 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 2067 2068 VkDeviceSize vertexBufferOffset = 0u; 2069 2070 for (deUint32 i = 0u; i < numTopologies; ++i) 2071 { 2072 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]); 2073 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 2074 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0); 2075 2076 vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA)); 2077 } 2078 2079 vk.cmdEndRenderPass(*m_cmdBuffer); 2080 2081 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 2082 } 2083 2084 // Create fence 2085 { 2086 const VkFenceCreateInfo fenceParams = 2087 { 2088 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 2089 DE_NULL, // const void* pNext; 2090 0u // VkFenceCreateFlags flags; 2091 }; 2092 2093 m_fence = createFence(vk, vkDevice, &fenceParams); 2094 } 2095} 2096 2097MultisampleRenderer::~MultisampleRenderer (void) 2098{ 2099} 2100 2101de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void) 2102{ 2103 const DeviceInterface& vk = m_context.getDeviceInterface(); 2104 const VkDevice vkDevice = m_context.getDevice(); 2105 const VkQueue queue = m_context.getUniversalQueue(); 2106 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 2107 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 2108 const VkSubmitInfo submitInfo = 2109 { 2110 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 2111 DE_NULL, // const void* pNext; 2112 0u, // deUint32 waitSemaphoreCount; 2113 DE_NULL, // const VkSemaphore* pWaitSemaphores; 2114 (const VkPipelineStageFlags*)DE_NULL, 2115 1u, // deUint32 commandBufferCount; 2116 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 2117 0u, // deUint32 signalSemaphoreCount; 2118 DE_NULL // const VkSemaphore* pSignalSemaphores; 2119 }; 2120 2121 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 2122 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 2123 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 2124 2125 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>()); 2126} 2127 2128} // anonymous 2129 2130tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx) 2131{ 2132 const VkSampleCountFlagBits samples[] = 2133 { 2134 VK_SAMPLE_COUNT_2_BIT, 2135 VK_SAMPLE_COUNT_4_BIT, 2136 VK_SAMPLE_COUNT_8_BIT, 2137 VK_SAMPLE_COUNT_16_BIT, 2138 VK_SAMPLE_COUNT_32_BIT, 2139 VK_SAMPLE_COUNT_64_BIT 2140 }; 2141 2142 de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", "")); 2143 2144 // Rasterization samples tests 2145 { 2146 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", "")); 2147 2148 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2149 { 2150 std::ostringstream caseName; 2151 caseName << "samples_" << samples[samplesNdx]; 2152 2153 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2154 2155 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2156 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE)); 2157 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT)); 2158 2159 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT)); 2160 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_STENCIL_BIT)); 2161 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT)); 2162 2163 rasterizationSamplesTests->addChild(samplesTests.release()); 2164 } 2165 2166 multisampleTests->addChild(rasterizationSamplesTests.release()); 2167 } 2168 2169 // Raster samples consistency check 2170 { 2171 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", "")); 2172 2173 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(), 2174 "unique_colors_check", 2175 "", 2176 initMultisamplePrograms, 2177 testRasterSamplesConsistency, 2178 GEOMETRY_TYPE_OPAQUE_TRIANGLE); 2179 2180 multisampleTests->addChild(rasterSamplesConsistencyTests.release()); 2181 } 2182 2183 // minSampleShading tests 2184 { 2185 struct TestConfig 2186 { 2187 const char* name; 2188 float minSampleShading; 2189 }; 2190 2191 const TestConfig testConfigs[] = 2192 { 2193 { "min_0_0", 0.0f }, 2194 { "min_0_25", 0.25f }, 2195 { "min_0_5", 0.5f }, 2196 { "min_0_75", 0.75f }, 2197 { "min_1_0", 1.0f } 2198 }; 2199 2200 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", "")); 2201 2202 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 2203 { 2204 const TestConfig& testConfig = testConfigs[configNdx]; 2205 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, "")); 2206 2207 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2208 { 2209 std::ostringstream caseName; 2210 caseName << "samples_" << samples[samplesNdx]; 2211 2212 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2213 2214 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2215 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE)); 2216 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT)); 2217 2218 minShadingValueTests->addChild(samplesTests.release()); 2219 } 2220 2221 minSampleShadingTests->addChild(minShadingValueTests.release()); 2222 } 2223 2224 multisampleTests->addChild(minSampleShadingTests.release()); 2225 } 2226 2227 // pSampleMask tests 2228 { 2229 struct TestConfig 2230 { 2231 const char* name; 2232 const char* description; 2233 VkSampleMask sampleMask; 2234 }; 2235 2236 const TestConfig testConfigs[] = 2237 { 2238 { "mask_all_on", "All mask bits are off", 0x0 }, 2239 { "mask_all_off", "All mask bits are on", 0xFFFFFFFF }, 2240 { "mask_one", "All mask elements are 0x1", 0x1}, 2241 { "mask_random", "All mask elements are 0xAAAAAAAA", 0xAAAAAAAA }, 2242 }; 2243 2244 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", "")); 2245 2246 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++) 2247 { 2248 const TestConfig& testConfig = testConfigs[configNdx]; 2249 de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description)); 2250 2251 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2252 { 2253 std::ostringstream caseName; 2254 caseName << "samples_" << samples[samplesNdx]; 2255 2256 const deUint32 sampleMaskCount = samples[samplesNdx] / 32; 2257 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2258 2259 std::vector<VkSampleMask> mask; 2260 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++) 2261 mask.push_back(testConfig.sampleMask); 2262 2263 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE)); 2264 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE)); 2265 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT)); 2266 2267 sampleMaskValueTests->addChild(samplesTests.release()); 2268 } 2269 2270 sampleMaskTests->addChild(sampleMaskValueTests.release()); 2271 } 2272 2273 multisampleTests->addChild(sampleMaskTests.release()); 2274 2275 } 2276 2277 // AlphaToOne tests 2278 { 2279 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", "")); 2280 2281 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2282 { 2283 std::ostringstream caseName; 2284 caseName << "samples_" << samples[samplesNdx]; 2285 2286 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx])); 2287 } 2288 2289 multisampleTests->addChild(alphaToOneTests.release()); 2290 } 2291 2292 // AlphaToCoverageEnable tests 2293 { 2294 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", "")); 2295 2296 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++) 2297 { 2298 std::ostringstream caseName; 2299 caseName << "samples_" << samples[samplesNdx]; 2300 2301 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), "")); 2302 2303 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD)); 2304 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD)); 2305 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD)); 2306 2307 alphaToCoverageTests->addChild(samplesTests.release()); 2308 } 2309 multisampleTests->addChild(alphaToCoverageTests.release()); 2310 } 2311 2312 // Sampling from a multisampled image texture (texelFetch) 2313 { 2314 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx)); 2315 } 2316 2317 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.) 2318 { 2319 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx)); 2320 } 2321 2322 return multisampleTests.release(); 2323} 2324 2325} // pipeline 2326} // vkt 2327