1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2021 The Khronos Group Inc. 6 * Copyright (c) 2023 LunarG, Inc. 7 * Copyright (c) 2023 Nintendo 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Tests for VK_EXT_multisampled_render_to_single_sampled 24 *//*--------------------------------------------------------------------*/ 25 26#include "vktPipelineMultisampledRenderToSingleSampledTests.hpp" 27#include "vktPipelineMakeUtil.hpp" 28#include "vktTestCase.hpp" 29#include "vktTestCaseUtil.hpp" 30#include "vktTestGroupUtil.hpp" 31 32#include "vkCmdUtil.hpp" 33#include "vkObjUtil.hpp" 34#include "vkPlatform.hpp" 35#include "vkMemUtil.hpp" 36#include "vkQueryUtil.hpp" 37#include "vkTypeUtil.hpp" 38#include "vkRefUtil.hpp" 39#include "vkBuilderUtil.hpp" 40#include "vkPrograms.hpp" 41#include "vkImageUtil.hpp" 42#include "vkPipelineConstructionUtil.hpp" 43 44#include "deUniquePtr.hpp" 45#include "deSharedPtr.hpp" 46#include "deRandom.hpp" 47#include "deMath.h" 48 49#include "tcuVector.hpp" 50#include "tcuTestLog.hpp" 51#include "tcuImageCompare.hpp" 52#include "tcuTextureUtil.hpp" 53#include "tcuRGBA.hpp" 54 55#include <string> 56#include <vector> 57 58 59// For testing, logs 60#define DEBUG_LOGS 0 61 62#if DEBUG_LOGS 63#define DBG(...) fprintf(stderr, __VA_ARGS__) 64#else 65#define DBG(...) ((void)0) 66#endif 67 68 69namespace vkt 70{ 71namespace pipeline 72{ 73namespace 74{ 75using namespace vk; 76using de::UniquePtr; 77using de::MovePtr; 78using de::SharedPtr; 79using tcu::IVec2; 80using tcu::UVec2; 81using tcu::Vec2; 82using tcu::Vec4; 83using tcu::IVec4; 84using tcu::UVec4; 85 86VkImageAspectFlags getDepthStencilAspectFlags (const VkFormat format) 87{ 88 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 89 90 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 91 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; 92 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; 93 94 DE_ASSERT(false); 95 return 0u; 96} 97 98inline bool isDepthFormat (const VkFormat format) 99{ 100 return (getDepthStencilAspectFlags(format) & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; 101} 102 103inline bool isStencilFormat (const VkFormat format) 104{ 105 return (getDepthStencilAspectFlags(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; 106} 107 108using PipelineSp = SharedPtr<Unique<VkPipeline>>; 109 110// How many regions to render to in multi-pass tests 111constexpr deUint32 RegionCount = 4; 112 113struct DrawPushConstants 114{ 115 Vec4 color1Data[2]; 116 Vec4 color2Data[2]; 117 IVec4 color3Data[2]; 118 Vec2 depthData; 119}; 120 121struct VerifyPushConstants 122{ 123 Vec4 color1Data[2] = {Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0)}; 124 Vec4 color2Data[2] = {Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0)}; 125 IVec4 color3Data[2] = {IVec4(0, 0, 0, 0), IVec4(0, 0, 0, 0)}; 126 float depthData = 0; 127 deUint32 stencilData = 0; 128}; 129 130struct VerificationResults 131{ 132 deUint32 color1Verification; 133 deUint32 color2Verification; 134 deUint32 color3Verification; 135 deUint32 depthVerification; 136 deUint32 stencilVerification; 137}; 138 139struct VerifySingleFloatPushConstants 140{ 141 UVec4 area; 142 Vec4 color; 143 deUint32 attachmentNdx; 144}; 145 146struct VerifySingleIntPushConstants 147{ 148 UVec4 area; 149 IVec4 color; 150 deUint32 attachmentNdx; 151}; 152 153struct VerifySingleDepthPushConstants 154{ 155 UVec4 area; 156 float depthData; 157}; 158 159struct VerifySingleStencilPushConstants 160{ 161 UVec4 area; 162 deUint32 stencilData; 163}; 164 165//! The parameters that define a test case 166struct TestParams 167{ 168 VkSampleCountFlagBits numFloatColor1Samples; //!< VkAttachmentDescription::samples and VkImageCreateInfo::samples 169 VkSampleCountFlagBits numFloatColor2Samples; //!< VkAttachmentDescription::samples and VkImageCreateInfo::samples 170 VkSampleCountFlagBits numIntColorSamples; //!< VkAttachmentDescription::samples and VkImageCreateInfo::samples 171 VkSampleCountFlagBits numDepthStencilSamples; //!< VkAttachmentDescription::samples and VkImageCreateInfo::samples 172 173 VkFormat floatColor1Format; //!< Color attachment format 174 VkFormat floatColor2Format; //!< Color attachment format 175 VkFormat intColorFormat; //!< Color attachment format 176 VkFormat depthStencilFormat; //!< D/S attachment format. Will test both aspects if it's a mixed format 177 178 VkClearValue clearValues[4]; 179 180 VerifyPushConstants verifyConstants[RegionCount]; 181 182 bool isMultisampledRenderToSingleSampled; //!< Whether the test should use VK_EXT_multisampled_render_to_single_sampled or normal multisampling 183 bool clearBeforeRenderPass; //!< Whether loadOp=CLEAR should be used, or clear is done before render pass and loadOp=LOAD is used 184 bool renderToWholeFramebuffer; //!< Whether the test should render to the whole framebuffer. 185 bool testBlendsColors; //!< Whether the test blends colors or overwrites them. Tests don't adapt to this automatically, it's informative for shader generation. 186 bool dynamicRendering; //!< Whether the test should use dynamic rendering. 187 bool useGarbageAttachment; //!< Whether the test uese garbage attachments. 188 189 struct PerPass 190 { 191 VkSampleCountFlagBits numSamples; //!< Pipeline samples 192 193 deInt32 floatColor1Location; 194 deInt32 floatColor2Location; 195 deInt32 intColorLocation; 196 bool hasDepthStencil; 197 198 bool resolveFloatColor1; 199 bool resolveFloatColor2; 200 bool resolveIntColor; 201 bool resolveDepthStencil; 202 203 VkResolveModeFlagBits depthStencilResolveMode; 204 205 DrawPushConstants drawConstantsWithDepthWrite[RegionCount]; 206 DrawPushConstants drawConstantsWithDepthTest[RegionCount]; 207 }; 208 209 std::vector<PerPass> perPass; 210 211 // Used to carry forward the rng seed from test generation to test run. 212 deUint32 rngSeed; 213 214 PipelineConstructionType pipelineConstructionType; 215 216 TestParams () 217 : numFloatColor1Samples {} 218 , numFloatColor2Samples {} 219 , numIntColorSamples {} 220 , numDepthStencilSamples {} 221 , floatColor1Format {} 222 , floatColor2Format {} 223 , intColorFormat {} 224 , depthStencilFormat {} 225 , clearValues {} 226 { 227 } 228 229 bool usesColor1InPass (const size_t passNdx) const { return perPass[passNdx].floatColor1Location >= 0; } 230 bool usesColor2InPass (const size_t passNdx) const { return perPass[passNdx].floatColor2Location >= 0; } 231 bool usesColor3InPass (const size_t passNdx) const { return perPass[passNdx].intColorLocation >= 0; } 232 bool usesDepthStencilInPass (const size_t passNdx) const { return perPass[passNdx].hasDepthStencil; } 233}; 234 235struct Image 236{ 237 Move<VkImage> image; 238 MovePtr<Allocation> alloc; 239 Move<VkImageView> view; 240 241 void allocate(const DeviceInterface& vk, 242 const VkDevice device, 243 const MovePtr<Allocator>& allocator, 244 const VkFormat format, 245 const UVec2& size, 246 const VkSampleCountFlagBits samples, 247 const VkImageUsageFlags usage, 248 const VkImageAspectFlags aspect, 249 const deUint32 layerCount, 250 const bool usedForMSRTSS); 251 Move<VkImageView> makeView(const DeviceInterface& vk, 252 const VkDevice device, 253 const VkFormat format, 254 const VkImageAspectFlags aspect, 255 const deUint32 layerCount); 256}; 257 258//! Common data used by the test 259struct WorkingData 260{ 261 UVec2 framebufferSize; //!< Size of the framebuffer 262 UVec4 renderArea; //!< Render area 263 264 Move<VkBuffer> vertexBuffer; //!< Contains a fullscreen triangle 265 MovePtr<Allocation> vertexBufferAlloc; //!< Storage for vertexBuffer 266 Move<VkBuffer> verificationBuffer; //!< Buffer used for validation 267 MovePtr<Allocation> verificationBufferAlloc; //!< Storage for verificationBuffer 268 Move<VkBuffer> singleVerificationBuffer; //!< Buffer used for validation of attachments outside the render area 269 MovePtr<Allocation> singleVerificationBufferAlloc; //!< Storage for singleVerificationBuffer 270 271 //!< Color and depth/stencil attachments 272 Image floatColor1; 273 Image floatColor2; 274 Image intColor; 275 Image depthStencil; 276 Move<VkImageView> depthOnlyImageView; 277 Move<VkImageView> stencilOnlyImageView; 278 279 //!< Resolve attachments 280 Image floatResolve1; 281 Image floatResolve2; 282 Image intResolve; 283 Image depthStencilResolve; 284 Move<VkImageView> depthOnlyResolveImageView; 285 Move<VkImageView> stencilOnlyResolveImageView; 286 287 //!< Verification results for logging (an array of 5 to avoid hitting maxPerStageDescriptorStorageImages limit of 4. 288 Image verify; 289 290 WorkingData (void) {} 291 292 Move<VkImage>& getResolvedFloatColorImage1(const TestParams& params) 293 { 294 return params.numFloatColor1Samples != VK_SAMPLE_COUNT_1_BIT ? floatResolve1.image : floatColor1.image; 295 } 296 Move<VkImage>& getResolvedFloatColorImage2(const TestParams& params) 297 { 298 return params.numFloatColor2Samples != VK_SAMPLE_COUNT_1_BIT ? floatResolve2.image : floatColor2.image; 299 } 300 Move<VkImage>& getResolvedIntColorImage(const TestParams& params) 301 { 302 return params.numIntColorSamples != VK_SAMPLE_COUNT_1_BIT ? intResolve.image : intColor.image; 303 } 304 Move<VkImage>& getResolvedDepthStencilImage(const TestParams& params) 305 { 306 return params.numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT ? depthStencilResolve.image : depthStencil.image; 307 } 308 309 Move<VkImageView>& getResolvedFloatColorImage1View(const TestParams& params) 310 { 311 return params.numFloatColor1Samples != VK_SAMPLE_COUNT_1_BIT ? floatResolve1.view : floatColor1.view; 312 } 313 Move<VkImageView>& getResolvedFloatColorImage2View(const TestParams& params) 314 { 315 return params.numFloatColor2Samples != VK_SAMPLE_COUNT_1_BIT ? floatResolve2.view : floatColor2.view; 316 } 317 Move<VkImageView>& getResolvedIntColorImageView(const TestParams& params) 318 { 319 return params.numIntColorSamples != VK_SAMPLE_COUNT_1_BIT ? intResolve.view : intColor.view; 320 } 321 Move<VkImageView>& getResolvedDepthOnlyImageView(const TestParams& params) 322 { 323 // If no depth aspect, return the stencil view just to have something bound in the desc set 324 if (!isDepthFormat(params.depthStencilFormat)) 325 return getResolvedStencilOnlyImageView(params); 326 return params.numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT ? depthOnlyResolveImageView : depthOnlyImageView; 327 } 328 Move<VkImageView>& getResolvedStencilOnlyImageView(const TestParams& params) 329 { 330 // If no stencil aspect, return the depth view just to have something bound in the desc set 331 if (!isStencilFormat(params.depthStencilFormat)) 332 return getResolvedDepthOnlyImageView(params); 333 return params.numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT ? stencilOnlyResolveImageView : stencilOnlyImageView; 334 } 335}; 336 337// Accumulate objects throughout the test to avoid them getting deleted before the command buffer is submitted and waited on. 338// Speeds up the test by avoiding making multiple submissions and waits. 339class TestObjects 340{ 341public: 342 TestObjects(Context& contextIn); 343 344 void beginCommandBuffer(); 345 void submitCommandsAndWait(); 346 347 const Unique<VkCommandPool> cmdPool; 348 const Unique<VkCommandBuffer> cmdBuffer; 349 std::vector<PipelineSp> computePipelines; 350 std::vector<MovePtr<GraphicsPipelineWrapper>> graphicsPipelines; 351 std::vector<Move<VkDescriptorPool>> descriptorPools; 352 std::vector<Move<VkDescriptorSet>> descriptorSets; 353 std::vector<RenderPassWrapper> renderPassFramebuffers; 354 355private: 356 Context& context; 357}; 358 359const VkImageUsageFlags commonImageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 360const VkImageUsageFlags colorImageUsageFlags = commonImageUsageFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 361const VkImageUsageFlags depthStencilImageUsageFlags = commonImageUsageFlags | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 362 363Move<VkImage> makeImage (const DeviceInterface& vk, 364 const VkDevice device, 365 const VkFormat format, 366 const UVec2& size, 367 const deUint32 layerCount, 368 const VkSampleCountFlagBits samples, 369 const VkImageUsageFlags usage, 370 const bool usedForMSRTSS) 371{ 372 const VkImageCreateFlags createFlags = samples == VK_SAMPLE_COUNT_1_BIT && usedForMSRTSS ? VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT : 0; 373 374 const VkImageCreateInfo imageParams = 375 { 376 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 377 DE_NULL, // const void* pNext; 378 createFlags, // VkImageCreateFlags flags; 379 VK_IMAGE_TYPE_2D, // VkImageType imageType; 380 format, // VkFormat format; 381 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; 382 1u, // deUint32 mipLevels; 383 layerCount, // deUint32 arrayLayers; 384 samples, // VkSampleCountFlagBits samples; 385 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 386 usage, // VkImageUsageFlags usage; 387 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 388 0u, // deUint32 queueFamilyIndexCount; 389 DE_NULL, // const deUint32* pQueueFamilyIndices; 390 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 391 }; 392 return createImage(vk, device, &imageParams); 393} 394 395void Image::allocate (const DeviceInterface& vk, 396 const VkDevice device, 397 const MovePtr<Allocator>& allocator, 398 const VkFormat format, 399 const UVec2& size, 400 const VkSampleCountFlagBits samples, 401 const VkImageUsageFlags usage, 402 const VkImageAspectFlags aspect, 403 const deUint32 layerCount, 404 const bool usedForMSRTSS) 405{ 406 image = makeImage(vk, device, format, size, layerCount, samples, usage, usedForMSRTSS); 407 alloc = bindImage(vk, device, *allocator, *image, MemoryRequirement::Any); 408 view = makeView(vk, device, format, aspect, layerCount); 409} 410 411Move<VkImageView> Image::makeView(const DeviceInterface& vk, 412 const VkDevice device, 413 const VkFormat format, 414 const VkImageAspectFlags aspect, 415 const deUint32 layerCount) 416{ 417 return makeImageView(vk, device, *image, layerCount > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, format, makeImageSubresourceRange(aspect, 0u, 1u, 0u, layerCount)); 418} 419 420//! Create a test-specific MSAA pipeline 421MovePtr<GraphicsPipelineWrapper> makeGraphicsPipeline (const InstanceInterface& vki, 422 const DeviceInterface& vk, 423 const VkPhysicalDevice physicalDevice, 424 const VkDevice device, 425 const std::vector<std::string>& deviceExtensions, 426 const PipelineConstructionType pipelineConstructionType, 427 const PipelineLayoutWrapper& pipelineLayout, 428 const VkRenderPass renderPass, 429 VkPipelineRenderingCreateInfoKHR* pipelineRenderingCreateInfo, 430 const ShaderWrapper vertexModule, 431 const ShaderWrapper fragmentModule, 432 const bool enableBlend, 433 const bool enableDepthStencilWrite, 434 const bool enableDepthTest, 435 const deUint32 intWriteMask, 436 const deUint32 subpassNdx, 437 const deInt32 integerAttachmentLocation, 438 const UVec4& viewportIn, 439 const UVec4& scissorIn, 440 const VkSampleCountFlagBits numSamples, 441 const bool garbageAttachment) 442{ 443 std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions; 444 std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions; 445 446 // Vertex attributes: position 447 vertexInputBindingDescriptions.push_back (makeVertexInputBindingDescription (0u, sizeof(Vec4), VK_VERTEX_INPUT_RATE_VERTEX)); 448 vertexInputAttributeDescriptions.push_back(makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u)); 449 450 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 451 { 452 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 453 DE_NULL, // const void* pNext; 454 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 455 static_cast<deUint32>(vertexInputBindingDescriptions.size()), // uint32_t vertexBindingDescriptionCount; 456 dataOrNullPtr(vertexInputBindingDescriptions), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 457 static_cast<deUint32>(vertexInputAttributeDescriptions.size()), // uint32_t vertexAttributeDescriptionCount; 458 dataOrNullPtr(vertexInputAttributeDescriptions), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 459 }; 460 461 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 462 { 463 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 464 DE_NULL, // const void* pNext; 465 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 466 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 467 VK_FALSE, // VkBool32 primitiveRestartEnable; 468 }; 469 470 const std::vector<VkViewport> viewports 471 {{ 472 static_cast<float>(viewportIn.x()), static_cast<float>(viewportIn.y()), // x, y 473 static_cast<float>(viewportIn.z()), static_cast<float>(viewportIn.w()), // width, height 474 0.0f, 1.0f // minDepth, maxDepth 475 }}; 476 477 const std::vector<VkRect2D> scissors = 478 {{ 479 makeOffset2D(scissorIn.x(), scissorIn.y()), 480 makeExtent2D(scissorIn.z(), scissorIn.w()), 481 }}; 482 483 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 484 { 485 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 486 DE_NULL, // const void* pNext; 487 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 488 VK_FALSE, // VkBool32 depthClampEnable; 489 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 490 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 491 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 492 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 493 VK_FALSE, // VkBool32 depthBiasEnable; 494 0.0f, // float depthBiasConstantFactor; 495 0.0f, // float depthBiasClamp; 496 0.0f, // float depthBiasSlopeFactor; 497 1.0f, // float lineWidth; 498 }; 499 500 VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 501 { 502 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 503 DE_NULL, // const void* pNext; 504 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 505 numSamples, // VkSampleCountFlagBits rasterizationSamples; 506 VK_TRUE, // VkBool32 sampleShadingEnable; 507 1.0f, // float minSampleShading; 508 DE_NULL, // const VkSampleMask* pSampleMask; 509 VK_FALSE, // VkBool32 alphaToCoverageEnable; 510 VK_FALSE // VkBool32 alphaToOneEnable; 511 }; 512 513 // Simply increment the buffer 514 const VkStencilOpState stencilOpState = makeStencilOpState( 515 VK_STENCIL_OP_KEEP, // stencil fail 516 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // depth & stencil pass 517 VK_STENCIL_OP_KEEP, // depth only fail 518 VK_COMPARE_OP_ALWAYS, // compare op 519 ~0u, // compare mask 520 ~0u, // write mask 521 0u); // reference 522 523 // Enable depth write and test if needed 524 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 525 { 526 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 527 DE_NULL, // const void* pNext; 528 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 529 VK_TRUE, // VkBool32 depthTestEnable; 530 enableDepthStencilWrite, // VkBool32 depthWriteEnable; 531 enableDepthTest ? VK_COMPARE_OP_GREATER : VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp; 532 VK_FALSE, // VkBool32 depthBoundsTestEnable; 533 VK_TRUE, // VkBool32 stencilTestEnable; 534 stencilOpState, // VkStencilOpState front; 535 stencilOpState, // VkStencilOpState back; 536 0.0f, // float minDepthBounds; 537 1.0f, // float maxDepthBounds; 538 }; 539 540 // Always blend by addition. This is used to verify the combination of multiple draw calls. 541 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 542 VkPipelineColorBlendAttachmentState defaultBlendAttachmentState = 543 { 544 enableBlend 545 ? VK_TRUE 546 : VK_FALSE, // VkBool32 blendEnable; 547 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 548 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 549 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 550 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 551 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 552 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 553 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 554 }; 555 556 VkPipelineColorBlendAttachmentState blendAttachmentStates[4] = 557 { 558 defaultBlendAttachmentState, 559 defaultBlendAttachmentState, 560 defaultBlendAttachmentState, 561 defaultBlendAttachmentState, 562 }; 563 564 if (enableBlend && integerAttachmentLocation >= 0) 565 { 566 // Disable blend for the integer attachment unconditionally 567 blendAttachmentStates[integerAttachmentLocation].blendEnable = VK_FALSE; 568 // But emulate it by outputting to one channel only. 569 blendAttachmentStates[integerAttachmentLocation].colorWriteMask = 570 ((intWriteMask & 1) != 0 ? VK_COLOR_COMPONENT_R_BIT : 0) | 571 ((intWriteMask & 2) != 0 ? VK_COLOR_COMPONENT_G_BIT : 0) | 572 ((intWriteMask & 4) != 0 ? VK_COLOR_COMPONENT_B_BIT : 0) | 573 ((intWriteMask & 8) != 0 ? VK_COLOR_COMPONENT_A_BIT : 0); 574 DE_ASSERT(blendAttachmentStates[integerAttachmentLocation].colorWriteMask != 0); 575 } 576 577 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 578 { 579 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 580 DE_NULL, // const void* pNext; 581 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 582 VK_FALSE, // VkBool32 logicOpEnable; 583 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 584 4u, // deUint32 attachmentCount; 585 blendAttachmentStates, // const VkPipelineColorBlendAttachmentState* pAttachments; 586 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 587 }; 588 589 VkPipelineRenderingCreateInfo pipelineRenderingCreateInfoWithGarbage; 590 std::vector<VkFormat> garbageFormats; 591 592 if (garbageAttachment) 593 { 594 DE_ASSERT(pipelineRenderingCreateInfo); 595 596 for (int i = 0; i < 10; i++) 597 garbageFormats.push_back(VK_FORMAT_UNDEFINED); 598 599 pipelineRenderingCreateInfoWithGarbage = *pipelineRenderingCreateInfo; 600 // Just set a bunch of VK_FORMAT_UNDEFINED for garbage_color_attachment tests to make the validation happy. 601 pipelineRenderingCreateInfoWithGarbage.colorAttachmentCount = static_cast<uint32_t>(garbageFormats.size()); 602 pipelineRenderingCreateInfoWithGarbage.pColorAttachmentFormats = garbageFormats.data(); 603 } 604 605 MovePtr<GraphicsPipelineWrapper> graphicsPipeline = MovePtr<GraphicsPipelineWrapper>(new GraphicsPipelineWrapper(vki, vk, physicalDevice, device, deviceExtensions, pipelineConstructionType, 0u)); 606 graphicsPipeline.get()->setMonolithicPipelineLayout(pipelineLayout) 607 .setupVertexInputState(&vertexInputStateInfo, 608 &pipelineInputAssemblyStateInfo) 609 .setupPreRasterizationShaderState(viewports, 610 scissors, 611 pipelineLayout, 612 renderPass, 613 subpassNdx, 614 vertexModule, 615 &pipelineRasterizationStateInfo, 616 ShaderWrapper(), 617 ShaderWrapper(), 618 ShaderWrapper(), 619 DE_NULL, 620 nullptr, 621 garbageAttachment ? &pipelineRenderingCreateInfoWithGarbage : pipelineRenderingCreateInfo) 622 .setupFragmentShaderState(pipelineLayout, 623 renderPass, 624 subpassNdx, 625 fragmentModule, 626 &pipelineDepthStencilStateInfo, 627 &pipelineMultisampleStateInfo) 628 .setRenderingColorAttachmentsInfo(pipelineRenderingCreateInfo) 629 .setupFragmentOutputState(renderPass, 630 subpassNdx, 631 &pipelineColorBlendStateInfo, 632 &pipelineMultisampleStateInfo) 633 .buildPipeline(); 634 635 return graphicsPipeline; 636} 637 638void logTestImages(Context& context, 639 const TestParams& params, 640 WorkingData& wd, 641 const bool drawsToColor1, 642 const bool drawsToColor2, 643 const bool drawsToColor3, 644 const bool drawsToDepthStencil) 645{ 646 const DeviceInterface& vk = context.getDeviceInterface(); 647 const VkDevice device = context.getDevice(); 648 MovePtr<Allocator> allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))); 649 tcu::TestLog& log = context.getTestContext().getLog(); 650 651 const VkDeviceSize bufferSize[4] = 652 { 653 wd.framebufferSize.x() * wd.framebufferSize.y() * tcu::getPixelSize(mapVkFormat(params.floatColor1Format)), 654 wd.framebufferSize.x() * wd.framebufferSize.y() * tcu::getPixelSize(mapVkFormat(params.floatColor2Format)), 655 wd.framebufferSize.x() * wd.framebufferSize.y() * tcu::getPixelSize(mapVkFormat(params.intColorFormat)), 656 wd.framebufferSize.x() * wd.framebufferSize.y() * tcu::getPixelSize(mapVkFormat(params.depthStencilFormat)), 657 }; 658 const Move<VkBuffer> buffer[5] = 659 { 660 makeBuffer(vk, device, bufferSize[0], VK_BUFFER_USAGE_TRANSFER_DST_BIT), 661 makeBuffer(vk, device, bufferSize[1], VK_BUFFER_USAGE_TRANSFER_DST_BIT), 662 makeBuffer(vk, device, bufferSize[2], VK_BUFFER_USAGE_TRANSFER_DST_BIT), 663 makeBuffer(vk, device, bufferSize[3], VK_BUFFER_USAGE_TRANSFER_DST_BIT), 664 makeBuffer(vk, device, bufferSize[3], VK_BUFFER_USAGE_TRANSFER_DST_BIT), 665 }; 666 const MovePtr<Allocation> bufferAlloc[5] = 667 { 668 bindBuffer(vk, device, *allocator, *buffer[0], MemoryRequirement::HostVisible), 669 bindBuffer(vk, device, *allocator, *buffer[1], MemoryRequirement::HostVisible), 670 bindBuffer(vk, device, *allocator, *buffer[2], MemoryRequirement::HostVisible), 671 bindBuffer(vk, device, *allocator, *buffer[3], MemoryRequirement::HostVisible), 672 bindBuffer(vk, device, *allocator, *buffer[4], MemoryRequirement::HostVisible), 673 }; 674 675 for (deUint32 bufferNdx = 0; bufferNdx < 5; ++bufferNdx) 676 invalidateAlloc(vk, device, *bufferAlloc[bufferNdx]); 677 678 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex())); 679 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 680 681 beginCommandBuffer(vk, *cmdBuffer); 682 683 const IVec2 size (wd.framebufferSize.x(), wd.framebufferSize.y()); 684 { 685 if (drawsToColor1) 686 copyImageToBuffer(vk, *cmdBuffer, *wd.getResolvedFloatColorImage1(params), *buffer[0], size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); 687 if (drawsToColor2) 688 copyImageToBuffer(vk, *cmdBuffer, *wd.getResolvedFloatColorImage2(params), *buffer[1], size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); 689 if (drawsToColor3) 690 copyImageToBuffer(vk, *cmdBuffer, *wd.getResolvedIntColorImage(params), *buffer[2], size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); 691 692 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 693 if (drawsToDepthStencil && isDepthFormat(params.depthStencilFormat)) 694 { 695 copyImageToBuffer(vk, *cmdBuffer, *wd.getResolvedDepthStencilImage(params), *buffer[3], size, VK_ACCESS_SHADER_WRITE_BIT, depthStencilLayout, 1, 696 getDepthStencilAspectFlags(params.depthStencilFormat), VK_IMAGE_ASPECT_DEPTH_BIT); 697 depthStencilLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 698 } 699 if (drawsToDepthStencil && isStencilFormat(params.depthStencilFormat)) 700 { 701 copyImageToBuffer(vk, *cmdBuffer, *wd.getResolvedDepthStencilImage(params), *buffer[4], size, VK_ACCESS_SHADER_WRITE_BIT, depthStencilLayout, 1, 702 getDepthStencilAspectFlags(params.depthStencilFormat), VK_IMAGE_ASPECT_STENCIL_BIT); 703 } 704 } 705 706 endCommandBuffer(vk, *cmdBuffer); 707 submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer); 708 709 // For the D32 depth formats, we specify the texture format directly as tcu::getEffectiveDepthStencilAccess assumes stencil data is interleaved. 710 // For the D24 format however, we have to use tcu::getEffectiveDepthStencilAccess to correctly account for the 8-bit padding. 711 const tcu::TextureFormat copiedDepthFormat = tcu::TextureFormat(tcu::TextureFormat::D, 712 params.depthStencilFormat == VK_FORMAT_D16_UNORM ? tcu::TextureFormat::UNORM_INT16 713 : tcu::TextureFormat::FLOAT); 714 const tcu::TextureFormat copiedStencilFormat = tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8); 715 716 const tcu::ConstPixelBufferAccess testImageData[5] = 717 { 718 { mapVkFormat(params.floatColor1Format), size.x(), size.y(), 1, bufferAlloc[0]->getHostPtr() }, 719 { mapVkFormat(params.floatColor2Format), size.x(), size.y(), 1, bufferAlloc[1]->getHostPtr() }, 720 { mapVkFormat(params.intColorFormat), size.x(), size.y(), 1, bufferAlloc[2]->getHostPtr() }, 721 { copiedDepthFormat, size.x(), size.y(), 1, bufferAlloc[3]->getHostPtr() }, 722 { copiedStencilFormat, size.x(), size.y(), 1, bufferAlloc[4]->getHostPtr() }, 723 }; 724 725 const tcu::ConstPixelBufferAccess testImageDataD24 = tcu::getEffectiveDepthStencilAccess(tcu::ConstPixelBufferAccess(mapVkFormat(params.depthStencilFormat), 726 size.x(), size.y(), 1, bufferAlloc[3]->getHostPtr()), 727 tcu::Sampler::MODE_DEPTH); 728 729 log << tcu::TestLog::ImageSet("attachments", "attachments"); 730 if (drawsToColor1) 731 log << tcu::TestLog::Image("Color attachment 1", "Color attachment 1", testImageData[0]); 732 if (drawsToColor2) 733 log << tcu::TestLog::Image("Color attachment 2", "Color attachment 2", testImageData[1]); 734 if (drawsToColor3) 735 log << tcu::TestLog::Image("Color attachment 3", "Color attachment 3", testImageData[2]); 736 if (isDepthFormat(params.depthStencilFormat)) 737 log << tcu::TestLog::Image("Depth attachment", "Depth attachment", params.depthStencilFormat == VK_FORMAT_D24_UNORM_S8_UINT ? testImageDataD24 : testImageData[3]); 738 if (isStencilFormat(params.depthStencilFormat)) 739 log << tcu::TestLog::Image("Stencil attachment", "Stencil attachment", testImageData[4]); 740 log << tcu::TestLog::EndImageSet; 741} 742 743void logVerifyImages(Context& context, 744 const TestParams& params, 745 WorkingData& wd, 746 const bool drawsToColor1, 747 const bool drawsToColor2, 748 const bool drawsToColor3, 749 const bool drawsToDepthStencil) 750{ 751 const DeviceInterface& vk = context.getDeviceInterface(); 752 const VkDevice device = context.getDevice(); 753 MovePtr<Allocator> allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))); 754 tcu::TestLog& log = context.getTestContext().getLog(); 755 756 const VkDeviceSize bufferSize = wd.framebufferSize.x() * wd.framebufferSize.y() * 5 * tcu::getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 757 const Move<VkBuffer> buffer = makeBuffer(vk, device, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT); 758 const MovePtr<Allocation> bufferAlloc = bindBuffer(vk, device, *allocator, *buffer, MemoryRequirement::HostVisible); 759 760 invalidateAlloc(vk, device, *bufferAlloc); 761 762 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex())); 763 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 764 765 beginCommandBuffer(vk, *cmdBuffer); 766 767 copyImageToBuffer(vk, *cmdBuffer, *wd.verify.image, *buffer, IVec2(wd.framebufferSize.x(), wd.framebufferSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, 5); 768 769 endCommandBuffer(vk, *cmdBuffer); 770 submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer); 771 772 const tcu::ConstPixelBufferAccess verifyImageData (mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), wd.framebufferSize.x(), wd.framebufferSize.y(), 5, bufferAlloc->getHostPtr()); 773 774 log << tcu::TestLog::ImageSet("attachment error mask", "attachment error mask"); 775 if (drawsToColor1) 776 log << tcu::TestLog::Image("ErrorMask color attachment 1", "Error mask color attachment 1", tcu::getSubregion(verifyImageData, 0, 0, 0, wd.framebufferSize.x(), wd.framebufferSize.y(), 1)); 777 if (drawsToColor2) 778 log << tcu::TestLog::Image("ErrorMask color attachment 2", "Error mask color attachment 2", tcu::getSubregion(verifyImageData, 0, 0, 1, wd.framebufferSize.x(), wd.framebufferSize.y(), 1)); 779 if (drawsToColor3) 780 log << tcu::TestLog::Image("ErrorMask color attachment 3", "Error mask color attachment 3", tcu::getSubregion(verifyImageData, 0, 0, 2, wd.framebufferSize.x(), wd.framebufferSize.y(), 1)); 781 if (drawsToDepthStencil && isDepthFormat(params.depthStencilFormat)) 782 log << tcu::TestLog::Image("ErrorMask depth attachment", "Error mask depth attachment", tcu::getSubregion(verifyImageData, 0, 0, 3, wd.framebufferSize.x(), wd.framebufferSize.y(), 1)); 783 if (drawsToDepthStencil && isStencilFormat(params.depthStencilFormat)) 784 log << tcu::TestLog::Image("ErrorMask stencil attachment", "Error mask stencil attachment", tcu::getSubregion(verifyImageData, 0, 0, 4, wd.framebufferSize.x(), wd.framebufferSize.y(), 1)); 785 log << tcu::TestLog::EndImageSet; 786} 787 788bool checkAndReportError (Context& context, 789 const deUint32 verifiedPixelCount, 790 const deUint32 expectedPixelCount, 791 const std::string& attachment) 792{ 793 tcu::TestLog& log = context.getTestContext().getLog(); 794 795 bool passed = verifiedPixelCount == expectedPixelCount; 796 797 if (passed) 798 log << tcu::TestLog::Message << "Verification passed for " << attachment << tcu::TestLog::EndMessage; 799 else 800 log << tcu::TestLog::Message << "Verification failed for " << attachment << " for " << (expectedPixelCount - verifiedPixelCount) << " pixel(s)" << tcu::TestLog::EndMessage; 801 802 return passed; 803} 804 805void checkSampleRequirements (Context& context, 806 const VkSampleCountFlagBits numSamples, 807 const bool checkColor, 808 const bool checkDepth, 809 const bool checkStencil) 810{ 811 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits; 812 813 if (checkColor && (limits.framebufferColorSampleCounts & numSamples) == 0u) 814 TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported"); 815 816 if (checkDepth && (limits.framebufferDepthSampleCounts & numSamples) == 0u) 817 TCU_THROW(NotSupportedError, "framebufferDepthSampleCounts: sample count not supported"); 818 819 if (checkStencil && (limits.framebufferStencilSampleCounts & numSamples) == 0u) 820 TCU_THROW(NotSupportedError, "framebufferStencilSampleCounts: sample count not supported"); 821} 822 823void checkImageRequirements (Context& context, 824 const VkFormat format, 825 const VkFormatFeatureFlags requiredFeatureFlags, 826 const VkImageUsageFlags requiredUsageFlags, 827 const VkSampleCountFlagBits requiredSampleCount, 828 VkImageFormatProperties& imageProperties) 829{ 830 const InstanceInterface& vki = context.getInstanceInterface(); 831 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 832 833 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 834 835 if ((formatProperties.optimalTilingFeatures & requiredFeatureFlags) != requiredFeatureFlags) 836 TCU_THROW(NotSupportedError, (de::toString(format) + ": format features not supported").c_str()); 837 838 const VkImageCreateFlags createFlags = requiredSampleCount == VK_SAMPLE_COUNT_1_BIT ? VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT : 0; 839 840 const VkResult result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, requiredUsageFlags, createFlags, &imageProperties); 841 842 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) 843 TCU_THROW(NotSupportedError, (de::toString(format) + ": format not supported").c_str()); 844 845 if ((imageProperties.sampleCounts & requiredSampleCount) != requiredSampleCount) 846 TCU_THROW(NotSupportedError, (de::toString(format) + ": sample count not supported").c_str()); 847} 848 849TestObjects::TestObjects(Context& contextIn) 850 : cmdPool(createCommandPool(contextIn.getDeviceInterface(), contextIn.getDevice(), VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, contextIn.getUniversalQueueFamilyIndex())) 851 , cmdBuffer(makeCommandBuffer(contextIn.getDeviceInterface(), contextIn.getDevice(), *cmdPool)) 852 , context(contextIn) 853{ 854} 855 856void TestObjects::beginCommandBuffer() 857{ 858 const DeviceInterface& vk = context.getDeviceInterface(); 859 860 vk::beginCommandBuffer(vk, *cmdBuffer); 861} 862 863void TestObjects::submitCommandsAndWait() 864{ 865 const DeviceInterface& vk = context.getDeviceInterface(); 866 const VkDevice device = context.getDevice(); 867 868 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 869 vk::submitCommandsAndWait(vk, device, context.getUniversalQueue(), *cmdBuffer); 870} 871 872void initializeAttachments(const TestParams& params, WorkingData& wd, std::vector<VkImage>& images, std::vector<VkImageView>& attachments, const size_t passNdx, deInt32 attachmentNdxes[8]) 873{ 874 const bool includeAll = passNdx >= params.perPass.size(); 875 deInt32 currentNdx = 0; 876 877 // Output attachments 878 if (includeAll || params.usesColor1InPass(passNdx)) 879 { 880 images.push_back(wd.floatColor1.image.get()); 881 attachments.push_back(wd.floatColor1.view.get()); 882 attachmentNdxes[0] = currentNdx++; 883 } 884 if (includeAll || params.usesColor2InPass(passNdx)) 885 { 886 images.push_back(wd.floatColor2.image.get()); 887 attachments.push_back(wd.floatColor2.view.get()); 888 attachmentNdxes[1] = currentNdx++; 889 } 890 if (includeAll || params.usesColor3InPass(passNdx)) 891 { 892 images.push_back(wd.intColor.image.get()); 893 attachments.push_back(wd.intColor.view.get()); 894 attachmentNdxes[2] = currentNdx++; 895 } 896 if (includeAll || params.usesDepthStencilInPass(passNdx)) 897 { 898 images.push_back(wd.depthStencil.image.get()); 899 attachments.push_back(wd.depthStencil.view.get()); 900 attachmentNdxes[3] = currentNdx++; 901 } 902 903 // Resolve attachments 904 if (params.numFloatColor1Samples != VK_SAMPLE_COUNT_1_BIT && (includeAll || params.usesColor1InPass(passNdx))) 905 { 906 images.push_back(wd.floatResolve1.image.get()); 907 attachments.push_back(wd.floatResolve1.view.get()); 908 attachmentNdxes[4] = currentNdx++; 909 } 910 if (params.numFloatColor2Samples != VK_SAMPLE_COUNT_1_BIT && (includeAll || params.usesColor2InPass(passNdx))) 911 { 912 images.push_back(wd.floatResolve2.image.get()); 913 attachments.push_back(wd.floatResolve2.view.get()); 914 attachmentNdxes[5] = currentNdx++; 915 } 916 if (params.numIntColorSamples != VK_SAMPLE_COUNT_1_BIT && (includeAll || params.usesColor3InPass(passNdx))) 917 { 918 images.push_back(wd.intResolve.image.get()); 919 attachments.push_back(wd.intResolve.view.get()); 920 attachmentNdxes[6] = currentNdx++; 921 } 922 if (params.numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT && (includeAll || params.usesDepthStencilInPass(passNdx))) 923 { 924 images.push_back(wd.depthStencilResolve.image.get()); 925 attachments.push_back(wd.depthStencilResolve.view.get()); 926 attachmentNdxes[7] = currentNdx++; 927 } 928} 929 930void initializeAttachmentDescriptions(const TestParams& params, std::vector<VkAttachmentDescription2>& descs, 931 const bool preCleared, const deInt32 attachmentNdxes[8], deUint32& attachmentUseMask) 932{ 933 // The attachments are either cleared already or should be cleared now. If an attachment was used in a previous render pass, 934 // it will override these values to always LOAD and use the SHADER_READ_ONLY layout. It's SHADER_READ_ONLY because final layout 935 // is always that for simplicity. 936 const VkAttachmentLoadOp loadOp = preCleared ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR; 937 const VkImageLayout initialLayout = preCleared ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; 938 939 // Output attachments 940 if (attachmentNdxes[0] >= 0) 941 { 942 descs.push_back(VkAttachmentDescription2{ 943 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 944 DE_NULL, // const void* pNext; 945 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 946 params.floatColor1Format, // VkFormat format; 947 params.numFloatColor1Samples, // VkSampleCountFlagBits samples; 948 (attachmentUseMask & (1 << 0)) != 0 949 ? VK_ATTACHMENT_LOAD_OP_LOAD 950 : loadOp, // VkAttachmentLoadOp loadOp; 951 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 952 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 953 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 954 (attachmentUseMask & (1 << 0)) != 0 955 ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 956 : initialLayout, // VkImageLayout initialLayout; 957 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 958 }); 959 attachmentUseMask |= 1 << 0; 960 } 961 962 if (attachmentNdxes[1] >= 0) 963 { 964 descs.push_back(VkAttachmentDescription2{ 965 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 966 DE_NULL, // const void* pNext; 967 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 968 params.floatColor2Format, // VkFormat format; 969 params.numFloatColor2Samples, // VkSampleCountFlagBits samples; 970 (attachmentUseMask & (1 << 1)) != 0 971 ? VK_ATTACHMENT_LOAD_OP_LOAD 972 : loadOp, // VkAttachmentLoadOp loadOp; 973 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 974 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 975 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 976 (attachmentUseMask & (1 << 1)) != 0 977 ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 978 : initialLayout, // VkImageLayout initialLayout; 979 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 980 }); 981 attachmentUseMask |= 1 << 1; 982 } 983 984 if (attachmentNdxes[2] >= 0) 985 { 986 descs.push_back(VkAttachmentDescription2{ 987 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 988 DE_NULL, // const void* pNext; 989 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 990 params.intColorFormat, // VkFormat format; 991 params.numIntColorSamples, // VkSampleCountFlagBits samples; 992 (attachmentUseMask & (1 << 2)) != 0 993 ? VK_ATTACHMENT_LOAD_OP_LOAD 994 : loadOp, // VkAttachmentLoadOp loadOp; 995 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 996 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 997 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 998 (attachmentUseMask & (1 << 2)) != 0 999 ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 1000 : initialLayout, // VkImageLayout initialLayout; 1001 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1002 }); 1003 attachmentUseMask |= 1 << 2; 1004 } 1005 1006 if (attachmentNdxes[3] >= 0) 1007 { 1008 descs.push_back(VkAttachmentDescription2{ 1009 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 1010 DE_NULL, // const void* pNext; 1011 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 1012 params.depthStencilFormat, // VkFormat format; 1013 params.numDepthStencilSamples, // VkSampleCountFlagBits samples; 1014 (attachmentUseMask & (1 << 3)) != 0 1015 ? VK_ATTACHMENT_LOAD_OP_LOAD 1016 : loadOp, // VkAttachmentLoadOp loadOp; 1017 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1018 (attachmentUseMask & (1 << 3)) != 0 1019 ? VK_ATTACHMENT_LOAD_OP_LOAD 1020 : loadOp, // VkAttachmentLoadOp stencilLoadOp; 1021 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 1022 (attachmentUseMask & (1 << 3)) != 0 1023 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 1024 : initialLayout, // VkImageLayout initialLayout; 1025 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1026 }); 1027 attachmentUseMask |= 1 << 3; 1028 } 1029 1030 // Resolve attachments 1031 if (attachmentNdxes[4] >= 0) 1032 descs.push_back(VkAttachmentDescription2{ 1033 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 1034 DE_NULL, // const void* pNext; 1035 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 1036 params.floatColor1Format, // VkFormat format; 1037 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1038 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 1039 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1040 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1041 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1042 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1043 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1044 }); 1045 1046 if (attachmentNdxes[5] >= 0) 1047 descs.push_back(VkAttachmentDescription2{ 1048 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 1049 DE_NULL, // const void* pNext; 1050 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 1051 params.floatColor2Format, // VkFormat format; 1052 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1053 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 1054 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1055 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1056 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1057 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1058 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1059 }); 1060 1061 if (attachmentNdxes[6] >= 0) 1062 descs.push_back(VkAttachmentDescription2{ 1063 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 1064 DE_NULL, // const void* pNext; 1065 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 1066 params.intColorFormat, // VkFormat format; 1067 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1068 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 1069 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1070 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1071 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 1072 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1073 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1074 }); 1075 1076 if (attachmentNdxes[7] >= 0) 1077 descs.push_back(VkAttachmentDescription2{ 1078 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType; 1079 DE_NULL, // const void* pNext; 1080 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 1081 params.depthStencilFormat, // VkFormat format; 1082 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1083 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 1084 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 1085 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 1086 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 1087 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1088 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 1089 }); 1090} 1091 1092void initializeRenderingAttachmentInfos (const TestParams& params, 1093 WorkingData& wd, 1094 std::vector<VkRenderingAttachmentInfo>& colorAttachmentInfos, 1095 VkRenderingAttachmentInfo& depthStencilAttachmentInfo, 1096 std::vector<VkFormat>& colorAttachmentFormats, 1097 const deInt32 attachmentNdxes[8], 1098 deUint32& attachmentUseMask, 1099 deUint32 passNdx) 1100{ 1101 // The attachments are either cleared already or should be cleared now. If an attachment was used in a previous render pass, 1102 // it will override these values to always LOAD and use the SHADER_READ_ONLY layout. It's SHADER_READ_ONLY because final layout 1103 // is always that for simplicity. 1104 const VkAttachmentLoadOp loadOp = params.clearBeforeRenderPass ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR; 1105 const TestParams::PerPass& perPass = params.perPass[passNdx]; 1106 1107 const VkRenderingAttachmentInfo emptyRenderingAttachmentInfo = { 1108 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType 1109 DE_NULL, // const void* pNext 1110 DE_NULL, // VkImageView imageView 1111 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout imageLayout 1112 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode 1113 DE_NULL, // VkImageView resolveImageView 1114 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout 1115 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp 1116 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp 1117 params.clearValues[0] // VkClearValue clearValue 1118 }; 1119 1120 for (auto& colorAttachmentInfo : colorAttachmentInfos) 1121 { 1122 colorAttachmentInfo = emptyRenderingAttachmentInfo; 1123 } 1124 1125 // Output attachments 1126 if (attachmentNdxes[0] >= 0) 1127 { 1128 VkRenderingAttachmentInfo renderingAttachmentInfo = { 1129 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType 1130 DE_NULL, // const void* pNext 1131 wd.floatColor1.view.get(), // VkImageView imageView 1132 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout 1133 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode 1134 DE_NULL, // VkImageView resolveImageView 1135 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout 1136 (attachmentUseMask & (1 << 0)) != 0 1137 ? VK_ATTACHMENT_LOAD_OP_LOAD 1138 : loadOp, // VkAttachmentLoadOp loadOp 1139 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp 1140 params.clearValues[0] // VkClearValue clearValue 1141 }; 1142 1143 // Enable resolve image if it's used. 1144 if (attachmentNdxes[4] >= 0) 1145 { 1146 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1147 renderingAttachmentInfo.resolveImageView = wd.floatResolve1.view.get(); 1148 renderingAttachmentInfo.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1149 } 1150 else if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 1151 { 1152 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1153 } 1154 1155 colorAttachmentInfos[perPass.floatColor1Location] = renderingAttachmentInfo; 1156 colorAttachmentFormats[perPass.floatColor1Location] = params.floatColor1Format; 1157 attachmentUseMask |= 1 << 0; 1158 } 1159 1160 if (attachmentNdxes[1] >= 0) 1161 { 1162 VkRenderingAttachmentInfo renderingAttachmentInfo = { 1163 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType 1164 DE_NULL, // const void* pNext 1165 wd.floatColor2.view.get(), // VkImageView imageView 1166 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout 1167 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode 1168 DE_NULL, // VkImageView resolveImageView 1169 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout 1170 (attachmentUseMask & (1 << 1)) != 0 1171 ? VK_ATTACHMENT_LOAD_OP_LOAD 1172 : loadOp, // VkAttachmentLoadOp loadOp 1173 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp 1174 params.clearValues[1] // VkClearValue clearValue 1175 }; 1176 1177 if (attachmentNdxes[5] >= 0) 1178 { 1179 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1180 renderingAttachmentInfo.resolveImageView = wd.floatResolve2.view.get(); 1181 renderingAttachmentInfo.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1182 } 1183 else if (params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT) 1184 { 1185 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1186 } 1187 1188 colorAttachmentInfos[perPass.floatColor2Location] = renderingAttachmentInfo; 1189 colorAttachmentFormats[perPass.floatColor2Location] = params.floatColor2Format; 1190 attachmentUseMask |= 1 << 1; 1191 } 1192 1193 if (attachmentNdxes[2] >= 0) 1194 { 1195 VkRenderingAttachmentInfo renderingAttachmentInfo = { 1196 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType 1197 DE_NULL, // const void* pNext 1198 wd.intColor.view.get(), // VkImageView imageView 1199 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout 1200 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode 1201 DE_NULL, // VkImageView resolveImageView 1202 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout 1203 (attachmentUseMask & (1 << 2)) != 0 1204 ? VK_ATTACHMENT_LOAD_OP_LOAD 1205 : loadOp, // VkAttachmentLoadOp loadOp 1206 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp 1207 params.clearValues[2] // VkClearValue clearValue 1208 }; 1209 1210 if (attachmentNdxes[6] >= 0) 1211 { 1212 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; 1213 renderingAttachmentInfo.resolveImageView = wd.intResolve.view.get(); 1214 renderingAttachmentInfo.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1215 } 1216 else if (params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT) 1217 { 1218 renderingAttachmentInfo.resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; 1219 } 1220 1221 colorAttachmentInfos[perPass.intColorLocation] = renderingAttachmentInfo; 1222 colorAttachmentFormats[perPass.intColorLocation] = params.intColorFormat; 1223 attachmentUseMask |= 1 << 2; 1224 } 1225 1226 if (attachmentNdxes[3] >= 0) 1227 { 1228 1229 VkRenderingAttachmentInfo renderingAttachmentInfo = { 1230 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType 1231 DE_NULL, // const void* pNext 1232 wd.depthStencil.view.get(), // VkImageView imageView 1233 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout 1234 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode 1235 DE_NULL, // VkImageView resolveImageView 1236 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout 1237 (attachmentUseMask & (1 << 3)) != 0 1238 ? VK_ATTACHMENT_LOAD_OP_LOAD 1239 : loadOp, // VkAttachmentLoadOp loadOp 1240 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp 1241 params.clearValues[3] // VkClearValue clearValue 1242 }; 1243 1244 if (attachmentNdxes[7] >= 0) 1245 { 1246 renderingAttachmentInfo.resolveMode = params.perPass[passNdx].depthStencilResolveMode; 1247 renderingAttachmentInfo.resolveImageView = wd.depthStencilResolve.view.get(); 1248 renderingAttachmentInfo.resolveImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1249 } 1250 else if (params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT) 1251 { 1252 renderingAttachmentInfo.resolveMode = params.perPass[passNdx].depthStencilResolveMode; 1253 } 1254 1255 depthStencilAttachmentInfo = renderingAttachmentInfo; 1256 attachmentUseMask |= 1 << 3; 1257 } 1258} 1259 1260void initResolveImageLayouts (Context& context, 1261 const TestParams& params, 1262 WorkingData& wd, 1263 TestObjects& testObjects) 1264{ 1265 const DeviceInterface& vk = context.getDeviceInterface(); 1266 const VkImageMemoryBarrier imageBarrierTemplate = 1267 { 1268 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1269 DE_NULL, // const void* pNext 1270 0, // VkAccessFlags srcAccessMask 1271 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1272 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask 1273 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout 1274 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout 1275 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1276 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1277 0, // VkImage image 1278 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u), // VkImageSubresourceRange subresourceRange 1279 }; 1280 1281 std::vector<VkImageMemoryBarrier> barriers; 1282 1283 if (wd.floatResolve1.image) 1284 { 1285 barriers.push_back(imageBarrierTemplate); 1286 barriers.back().image = *wd.floatResolve1.image; 1287 } 1288 1289 if (wd.floatResolve2.image) 1290 { 1291 barriers.push_back(imageBarrierTemplate); 1292 barriers.back().image = *wd.floatResolve2.image; 1293 } 1294 1295 if (wd.intResolve.image) 1296 { 1297 barriers.push_back(imageBarrierTemplate); 1298 barriers.back().image = *wd.intResolve.image; 1299 } 1300 1301 if (wd.depthStencilResolve.image) 1302 { 1303 barriers.push_back(imageBarrierTemplate); 1304 barriers.back().image = *wd.depthStencilResolve.image; 1305 barriers.back().newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1306 barriers.back().subresourceRange.aspectMask = getDepthStencilAspectFlags(params.depthStencilFormat); 1307 } 1308 1309 if (!barriers.empty()) 1310 { 1311 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 1312 0u, DE_NULL, 0u, DE_NULL, static_cast<uint32_t>(barriers.size()), barriers.data()); 1313 } 1314} 1315 1316void preRenderingImageLayoutTransition (Context& context, 1317 const TestParams& params, 1318 WorkingData& wd, 1319 TestObjects& testObjects) 1320{ 1321 const DeviceInterface& vk = context.getDeviceInterface(); 1322 const bool preCleared = params.clearBeforeRenderPass; 1323 1324 const VkImageMemoryBarrier imageBarrierTemplate = 1325 { 1326 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1327 DE_NULL, // const void* pNext; 1328 preCleared ? VK_ACCESS_TRANSFER_WRITE_BIT : (VkAccessFlagBits)0, // VkAccessFlags srcAccessMask; 1329 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1330 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1331 preCleared 1332 ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 1333 : VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1334 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1335 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 1336 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 1337 0, // VkImage image; 1338 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u), // VkImageSubresourceRange subresourceRange; 1339 }; 1340 1341 VkImageMemoryBarrier barriers[4] = { imageBarrierTemplate, imageBarrierTemplate, imageBarrierTemplate, imageBarrierTemplate }; 1342 barriers[0].image = *wd.floatColor1.image; 1343 barriers[1].image = *wd.floatColor2.image; 1344 barriers[2].image = *wd.intColor.image; 1345 barriers[3].image = *wd.depthStencil.image; 1346 barriers[3].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 1347 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 1348 barriers[3].newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1349 barriers[3].subresourceRange.aspectMask = getDepthStencilAspectFlags(params.depthStencilFormat); 1350 1351 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, preCleared ? VK_PIPELINE_STAGE_TRANSFER_BIT : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 1352 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 1353 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); 1354} 1355 1356void postRenderingResolveImageLayoutTransition (Context& context, 1357 const TestParams& params, 1358 WorkingData& wd, 1359 TestObjects& testObjects) 1360{ 1361 const DeviceInterface& vk = context.getDeviceInterface(); 1362 const VkImageMemoryBarrier imageBarrierTemplate = 1363 { 1364 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1365 DE_NULL, // const void* pNext 1366 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1367 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 1368 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask 1369 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout 1370 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout 1371 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1372 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1373 0, // VkImage image 1374 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u), // VkImageSubresourceRange subresourceRange 1375 }; 1376 1377 std::vector<VkImageMemoryBarrier> barriers; 1378 1379 if (wd.floatResolve1.image) 1380 { 1381 barriers.push_back(imageBarrierTemplate); 1382 barriers.back().image = *wd.floatResolve1.image; 1383 } 1384 1385 if (wd.floatResolve2.image) 1386 { 1387 barriers.push_back(imageBarrierTemplate); 1388 barriers.back().image = *wd.floatResolve2.image; 1389 } 1390 1391 if (wd.intResolve.image) 1392 { 1393 barriers.push_back(imageBarrierTemplate); 1394 barriers.back().image = *wd.intResolve.image; 1395 } 1396 1397 if (wd.depthStencilResolve.image) 1398 { 1399 barriers.push_back(imageBarrierTemplate); 1400 barriers.back().image = *wd.depthStencilResolve.image; 1401 barriers.back().oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1402 barriers.back().newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 1403 barriers.back().subresourceRange.aspectMask = getDepthStencilAspectFlags(params.depthStencilFormat); 1404 } 1405 1406 if (!barriers.empty()) 1407 { 1408 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, 1409 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 1410 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT , 0u, 1411 0u, DE_NULL, 0u, DE_NULL, static_cast<uint32_t>(barriers.size()), barriers.data()); 1412 } 1413} 1414 1415void preinitializeAttachmentReferences(std::vector<VkAttachmentReference2>& references, const deUint32 count) 1416{ 1417 references.resize(count, VkAttachmentReference2{ 1418 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType; 1419 DE_NULL, // const void* pNext; 1420 VK_ATTACHMENT_UNUSED, // uint32_t attachment; 1421 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout layout; 1422 0, // VkImageAspectFlags aspectMask; 1423 }); 1424} 1425 1426void initializeAttachmentReference(VkAttachmentReference2& reference, deUint32 attachment, const VkFormat depthStencilFormat, const bool isInputAttachment) 1427{ 1428 const bool isColor = depthStencilFormat == VK_FORMAT_UNDEFINED; 1429 1430 reference.attachment = attachment; 1431 reference.layout = isInputAttachment 1432 ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 1433 : isColor 1434 ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 1435 : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1436 reference.aspectMask = isColor 1437 ? VkImageAspectFlags(VK_IMAGE_ASPECT_COLOR_BIT) 1438 : getDepthStencilAspectFlags(depthStencilFormat); 1439} 1440 1441bool isInAttachmentReferences(const std::vector<VkAttachmentReference2>& references, const deInt32 attachment) 1442{ 1443 for (const VkAttachmentReference2& reference: references) 1444 if (reference.attachment == static_cast<deUint32>(attachment)) 1445 return true; 1446 1447 return false; 1448} 1449 1450void addSubpassDescription(const TestParams& params, 1451 const deUint32 passNdx, 1452 std::vector<VkAttachmentReference2>& attachmentReferences, 1453 std::vector<VkAttachmentReference2>& resolveAttachmentReferences, 1454 VkSubpassDescriptionDepthStencilResolve& depthStencilResolve, 1455 std::vector<deUint32>* preserveAttachments, 1456 VkMultisampledRenderToSingleSampledInfoEXT& msrtss, 1457 std::vector<VkSubpassDescription2>& subpasses, 1458 const std::vector<VkAttachmentReference2>& inputAttachmentReferences, 1459 const deInt32 attachmentNdxes[8]) 1460{ 1461 const TestParams::PerPass& perPass = params.perPass[passNdx]; 1462 bool anySingleSampledAttachmentsUsed = false; 1463 1464 // Maximum 4 attachment references for color and 1 for depth 1465 preinitializeAttachmentReferences(attachmentReferences, 5); 1466 preinitializeAttachmentReferences(resolveAttachmentReferences, 5); 1467 1468 if (perPass.floatColor1Location >= 0) 1469 { 1470 initializeAttachmentReference(attachmentReferences[perPass.floatColor1Location], 1471 attachmentNdxes[0], VK_FORMAT_UNDEFINED, false); 1472 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT; 1473 } 1474 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[0])) 1475 { 1476 if (attachmentNdxes[0] != -1) 1477 preserveAttachments->push_back(attachmentNdxes[0]); 1478 } 1479 if (perPass.floatColor2Location >= 0) 1480 { 1481 initializeAttachmentReference(attachmentReferences[perPass.floatColor2Location], 1482 attachmentNdxes[1], VK_FORMAT_UNDEFINED, false); 1483 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT; 1484 } 1485 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[1])) 1486 { 1487 if (attachmentNdxes[1] != -1) 1488 preserveAttachments->push_back(attachmentNdxes[1]); 1489 } 1490 if (perPass.intColorLocation >= 0) 1491 { 1492 initializeAttachmentReference(attachmentReferences[perPass.intColorLocation], 1493 attachmentNdxes[2], VK_FORMAT_UNDEFINED, false); 1494 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT; 1495 } 1496 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[2])) 1497 { 1498 if (attachmentNdxes[2] != -1) 1499 preserveAttachments->push_back(attachmentNdxes[2]); 1500 } 1501 if (perPass.hasDepthStencil) 1502 { 1503 initializeAttachmentReference(attachmentReferences.back(), 1504 attachmentNdxes[3], params.depthStencilFormat, false); 1505 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT; 1506 } 1507 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[3])) 1508 { 1509 if (attachmentNdxes[3] != -1) 1510 preserveAttachments->push_back(attachmentNdxes[3]); 1511 } 1512 1513 // Resolve attachments 1514 if (perPass.resolveFloatColor1) 1515 { 1516 initializeAttachmentReference(resolveAttachmentReferences[perPass.floatColor1Location], 1517 attachmentNdxes[4], VK_FORMAT_UNDEFINED, false); 1518 } 1519 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[4])) 1520 { 1521 if (attachmentNdxes[4] != -1) 1522 preserveAttachments->push_back(attachmentNdxes[4]); 1523 } 1524 if (perPass.resolveFloatColor2) 1525 { 1526 initializeAttachmentReference(resolveAttachmentReferences[perPass.floatColor2Location], 1527 attachmentNdxes[5], VK_FORMAT_UNDEFINED, false); 1528 } 1529 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[5])) 1530 { 1531 if (attachmentNdxes[5] != -1) 1532 preserveAttachments->push_back(attachmentNdxes[5]); 1533 } 1534 if (perPass.resolveIntColor) 1535 { 1536 initializeAttachmentReference(resolveAttachmentReferences[perPass.intColorLocation], 1537 attachmentNdxes[6], VK_FORMAT_UNDEFINED, false); 1538 } 1539 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[6])) 1540 { 1541 if (attachmentNdxes[6] != -1) 1542 preserveAttachments->push_back(attachmentNdxes[6]); 1543 } 1544 1545 // Account for single-sampled attachments in input attachments as well. 1546 if (!inputAttachmentReferences.empty()) 1547 { 1548 if (attachmentNdxes[0] >= 0 && isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[0])) 1549 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT; 1550 if (attachmentNdxes[1] >= 0 && isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[1])) 1551 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT; 1552 if (attachmentNdxes[2] >= 0 && isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[2])) 1553 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT; 1554 if (attachmentNdxes[3] >= 0 && isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[3])) 1555 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT; 1556 } 1557 1558 const bool needsMsrtss = anySingleSampledAttachmentsUsed && perPass.numSamples != VK_SAMPLE_COUNT_1_BIT; 1559 const bool needsDepthStencilResolve = perPass.resolveDepthStencil || (needsMsrtss && params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT && perPass.hasDepthStencil); 1560 1561 if (needsDepthStencilResolve) 1562 { 1563 if (perPass.resolveDepthStencil) 1564 { 1565 initializeAttachmentReference(resolveAttachmentReferences.back(), 1566 attachmentNdxes[7], params.depthStencilFormat, false); 1567 } 1568 depthStencilResolve = VkSubpassDescriptionDepthStencilResolve 1569 { 1570 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, // VkStructureType sType; 1571 DE_NULL, // const void* pNext; 1572 perPass.depthStencilResolveMode, // VkResolveModeFlagBits depthResolveMode; 1573 perPass.depthStencilResolveMode, // VkResolveModeFlagBits stencilResolveMode; 1574 perPass.resolveDepthStencil 1575 ? &resolveAttachmentReferences.back() 1576 : nullptr, // const VkAttachmentReference2* pDepthStencilResolveAttachment; 1577 }; 1578 } 1579 else if (preserveAttachments && !isInAttachmentReferences(inputAttachmentReferences, attachmentNdxes[7])) 1580 { 1581 if (attachmentNdxes[7] != -1) 1582 preserveAttachments->push_back(attachmentNdxes[7]); 1583 } 1584 1585 VkSubpassDescription2 subpassDescription = 1586 { 1587 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // VkStructureType sType; 1588 needsDepthStencilResolve 1589 ? &depthStencilResolve 1590 : DE_NULL, // const void* pNext; 1591 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 1592 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 1593 0u, // uint32_t viewMask; 1594 static_cast<deUint32>(inputAttachmentReferences.size()), // uint32_t inputAttachmentCount; 1595 dataOrNullPtr(inputAttachmentReferences), // const VkAttachmentReference2* pInputAttachments; 1596 4u, // uint32_t colorAttachmentCount; 1597 dataOrNullPtr(attachmentReferences), // const VkAttachmentReference2* pColorAttachments; 1598 dataOrNullPtr(resolveAttachmentReferences), // const VkAttachmentReference2* pResolveAttachments; 1599 perPass.hasDepthStencil 1600 ? &attachmentReferences.back() 1601 : DE_NULL, // const VkAttachmentReference2* pDepthStencilAttachment; 1602 preserveAttachments 1603 ? static_cast<deUint32>(preserveAttachments->size()) 1604 : 0, // uint32_t preserveAttachmentCount; 1605 preserveAttachments 1606 ? dataOrNullPtr(*preserveAttachments) 1607 : nullptr, // const uint32_t* pPreserveAttachments; 1608 }; 1609 1610 // Append MSRTSS to subpass desc 1611 msrtss = VkMultisampledRenderToSingleSampledInfoEXT{ 1612 VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT, // VkStructureType sType 1613 subpassDescription.pNext, // const void* pNext 1614 VK_TRUE, // VkBool32 multisampledRenderToSingleSampledEnable 1615 perPass.numSamples, // VkSampleCountFlagBits rasterizationSamples 1616 }; 1617 if (needsMsrtss) 1618 subpassDescription.pNext = &msrtss; 1619 1620 subpasses.push_back(subpassDescription); 1621} 1622 1623void addSubpassDependency(const deUint32 subpassNdx, std::vector<VkSubpassDependency2>& subpassDependencies) 1624{ 1625 subpassDependencies.push_back(VkSubpassDependency2{ 1626 VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, // VkStructureType sType; 1627 DE_NULL, // const void* pNext; 1628 subpassNdx - 1, // uint32_t srcSubpass; 1629 subpassNdx, // uint32_t dstSubpass; 1630 1631 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 1632 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask; 1633 1634 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 1635 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask; 1636 1637 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1638 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 1639 1640 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1641 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1642 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 1643 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; 1644 1645 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; 1646 0, // int32_t viewOffset; 1647 }); 1648} 1649 1650void createRenderPassAndFramebuffer(Context& context, 1651 WorkingData& wd, 1652 TestObjects& testObjects, 1653 const PipelineConstructionType pipelineConstructionType, 1654 const std::vector<VkImage>& images, 1655 const std::vector<VkImageView>& attachments, 1656 const std::vector<VkAttachmentDescription2>& attachmentDescriptions, 1657 const std::vector<VkSubpassDescription2>& subpasses, 1658 const std::vector<VkSubpassDependency2>& subpassDependencies) 1659{ 1660 const DeviceInterface& vk = context.getDeviceInterface(); 1661 const VkDevice device = context.getDevice(); 1662 1663 const VkRenderPassCreateInfo2 renderPassInfo = 1664 { 1665 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // VkStructureType sType; 1666 DE_NULL, // const void* pNext; 1667 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 1668 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount; 1669 dataOrNullPtr(attachmentDescriptions), // const VkAttachmentDescription2* pAttachments; 1670 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount; 1671 dataOrNullPtr(subpasses), // const VkSubpassDescription2* pSubpasses; 1672 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount; 1673 dataOrNullPtr(subpassDependencies), // const VkSubpassDependency2* pDependencies; 1674 0u, // uint32_t correlatedViewMaskCount; 1675 DE_NULL, // const uint32_t* pCorrelatedViewMasks; 1676 }; 1677 1678 testObjects.renderPassFramebuffers.emplace_back(RenderPassWrapper(pipelineConstructionType, vk, device, &renderPassInfo)); 1679 testObjects.renderPassFramebuffers.back().createFramebuffer(vk, device, static_cast<deUint32>(attachments.size()), dataOrNullPtr(images), dataOrNullPtr(attachments), wd.framebufferSize.x(), wd.framebufferSize.y()); 1680} 1681 1682void createWorkingData (Context& context, const TestParams& params, WorkingData& wd) 1683{ 1684 const DeviceInterface& vk = context.getDeviceInterface(); 1685 const VkDevice device = context.getDevice(); 1686 MovePtr<Allocator> allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))); 1687 1688 // Create images 1689 { 1690 // TODO: change image types to be nonuniform, for example: mip 1 of 2D image, mip 2/level 3 of 2D array image, etc. 1691 wd.floatColor1.allocate (vk, device, allocator, params.floatColor1Format, wd.framebufferSize, params.numFloatColor1Samples, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, true); 1692 wd.floatColor2.allocate (vk, device, allocator, params.floatColor2Format, wd.framebufferSize, params.numFloatColor2Samples, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, true); 1693 wd.intColor.allocate (vk, device, allocator, params.intColorFormat, wd.framebufferSize, params.numIntColorSamples, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, true); 1694 wd.depthStencil.allocate(vk, device, allocator, params.depthStencilFormat, wd.framebufferSize, params.numDepthStencilSamples, depthStencilImageUsageFlags, getDepthStencilAspectFlags(params.depthStencilFormat), 1, true); 1695 1696 if (isDepthFormat(params.depthStencilFormat)) 1697 wd.depthOnlyImageView = wd.depthStencil.makeView(vk, device, params.depthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1); 1698 1699 if (isStencilFormat(params.depthStencilFormat)) 1700 wd.stencilOnlyImageView = wd.depthStencil.makeView(vk, device, params.depthStencilFormat, VK_IMAGE_ASPECT_STENCIL_BIT, 1); 1701 1702 if (params.numFloatColor1Samples != VK_SAMPLE_COUNT_1_BIT) 1703 { 1704 wd.floatResolve1.allocate(vk, device, allocator, params.floatColor1Format, wd.framebufferSize, VK_SAMPLE_COUNT_1_BIT, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, false); 1705 } 1706 1707 if (params.numFloatColor2Samples != VK_SAMPLE_COUNT_1_BIT) 1708 { 1709 wd.floatResolve2.allocate(vk, device, allocator, params.floatColor2Format, wd.framebufferSize, VK_SAMPLE_COUNT_1_BIT, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, false); 1710 } 1711 1712 if (params.numIntColorSamples != VK_SAMPLE_COUNT_1_BIT) 1713 { 1714 wd.intResolve.allocate(vk, device, allocator, params.intColorFormat, wd.framebufferSize, VK_SAMPLE_COUNT_1_BIT, colorImageUsageFlags, VK_IMAGE_ASPECT_COLOR_BIT, 1, false); 1715 } 1716 1717 if (params.numDepthStencilSamples != VK_SAMPLE_COUNT_1_BIT) 1718 { 1719 wd.depthStencilResolve.allocate(vk, device, allocator, params.depthStencilFormat, wd.framebufferSize, VK_SAMPLE_COUNT_1_BIT, depthStencilImageUsageFlags, getDepthStencilAspectFlags(params.depthStencilFormat), 1, false); 1720 1721 if (isDepthFormat(params.depthStencilFormat)) 1722 wd.depthOnlyResolveImageView = wd.depthStencilResolve.makeView(vk, device, params.depthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1); 1723 1724 if (isStencilFormat(params.depthStencilFormat)) 1725 wd.stencilOnlyResolveImageView = wd.depthStencilResolve.makeView(vk, device, params.depthStencilFormat, VK_IMAGE_ASPECT_STENCIL_BIT, 1); 1726 } 1727 1728 wd.verify.allocate (vk, device, allocator, VK_FORMAT_R8G8B8A8_UNORM, wd.framebufferSize, VK_SAMPLE_COUNT_1_BIT, 1729 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 5, false); 1730 } 1731 1732 // Create vertex and verification buffers 1733 { 1734 // A fullscreen triangle 1735 const std::vector<Vec4> vertices = 1736 { 1737 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), 1738 Vec4( 3.0f, -1.0f, 0.0f, 1.0f), 1739 Vec4(-1.0f, 3.0f, 0.0f, 1.0f), 1740 }; 1741 1742 const VkDeviceSize vertexBufferSize = static_cast<VkDeviceSize>(sizeof(vertices[0]) * vertices.size()); 1743 wd.vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 1744 wd.vertexBufferAlloc = bindBuffer(vk, device, *allocator, *wd.vertexBuffer, MemoryRequirement::HostVisible); 1745 1746 deMemcpy(wd.vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize)); 1747 flushMappedMemoryRange(vk, device, wd.vertexBufferAlloc->getMemory(), wd.vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1748 1749 // Initialize the verification data with 0. 1750 const VerificationResults results = {}; 1751 1752 wd.verificationBuffer = makeBuffer(vk, device, sizeof(results), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1753 wd.verificationBufferAlloc = bindBuffer(vk, device, *allocator, *wd.verificationBuffer, MemoryRequirement::HostVisible); 1754 1755 deMemcpy(wd.verificationBufferAlloc->getHostPtr(), &results, sizeof(results)); 1756 flushMappedMemoryRange(vk, device, wd.verificationBufferAlloc->getMemory(), wd.verificationBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1757 1758 wd.singleVerificationBuffer = makeBuffer(vk, device, sizeof(results), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1759 wd.singleVerificationBufferAlloc = bindBuffer(vk, device, *allocator, *wd.singleVerificationBuffer, MemoryRequirement::HostVisible); 1760 1761 deMemcpy(wd.singleVerificationBufferAlloc->getHostPtr(), &results, sizeof(results)); 1762 flushMappedMemoryRange(vk, device, wd.singleVerificationBufferAlloc->getMemory(), wd.singleVerificationBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1763 } 1764} 1765 1766void checkRequirements (Context& context, TestParams params) 1767{ 1768 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1769 const vk::InstanceInterface& instanceInterface = context.getInstanceInterface(); 1770 1771 checkPipelineConstructionRequirements(instanceInterface, physicalDevice, params.pipelineConstructionType); 1772 1773 context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve"); 1774 context.requireDeviceFunctionality("VK_KHR_create_renderpass2"); 1775 1776 if (params.dynamicRendering) 1777 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering"); 1778 1779 if (params.isMultisampledRenderToSingleSampled) 1780 { 1781 context.requireDeviceFunctionality("VK_EXT_multisampled_render_to_single_sampled"); 1782 1783 // Check extension feature 1784 { 1785 VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT msrtssFeatures = 1786 { 1787 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, 1788 DE_NULL, 1789 VK_FALSE, 1790 }; 1791 VkPhysicalDeviceFeatures2 physicalDeviceFeatures = 1792 { 1793 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, 1794 &msrtssFeatures, 1795 {}, 1796 }; 1797 1798 instanceInterface.getPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures); 1799 1800 if (msrtssFeatures.multisampledRenderToSingleSampled != VK_TRUE) 1801 { 1802 TCU_THROW(NotSupportedError, "multisampledRenderToSingleSampled not supported"); 1803 } 1804 } 1805 } 1806 1807 // Check whether formats are supported with the requested usage and sample counts. 1808 { 1809 VkImageFormatProperties imageProperties; 1810 checkImageRequirements (context, params.floatColor1Format, 1811 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, 1812 colorImageUsageFlags, params.numFloatColor1Samples, imageProperties); 1813 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 1814 for (const TestParams::PerPass& perPass : params.perPass) 1815 if (perPass.floatColor1Location >= 0 && (imageProperties.sampleCounts & perPass.numSamples) != perPass.numSamples) 1816 TCU_THROW(NotSupportedError, (de::toString(params.floatColor1Format) + ": sample count not supported").c_str()); 1817 } 1818 { 1819 VkImageFormatProperties imageProperties; 1820 checkImageRequirements (context, params.floatColor2Format, 1821 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, 1822 colorImageUsageFlags, params.numFloatColor2Samples, imageProperties); 1823 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 1824 for (const TestParams::PerPass& perPass : params.perPass) 1825 if (perPass.floatColor2Location >= 0 && (imageProperties.sampleCounts & perPass.numSamples) != perPass.numSamples) 1826 TCU_THROW(NotSupportedError, (de::toString(params.floatColor2Format) + ": sample count not supported").c_str()); 1827 } 1828 { 1829 VkImageFormatProperties imageProperties; 1830 checkImageRequirements (context, params.intColorFormat, 1831 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, 1832 colorImageUsageFlags, params.numIntColorSamples, imageProperties); 1833 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 1834 for (const TestParams::PerPass& perPass : params.perPass) 1835 if (perPass.intColorLocation >= 0 && (imageProperties.sampleCounts & perPass.numSamples) != perPass.numSamples) 1836 TCU_THROW(NotSupportedError, (de::toString(params.intColorFormat) + ": sample count not supported").c_str()); 1837 } 1838 { 1839 VkImageFormatProperties imageProperties; 1840 checkImageRequirements (context, params.depthStencilFormat, 1841 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, 1842 depthStencilImageUsageFlags, params.numDepthStencilSamples, imageProperties); 1843 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 1844 for (const TestParams::PerPass& perPass : params.perPass) 1845 if (perPass.hasDepthStencil && (imageProperties.sampleCounts & perPass.numSamples) != perPass.numSamples) 1846 TCU_THROW(NotSupportedError, (de::toString(params.depthStencilFormat) + ": sample count not supported").c_str()); 1847 } 1848 1849 // Perform query to get supported depth/stencil resolve modes. 1850 VkPhysicalDeviceDepthStencilResolveProperties dsResolveProperties = {}; 1851 dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES; 1852 1853 VkPhysicalDeviceProperties2 deviceProperties = {}; 1854 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 1855 deviceProperties.pNext = &dsResolveProperties; 1856 1857 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties); 1858 1859 for (const TestParams::PerPass& perPass : params.perPass) 1860 { 1861 // Check whether sample counts used for rendering are acceptable 1862 const bool checkColor = perPass.floatColor1Location >= 0 || perPass.floatColor2Location >= 0 || perPass.intColorLocation >= 0; 1863 const bool checkDepth = perPass.hasDepthStencil && isDepthFormat(params.depthStencilFormat); 1864 const bool checkStencil = perPass.hasDepthStencil && isStencilFormat(params.depthStencilFormat); 1865 checkSampleRequirements(context, perPass.numSamples, checkColor, checkDepth, checkStencil); 1866 1867 // Check whether depth/stencil resolve mode is supported 1868 if (perPass.depthStencilResolveMode != VK_RESOLVE_MODE_NONE && 1869 ((dsResolveProperties.supportedDepthResolveModes & perPass.depthStencilResolveMode) == 0 || 1870 (dsResolveProperties.supportedStencilResolveModes & perPass.depthStencilResolveMode) == 0)) 1871 { 1872 TCU_THROW(NotSupportedError, "Depth/stencil resolve mode not supported"); 1873 } 1874 } 1875} 1876 1877void checkHasMsrtss (Context& context, VkFormat) 1878{ 1879 context.requireDeviceFunctionality("VK_EXT_multisampled_render_to_single_sampled"); 1880} 1881 1882void generateRandomClearValues(de::Random& rng, const TestParams& params, VkClearValue clearValues[4], bool smallValues) 1883{ 1884 const bool usesSignedIntFormat = params.intColorFormat == VK_FORMAT_R16G16B16A16_SINT; 1885 1886 const float minFloatValue = 0.05f; 1887 const float maxFloatValue = smallValues ? 0.1f : 0.95f; 1888 const deUint32 minIntValue = smallValues ? 20 : 5000; 1889 const deUint32 maxIntValue = smallValues ? 100 : 10000; 1890 const float minDepthValue = 0.05f; 1891 const float maxDepthValue = smallValues ? 0.1f : 0.5f; 1892 const deUint32 minStencilValue = 0x10; 1893 const deUint32 maxStencilValue = 0x20; 1894 1895 clearValues[0].color.float32[0] = rng.getFloat(minFloatValue, maxFloatValue); 1896 clearValues[0].color.float32[1] = rng.getFloat(minFloatValue, maxFloatValue); 1897 clearValues[0].color.float32[2] = rng.getFloat(minFloatValue, maxFloatValue); 1898 clearValues[0].color.float32[3] = rng.getFloat(minFloatValue, maxFloatValue); 1899 clearValues[1].color.float32[0] = rng.getFloat(minFloatValue, maxFloatValue); 1900 clearValues[1].color.float32[1] = rng.getFloat(minFloatValue, maxFloatValue); 1901 clearValues[1].color.float32[2] = rng.getFloat(minFloatValue, maxFloatValue); 1902 clearValues[1].color.float32[3] = rng.getFloat(minFloatValue, maxFloatValue); 1903 clearValues[2].color.int32[0] = (usesSignedIntFormat ? -1 : 1) * rng.getInt(minIntValue, maxIntValue); 1904 clearValues[2].color.int32[1] = (usesSignedIntFormat ? -1 : 1) * rng.getInt(minIntValue, maxIntValue); 1905 clearValues[2].color.int32[2] = (usesSignedIntFormat ? -1 : 1) * rng.getInt(minIntValue, maxIntValue); 1906 clearValues[2].color.int32[3] = (usesSignedIntFormat ? -1 : 1) * rng.getInt(minIntValue, maxIntValue); 1907 clearValues[3].depthStencil.depth = rng.getFloat(minDepthValue, maxDepthValue); 1908 clearValues[3].depthStencil.stencil = rng.getInt(minStencilValue, maxStencilValue); 1909} 1910 1911void clearImagesBeforeDraw(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 1912{ 1913 const DeviceInterface& vk = context.getDeviceInterface(); 1914 1915 const VkImageMemoryBarrier imageBarrierTemplate = 1916 { 1917 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1918 DE_NULL, // const void* pNext; 1919 0, // VkAccessFlags srcAccessMask; 1920 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1921 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1922 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1923 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 1924 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 1925 0, // VkImage image; 1926 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u), // VkImageSubresourceRange subresourceRange; 1927 }; 1928 1929 VkImageMemoryBarrier preClearBarriers[4] = { imageBarrierTemplate, imageBarrierTemplate, imageBarrierTemplate, imageBarrierTemplate }; 1930 preClearBarriers[0].image = *wd.floatColor1.image; 1931 preClearBarriers[1].image = *wd.floatColor2.image; 1932 preClearBarriers[2].image = *wd.intColor.image; 1933 preClearBarriers[3].image = *wd.depthStencil.image; 1934 preClearBarriers[3].subresourceRange.aspectMask = getDepthStencilAspectFlags(params.depthStencilFormat); 1935 1936 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1937 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(preClearBarriers), preClearBarriers); 1938 1939 vk.cmdClearColorImage(*testObjects.cmdBuffer, *wd.floatColor1.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ¶ms.clearValues[0].color, 1, &preClearBarriers[0].subresourceRange); 1940 vk.cmdClearColorImage(*testObjects.cmdBuffer, *wd.floatColor2.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ¶ms.clearValues[1].color, 1, &preClearBarriers[1].subresourceRange); 1941 vk.cmdClearColorImage(*testObjects.cmdBuffer, *wd.intColor.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ¶ms.clearValues[2].color, 1, &preClearBarriers[2].subresourceRange); 1942 vk.cmdClearDepthStencilImage(*testObjects.cmdBuffer, *wd.depthStencil.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ¶ms.clearValues[3].depthStencil, 1, &preClearBarriers[3].subresourceRange); 1943 1944 const VkMemoryBarrier postClearBarrier = 1945 { 1946 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 1947 DE_NULL, // const void* pNext; 1948 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1949 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1950 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1951 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 1952 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1953 }; 1954 1955 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, 1956 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 1957 0u, 1u, &postClearBarrier, 0u, DE_NULL, 0u, DE_NULL); 1958} 1959 1960void getDrawRegions(WorkingData& wd, UVec4 regions[RegionCount]) 1961{ 1962 static_assert(RegionCount == 4, "Update this function to generate the correct number of regions"); 1963 1964 UVec2 oneThirdRenderAreaSize(wd.renderArea.z() / 3, wd.renderArea.w() / 3); 1965 UVec2 twoThirdsRenderAreaSize(wd.renderArea.z() - oneThirdRenderAreaSize.x(), wd.renderArea.w() - oneThirdRenderAreaSize.y()); 1966 UVec2 renderAreaSplit(wd.renderArea.x() + oneThirdRenderAreaSize.x(), wd.renderArea.y() + oneThirdRenderAreaSize.y()); 1967 1968 regions[0] = UVec4(wd.renderArea.x(), wd.renderArea.y(), oneThirdRenderAreaSize.x(), oneThirdRenderAreaSize.y()); 1969 regions[1] = UVec4(renderAreaSplit.x(), wd.renderArea.y(), twoThirdsRenderAreaSize.x(), oneThirdRenderAreaSize.y()); 1970 regions[2] = UVec4(wd.renderArea.x(), renderAreaSplit.y(), oneThirdRenderAreaSize.x(), twoThirdsRenderAreaSize.y()); 1971 regions[3] = UVec4(renderAreaSplit.x(), renderAreaSplit.y(), twoThirdsRenderAreaSize.x(), twoThirdsRenderAreaSize.y()); 1972} 1973 1974void startRenderPass(Context& context, WorkingData&wd, TestObjects& testObjects, const deUint32 clearValueCount, const VkClearValue* clearValues) 1975{ 1976 const DeviceInterface& vk = context.getDeviceInterface(); 1977 1978 const VkRect2D renderArea = 1979 { 1980 { static_cast<deInt32>(wd.renderArea.x()), static_cast<deInt32>(wd.renderArea.y()) }, 1981 { wd.renderArea.z(), wd.renderArea.w() } 1982 }; 1983 1984 testObjects.renderPassFramebuffers.back().begin(vk, *testObjects.cmdBuffer, renderArea, clearValueCount, clearValues); 1985} 1986 1987void startRendering (Context& context, 1988 const TestParams& params, 1989 WorkingData& wd, 1990 TestObjects& testObjects, 1991 uint32_t colorAttachmentCount, 1992 std::vector<VkRenderingAttachmentInfo>& colorAttachmentInfos, 1993 VkRenderingAttachmentInfo& depthStencilAttachmentInfo, 1994 uint32_t renderPassNdx) 1995{ 1996 const DeviceInterface& vk = context.getDeviceInterface(); 1997 const TestParams::PerPass& perPass = params.perPass[renderPassNdx]; 1998 1999 bool anySingleSampledAttachmentsUsed = false; 2000 if (perPass.floatColor1Location >= 0) 2001 { 2002 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT; 2003 } 2004 if (perPass.floatColor2Location >= 0) 2005 { 2006 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT; 2007 } 2008 if (perPass.intColorLocation >= 0) 2009 { 2010 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT; 2011 } 2012 if (perPass.hasDepthStencil) 2013 { 2014 anySingleSampledAttachmentsUsed = anySingleSampledAttachmentsUsed || params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT; 2015 } 2016 2017 // Append MSRTSS to subpass desc 2018 VkMultisampledRenderToSingleSampledInfoEXT msrtss = 2019 { 2020 VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT, // VkStructureType sType 2021 DE_NULL, // const void* pNext 2022 VK_TRUE, // VkBool32 multisampledRenderToSingleSampledEnable 2023 perPass.numSamples // VkSampleCountFlagBits rasterizationSamples 2024 }; 2025 2026 const VkRect2D renderArea = 2027 { 2028 { static_cast<deInt32>(wd.renderArea.x()), static_cast<deInt32>(wd.renderArea.y()) }, 2029 { wd.renderArea.z(), wd.renderArea.w() } 2030 }; 2031 2032 const bool useDepthStencil = params.usesDepthStencilInPass(renderPassNdx); 2033 2034 VkRenderingInfo renderingInfo = 2035 { 2036 VK_STRUCTURE_TYPE_RENDERING_INFO, // VkStructureType sType 2037 DE_NULL, // const void* pNext 2038 (VkRenderingFlags) 0, // VkRenderingFlags flags 2039 renderArea, // VkRect2D renderArea 2040 1u, // uint32_t layerCount 2041 0u, // uint32_t viewMask 2042 colorAttachmentCount, // uint32_t colorAttachmentCount 2043 colorAttachmentInfos.data(), // const VkRenderingAttachmentInfo* pColorAttachments 2044 useDepthStencil && isDepthFormat(params.depthStencilFormat) ? 2045 &depthStencilAttachmentInfo : DE_NULL, // const VkRenderingAttachmentInfo* pDepthAttachment 2046 useDepthStencil && isStencilFormat(params.depthStencilFormat) ? 2047 &depthStencilAttachmentInfo : DE_NULL // const VkRenderingAttachmentInfo* pStencilAttachment 2048 }; 2049 2050 if (anySingleSampledAttachmentsUsed && perPass.numSamples != VK_SAMPLE_COUNT_1_BIT) 2051 renderingInfo.pNext = &msrtss; 2052 2053 vk.cmdBeginRendering(*testObjects.cmdBuffer, &renderingInfo); 2054} 2055 2056void postDrawBarrier(Context& context, TestObjects& testObjects) 2057{ 2058 const DeviceInterface& vk = context.getDeviceInterface(); 2059 2060 const VkMemoryBarrier barrier = 2061 { 2062 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 2063 DE_NULL, // const void* pNext; 2064 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 2065 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 2066 }; 2067 2068 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, 2069 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 2070 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL); 2071} 2072 2073void setupVerifyDescriptorSetAndPipeline(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects, const VkPushConstantRange* pushConstantRange, 2074 Move<VkPipelineLayout>& verifyPipelineLayout) 2075{ 2076 const DeviceInterface& vk = context.getDeviceInterface(); 2077 const VkDevice device = context.getDevice(); 2078 2079 const Unique<VkDescriptorSetLayout> descriptorSetLayout( 2080 DescriptorSetLayoutBuilder() 2081 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 2082 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2083 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2084 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2085 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2086 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2087 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2088 .build(vk, device)); 2089 2090 testObjects.descriptorPools.emplace_back( 2091 DescriptorPoolBuilder() 2092 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u) 2093 .addType(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 5u) 2094 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u) 2095 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 2096 2097 testObjects.descriptorSets.emplace_back(makeDescriptorSet(vk, device, *testObjects.descriptorPools.back(), *descriptorSetLayout)); 2098 2099 const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(*wd.verificationBuffer, 0ull, sizeof(VerificationResults)); 2100 const VkDescriptorImageInfo color1ImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.getResolvedFloatColorImage1View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2101 const VkDescriptorImageInfo color2ImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.getResolvedFloatColorImage2View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2102 const VkDescriptorImageInfo color3ImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.getResolvedIntColorImageView(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2103 const VkDescriptorImageInfo depthImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.getResolvedDepthOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); 2104 const VkDescriptorImageInfo stencilImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.getResolvedStencilOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); 2105 const VkDescriptorImageInfo verifyImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.verify.view, VK_IMAGE_LAYOUT_GENERAL); 2106 2107 DescriptorSetUpdateBuilder builder; 2108 2109 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo); 2110 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &color1ImageInfo); 2111 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &color2ImageInfo); 2112 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &color3ImageInfo); 2113 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &depthImageInfo); 2114 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(5u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &stencilImageInfo); 2115 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(6u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &verifyImageInfo); 2116 2117 builder.update(vk, device); 2118 2119 const Unique<VkShaderModule> verifyModule (createShaderModule(vk, device, context.getBinaryCollection().get("comp"), 0u)); 2120 2121 verifyPipelineLayout = makePipelineLayout(vk, device, 1, &*descriptorSetLayout, 1, pushConstantRange); 2122 2123 testObjects.computePipelines.push_back(PipelineSp(new Unique<VkPipeline>(makeComputePipeline(vk, device, *verifyPipelineLayout, *verifyModule)))); 2124 2125 vk.cmdBindPipeline(*testObjects.cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, **testObjects.computePipelines.back()); 2126 vk.cmdBindDescriptorSets(*testObjects.cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *verifyPipelineLayout, 0u, 1u, &testObjects.descriptorSets.back().get(), 0u, DE_NULL); 2127} 2128 2129void postVerifyBarrier(Context& context, TestObjects& testObjects, const Move<VkBuffer>& verificationBuffer) 2130{ 2131 const DeviceInterface& vk = context.getDeviceInterface(); 2132 2133 const VkBufferMemoryBarrier barrier = 2134 { 2135 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 2136 DE_NULL, // const void* pNext; 2137 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2138 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 2139 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 2140 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 2141 *verificationBuffer, // VkBuffer buffer; 2142 0ull, // VkDeviceSize offset; 2143 VK_WHOLE_SIZE, // VkDeviceSize size; 2144 }; 2145 2146 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 2147 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL); 2148} 2149 2150void dispatchVerifyConstantColor(Context& context, 2151 TestObjects& testObjects, 2152 const Move<VkImageView>& imageView, 2153 const VkImageLayout layout, 2154 const Move<VkImageView>& verifyImageView, 2155 const Move<VkBuffer>& verificationBuffer, 2156 const deUint32 pushConstantSize, 2157 const void* pushConstants, 2158 const std::string& shaderName) 2159{ 2160 const DeviceInterface& vk = context.getDeviceInterface(); 2161 const VkDevice device = context.getDevice(); 2162 2163 // Set up descriptor set 2164 const Unique<VkDescriptorSetLayout> descriptorSetLayout( 2165 DescriptorSetLayoutBuilder() 2166 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 2167 .addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2168 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2169 .build(vk, device)); 2170 2171 testObjects.descriptorPools.emplace_back( 2172 DescriptorPoolBuilder() 2173 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u) 2174 .addType(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1u) 2175 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u) 2176 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 2177 2178 testObjects.descriptorSets.emplace_back(makeDescriptorSet(vk, device, *testObjects.descriptorPools.back(), *descriptorSetLayout)); 2179 2180 const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(*verificationBuffer, 0ull, sizeof(VerificationResults)); 2181 const VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, layout); 2182 const VkDescriptorImageInfo verifyImageInfo = makeDescriptorImageInfo(DE_NULL, *verifyImageView, VK_IMAGE_LAYOUT_GENERAL); 2183 2184 DescriptorSetUpdateBuilder builder; 2185 2186 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo); 2187 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo); 2188 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &verifyImageInfo); 2189 2190 builder.update(vk, device); 2191 2192 // Setup pipeline 2193 const VkPushConstantRange& verifyPushConstantRange = 2194 { 2195 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 2196 0, // uint32_t offset; 2197 pushConstantSize, // uint32_t size; 2198 }; 2199 2200 const Unique<VkShaderModule> verifyModule (createShaderModule(vk, device, context.getBinaryCollection().get(shaderName), 0u)); 2201 const Unique<VkPipelineLayout> verifyPipelineLayout (makePipelineLayout(vk, device, 1, &*descriptorSetLayout, 1, &verifyPushConstantRange)); 2202 2203 testObjects.computePipelines.push_back(PipelineSp(new Unique<VkPipeline>(makeComputePipeline(vk, device, *verifyPipelineLayout, *verifyModule)))); 2204 2205 vk.cmdBindPipeline(*testObjects.cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, **testObjects.computePipelines.back()); 2206 vk.cmdBindDescriptorSets(*testObjects.cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *verifyPipelineLayout, 0u, 1u, &testObjects.descriptorSets.back().get(), 0u, DE_NULL); 2207 2208 const VkMemoryBarrier preVerifyBarrier = 2209 { 2210 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 2211 DE_NULL, // const void* pNext; 2212 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2213 VK_ACCESS_SHADER_WRITE_BIT | 2214 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 2215 }; 2216 2217 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 2218 1u, &preVerifyBarrier, 0u, DE_NULL, 0u, DE_NULL); 2219 2220 // Area is always the first uvec4 2221 const UVec4* area = static_cast<const UVec4*>(pushConstants); 2222 2223 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, pushConstantSize, pushConstants); 2224 vk.cmdDispatch(*testObjects.cmdBuffer, (area->z() + 7) / 8, (area->w() + 7) / 8, 1); 2225 2226 postVerifyBarrier(context, testObjects, verificationBuffer); 2227} 2228 2229void testStart(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 2230{ 2231 de::Random rng(params.rngSeed); 2232 2233 wd.framebufferSize = UVec2(rng.getInt(60, 80), rng.getInt(48, 64)); 2234 wd.renderArea = UVec4(0, 0, wd.framebufferSize.x(), wd.framebufferSize.y()); 2235 if (!params.renderToWholeFramebuffer) 2236 { 2237 wd.renderArea.x() += rng.getInt(5, 15); 2238 wd.renderArea.y() += rng.getInt(5, 15); 2239 wd.renderArea.z() -= wd.renderArea.x() + rng.getInt(2, 12); 2240 wd.renderArea.w() -= wd.renderArea.y() + rng.getInt(2, 12); 2241 } 2242 2243 createWorkingData(context, params, wd); 2244 2245 testObjects.beginCommandBuffer(); 2246 2247 const DeviceInterface& vk = context.getDeviceInterface(); 2248 2249 // Clear verify image 2250 { 2251 VkImageMemoryBarrier clearBarrier = 2252 { 2253 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2254 DE_NULL, // const void* pNext; 2255 0, // VkAccessFlags srcAccessMask; 2256 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 2257 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 2258 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 2259 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 2260 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 2261 *wd.verify.image, // VkImage image; 2262 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 5u), // VkImageSubresourceRange subresourceRange; 2263 }; 2264 2265 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 2266 0u, DE_NULL, 0u, DE_NULL, 1u, &clearBarrier); 2267 2268 VkClearColorValue clearToBlack; 2269 clearToBlack.float32[0] = 0; 2270 clearToBlack.float32[1] = 0; 2271 clearToBlack.float32[2] = 0; 2272 clearToBlack.float32[3] = 1.0; 2273 vk.cmdClearColorImage(*testObjects.cmdBuffer, *wd.verify.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearToBlack, 1, &clearBarrier.subresourceRange); 2274 } 2275 2276 // Transition it to GENERAL 2277 { 2278 VkImageMemoryBarrier verifyBarrier = 2279 { 2280 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2281 DE_NULL, // const void* pNext; 2282 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2283 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask; 2284 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 2285 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout; 2286 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 2287 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 2288 *wd.verify.image, // VkImage image; 2289 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 5u), // VkImageSubresourceRange subresourceRange; 2290 }; 2291 2292 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 2293 0u, DE_NULL, 0u, DE_NULL, 1u, &verifyBarrier); 2294 } 2295} 2296 2297void testEnd(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 2298{ 2299 // If not rendering to the whole framebuffer and the images were cleared before the render pass, verify that the area outside the render pass is untouched. 2300 const bool verifyOutsideRenderArea = params.clearBeforeRenderPass && !params.renderToWholeFramebuffer; 2301 if (verifyOutsideRenderArea) 2302 { 2303 const DeviceInterface& vk = context.getDeviceInterface(); 2304 const VkDevice device = context.getDevice(); 2305 2306 const UVec4 verifyAreas[] = { 2307 UVec4(0, 0, wd.framebufferSize.x(), wd.renderArea.y()), 2308 UVec4(0, wd.renderArea.y(), wd.renderArea.x(), wd.renderArea.w()), 2309 UVec4(wd.renderArea.x() + wd.renderArea.z(), wd.renderArea.y(), wd.framebufferSize.x() - wd.renderArea.x() - wd.renderArea.z(), wd.renderArea.w()), 2310 UVec4(0, wd.renderArea.y() + wd.renderArea.w(), wd.framebufferSize.x(), wd.framebufferSize.y() - wd.renderArea.y() - wd.renderArea.w()), 2311 }; 2312 2313 for (deUint32 areaNdx = 0; areaNdx < DE_LENGTH_OF_ARRAY(verifyAreas); ++areaNdx) 2314 { 2315 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 2316 { 2317 const VerifySingleFloatPushConstants verifyColor1 = 2318 { 2319 verifyAreas[areaNdx], 2320 Vec4(params.clearValues[0].color.float32[0], params.clearValues[0].color.float32[1], params.clearValues[0].color.float32[2], params.clearValues[0].color.float32[3]), 2321 0, 2322 }; 2323 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedFloatColorImage1View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.singleVerificationBuffer, 2324 static_cast<deUint32>(sizeof(verifyColor1)), &verifyColor1, "comp_singleFloat"); 2325 } 2326 2327 if (params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT) 2328 { 2329 const VerifySingleFloatPushConstants verifyColor2 = 2330 { 2331 verifyAreas[areaNdx], 2332 Vec4(params.clearValues[1].color.float32[0], params.clearValues[1].color.float32[1], params.clearValues[1].color.float32[2], params.clearValues[1].color.float32[3]), 2333 1, 2334 }; 2335 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedFloatColorImage2View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.singleVerificationBuffer, 2336 static_cast<deUint32>(sizeof(verifyColor2)), &verifyColor2, "comp_singleFloat"); 2337 } 2338 2339 if (params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT) 2340 { 2341 const VerifySingleIntPushConstants verifyColor3 = 2342 { 2343 verifyAreas[areaNdx], 2344 IVec4(params.clearValues[2].color.int32[0], params.clearValues[2].color.int32[1], params.clearValues[2].color.int32[2], params.clearValues[2].color.int32[3]), 2345 2, 2346 }; 2347 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedIntColorImageView(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.singleVerificationBuffer, 2348 static_cast<deUint32>(sizeof(verifyColor3)), &verifyColor3, "comp_singleInt"); 2349 } 2350 2351 if (params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT && isDepthFormat(params.depthStencilFormat)) 2352 { 2353 const VerifySingleDepthPushConstants verifyDepth = 2354 { 2355 verifyAreas[areaNdx], 2356 params.clearValues[3].depthStencil.depth, 2357 }; 2358 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedDepthOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, wd.verify.view, wd.singleVerificationBuffer, 2359 static_cast<deUint32>(sizeof(verifyDepth)), &verifyDepth, "comp_singleDepth"); 2360 } 2361 2362 if (params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT && isStencilFormat(params.depthStencilFormat)) 2363 { 2364 const VerifySingleStencilPushConstants verifyStencil = 2365 { 2366 verifyAreas[areaNdx], 2367 params.clearValues[3].depthStencil.stencil, 2368 }; 2369 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedStencilOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, wd.verify.view, wd.singleVerificationBuffer, 2370 static_cast<deUint32>(sizeof(verifyStencil)), &verifyStencil, "comp_singleStencil"); 2371 } 2372 } 2373 2374 invalidateAlloc(vk, device, *wd.singleVerificationBufferAlloc); 2375 } 2376 2377 testObjects.submitCommandsAndWait(); 2378} 2379 2380tcu::TestStatus verify(Context& context, const TestParams& params, WorkingData& wd) 2381{ 2382 bool drawsToColor1 = false; 2383 bool drawsToColor2 = false; 2384 bool drawsToColor3 = false; 2385 bool drawsToDepthStencil = false; 2386 for (const TestParams::PerPass& perPass : params.perPass) 2387 { 2388 if (perPass.floatColor1Location >= 0) 2389 drawsToColor1 = true; 2390 if (perPass.floatColor2Location >= 0) 2391 drawsToColor2 = true; 2392 if (perPass.intColorLocation >= 0) 2393 drawsToColor3 = true; 2394 if (perPass.hasDepthStencil) 2395 drawsToDepthStencil = true; 2396 } 2397 2398 logTestImages(context, params, wd, drawsToColor1, drawsToColor2, drawsToColor3, drawsToDepthStencil); 2399 2400 // Verify draw call results 2401 { 2402 const VerificationResults* const results = static_cast<const VerificationResults*>(wd.verificationBufferAlloc->getHostPtr()); 2403 const deUint32 totalPixels = wd.renderArea.z() * wd.renderArea.w(); 2404 bool allOk = true; 2405 const char* errorDelim = ""; 2406 std::string errorMsg = "Incorrect multisampled rendering for "; 2407 2408 if (drawsToColor1) 2409 if (!checkAndReportError(context, results->color1Verification, totalPixels, "color attachment 1")) 2410 { 2411 errorMsg += errorDelim; 2412 errorMsg += "color attachment 1"; 2413 errorDelim = ", "; 2414 allOk = false; 2415 } 2416 2417 if (drawsToColor2) 2418 if (!checkAndReportError(context, results->color2Verification, totalPixels, "color attachment 2")) 2419 { 2420 errorMsg += errorDelim; 2421 errorMsg += "color attachment 2"; 2422 errorDelim = ", "; 2423 allOk = false; 2424 } 2425 2426 if (drawsToColor3) 2427 if (!checkAndReportError(context, results->color3Verification, totalPixels, "color attachment 3")) 2428 { 2429 errorMsg += errorDelim; 2430 errorMsg += "color attachment 3"; 2431 errorDelim = ", "; 2432 allOk = false; 2433 } 2434 2435 if (drawsToDepthStencil && isDepthFormat(params.depthStencilFormat)) 2436 if (!checkAndReportError(context, results->depthVerification, totalPixels, "depth attachment")) 2437 { 2438 errorMsg += errorDelim; 2439 errorMsg += "depth attachment"; 2440 errorDelim = ", "; 2441 allOk = false; 2442 } 2443 2444 if (drawsToDepthStencil && isStencilFormat(params.depthStencilFormat)) 2445 if (!checkAndReportError(context, results->stencilVerification, totalPixels, "stencil attachment")) 2446 { 2447 errorMsg += errorDelim; 2448 errorMsg += "stencil attachment"; 2449 errorDelim = ", "; 2450 allOk = false; 2451 } 2452 2453 if (!allOk) 2454 { 2455 logVerifyImages(context, params, wd, drawsToColor1, drawsToColor2, drawsToColor3, drawsToDepthStencil); 2456 return tcu::TestStatus::fail(errorMsg); 2457 } 2458 } 2459 2460 const bool verifyOutsideRenderArea = params.clearBeforeRenderPass && !params.renderToWholeFramebuffer; 2461 if (verifyOutsideRenderArea) 2462 { 2463 const VerificationResults* const results = static_cast<const VerificationResults*>(wd.singleVerificationBufferAlloc->getHostPtr()); 2464 const deUint32 totalPixels = wd.framebufferSize.x() * wd.framebufferSize.y() - wd.renderArea.z() * wd.renderArea.w(); 2465 bool allOk = true; 2466 2467 if (params.numFloatColor1Samples == VK_SAMPLE_COUNT_1_BIT) 2468 allOk = checkAndReportError(context, results->color1Verification, totalPixels, "color attachment 1 (outside render area)") && allOk; 2469 if (params.numFloatColor2Samples == VK_SAMPLE_COUNT_1_BIT) 2470 allOk = checkAndReportError(context, results->color2Verification, totalPixels, "color attachment 2 (outside render area)") && allOk; 2471 if (params.numIntColorSamples == VK_SAMPLE_COUNT_1_BIT) 2472 allOk = checkAndReportError(context, results->color3Verification, totalPixels, "color attachment 3 (outside render area)") && allOk; 2473 if (params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT && isDepthFormat(params.depthStencilFormat)) 2474 allOk = checkAndReportError(context, results->depthVerification, totalPixels, "depth attachment (outside render area)") && allOk; 2475 if (params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT && isStencilFormat(params.depthStencilFormat)) 2476 allOk = checkAndReportError(context, results->stencilVerification, totalPixels, "stencil attachment (outside render area)") && allOk; 2477 2478 if (!allOk) 2479 { 2480 logVerifyImages(context, params, wd, drawsToColor1, drawsToColor2, drawsToColor3, drawsToDepthStencil); 2481 return tcu::TestStatus::fail("Detected corruption outside render area"); 2482 } 2483 } 2484 2485 return tcu::TestStatus::pass("Pass"); 2486} 2487 2488void initConstantColorVerifyPrograms (SourceCollections& programCollection, const TestParams params) 2489{ 2490 const bool usesSignedIntFormat = params.intColorFormat == VK_FORMAT_R16G16B16A16_SINT; 2491 2492 // Compute shader - Verify outside render area is intact (float colors) 2493 { 2494 std::ostringstream src; 2495 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2496 << "#extension GL_EXT_samplerless_texture_functions : require\n" 2497 << "\n" 2498 << "layout(push_constant) uniform PushConstants {\n" 2499 << " uvec4 area;\n" 2500 << " vec4 color;\n" 2501 << " uint attachmentNdx;\n" 2502 << "} params;\n" 2503 << "\n" 2504 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 2505 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 2506 << " uint colorVerification[3];\n" 2507 << " uint depthVerification;\n" 2508 << " uint stencilVerification;\n" 2509 << "} sb_out;\n" 2510 << "layout(set = 0, binding = 1) uniform texture2D colorImage;\n" 2511 << "layout(set = 0, binding = 2, rgba8) uniform writeonly image2DArray verify;\n" 2512 << "\n" 2513 << "bool v4matches(vec4 a, vec4 b, float error)\n" 2514 << "{\n" 2515 << " return all(lessThan(abs(a - b), vec4(error)));\n" 2516 << "}\n" 2517 << "\n" 2518 << "void main (void)\n" 2519 << "{\n" 2520 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 2521 << " return;\n" 2522 << "\n" 2523 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 2524 << "\n" 2525 << " vec4 result = vec4(1, 0, 0, 1);\n" 2526 << " vec4 color = texelFetch(colorImage, ivec2(coords), 0);\n" 2527 << " if (v4matches(color, params.color, 0.01))\n" 2528 << " {\n" 2529 << " atomicAdd(sb_out.colorVerification[params.attachmentNdx], 1);\n" 2530 << " result = vec4(0, 1, 0, 1);\n" 2531 << " }\n" 2532 << " imageStore(verify, ivec3(coords, params.attachmentNdx), result);\n" 2533 << "}\n"; 2534 2535 programCollection.glslSources.add("comp_singleFloat") << glu::ComputeSource(src.str()); 2536 } 2537 2538 // Compute shader - Verify outside render area is intact (int colors) 2539 { 2540 std::ostringstream src; 2541 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2542 << "#extension GL_EXT_samplerless_texture_functions : require\n" 2543 << "\n" 2544 << "layout(push_constant) uniform PushConstants {\n" 2545 << " uvec4 area;\n" 2546 << " ivec4 color;\n" 2547 << " uint attachmentNdx;\n" 2548 << "} params;\n" 2549 << "\n" 2550 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 2551 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 2552 << " uint colorVerification[3];\n" 2553 << " uint depthVerification;\n" 2554 << " uint stencilVerification;\n" 2555 << "} sb_out;\n" 2556 << "layout(set = 0, binding = 1) uniform " << (usesSignedIntFormat ? "i" : "u") << "texture2D colorImage;\n" 2557 << "layout(set = 0, binding = 2, rgba8) uniform writeonly image2DArray verify;\n" 2558 << "\n" 2559 << "bool i4matches(ivec4 a, ivec4 b, int error)\n" 2560 << "{\n" 2561 << " return all(lessThanEqual(abs(a - b), ivec4(error)));\n" 2562 << "}\n" 2563 << "\n" 2564 << "void main (void)\n" 2565 << "{\n" 2566 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 2567 << " return;\n" 2568 << "\n" 2569 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 2570 << "\n" 2571 << " vec4 result = vec4(1, 0, 0, 1);\n" 2572 << " ivec4 color = ivec4(texelFetch(colorImage, ivec2(coords), 0));\n" 2573 << " if (i4matches(color, params.color, 0))\n" 2574 << " {\n" 2575 << " atomicAdd(sb_out.colorVerification[params.attachmentNdx], 1);\n" 2576 << " result = vec4(0, 1, 0, 1);\n" 2577 << " }\n" 2578 << " imageStore(verify, ivec3(coords, params.attachmentNdx), result);\n" 2579 << "}\n"; 2580 2581 programCollection.glslSources.add("comp_singleInt") << glu::ComputeSource(src.str()); 2582 } 2583 2584 // Compute shader - Verify outside render area is intact (depth) 2585 { 2586 std::ostringstream src; 2587 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2588 << "#extension GL_EXT_samplerless_texture_functions : require\n" 2589 << "\n" 2590 << "layout(push_constant) uniform PushConstants {\n" 2591 << " uvec4 area;\n" 2592 << " float depthData;\n" 2593 << "} params;\n" 2594 << "\n" 2595 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 2596 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 2597 << " uint colorVerification[3];\n" 2598 << " uint depthVerification;\n" 2599 << " uint stencilVerification;\n" 2600 << "} sb_out;\n" 2601 << "layout(set = 0, binding = 1) uniform texture2D depthImage;\n" 2602 << "layout(set = 0, binding = 2, rgba8) uniform writeonly image2DArray verify;\n" 2603 << "\n" 2604 << "bool fmatches(float a, float b, float error)\n" 2605 << "{\n" 2606 << " return abs(a - b) < error;\n" 2607 << "}\n" 2608 << "\n" 2609 << "void main (void)\n" 2610 << "{\n" 2611 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 2612 << " return;\n" 2613 << "\n" 2614 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 2615 << "\n" 2616 << " vec4 result = vec4(1, 0, 0, 1);\n" 2617 << " float depth = texelFetch(depthImage, ivec2(coords), 0).r;\n" 2618 << " if (fmatches(depth, params.depthData, 0.01))\n" 2619 << " {\n" 2620 << " atomicAdd(sb_out.depthVerification, 1);\n" 2621 << " result = vec4(0, 1, 0, 1);\n" 2622 << " }\n" 2623 << " imageStore(verify, ivec3(coords, 3), result);\n" 2624 << "}\n"; 2625 2626 programCollection.glslSources.add("comp_singleDepth") << glu::ComputeSource(src.str()); 2627 } 2628 2629 // Compute shader - Verify outside render area is intact (stencil) 2630 { 2631 std::ostringstream src; 2632 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2633 << "#extension GL_EXT_samplerless_texture_functions : require\n" 2634 << "\n" 2635 << "layout(push_constant) uniform PushConstants {\n" 2636 << " uvec4 area;\n" 2637 << " uint stencilData;\n" 2638 << "} params;\n" 2639 << "\n" 2640 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 2641 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 2642 << " uint colorVerification[3];\n" 2643 << " uint depthVerification;\n" 2644 << " uint stencilVerification;\n" 2645 << "} sb_out;\n" 2646 << "layout(set = 0, binding = 1) uniform utexture2D stencilImage;\n" 2647 << "layout(set = 0, binding = 2, rgba8) uniform writeonly image2DArray verify;\n" 2648 << "\n" 2649 << "bool umatches(uint a, uint b, uint error)\n" 2650 << "{\n" 2651 << " return abs(a - b) <= error;\n" 2652 << "}\n" 2653 << "\n" 2654 << "void main (void)\n" 2655 << "{\n" 2656 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 2657 << " return;\n" 2658 << "\n" 2659 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 2660 << "\n" 2661 << " vec4 result = vec4(1, 0, 0, 1);\n" 2662 << " uint stencil = texelFetch(stencilImage, ivec2(coords), 0).r;\n" 2663 << " if (umatches(stencil, params.stencilData, 0))\n" 2664 << " {\n" 2665 << " atomicAdd(sb_out.stencilVerification, 1);\n" 2666 << " result = vec4(0, 1, 0, 1);\n" 2667 << " }\n" 2668 << " imageStore(verify, ivec3(coords, 4), result);\n" 2669 << "}\n"; 2670 2671 programCollection.glslSources.add("comp_singleStencil") << glu::ComputeSource(src.str()); 2672 } 2673} 2674 2675void initBasicPrograms (SourceCollections& programCollection, const TestParams params) 2676{ 2677 // Vertex shader - position 2678 { 2679 std::ostringstream src; 2680 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2681 << "\n" 2682 << "layout(location = 0) in vec4 in_position;\n" 2683 << "\n" 2684 << "out gl_PerVertex {\n" 2685 << " vec4 gl_Position;\n" 2686 << "};\n" 2687 << "\n" 2688 << "void main(void)\n" 2689 << "{\n" 2690 << " gl_Position = in_position;\n" 2691 << "}\n"; 2692 2693 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 2694 } 2695 2696 const bool usesSignedIntFormat = params.intColorFormat == VK_FORMAT_R16G16B16A16_SINT; 2697 const char* intTypePrefix = usesSignedIntFormat ? "i" : "u"; 2698 2699 // The framebuffer contains four attachments with the same number of samples. 2700 // The fragment shader outputs a different color per sample (in a gradient) to verify that the multisampled image actually has that many samples: 2701 // 2702 // - For samples [4s, 4s+3), the shader outputs: 2703 // 2704 // Vec4(0, v, v, v), 2705 // Vec4(v, 0, v, v), 2706 // Vec4(v, v, 0, v), 2707 // Vec4(v, v, v, 0), 2708 // 2709 // for float attachments where v = 1-s*0.2. For sample s, it outputs: 2710 // 2711 // UVec4(v, v + 1, v + 2, v + 3), 2712 // 2713 // for the int attachment where v = (s+1)*(s+1)*10. 2714 // 2715 // Additionally, the fragment shader outputs depth based on the sample index as well. For sample s, it outputs 1 - (s^1)/16. 2716 // Note that ^1 ensures VK_RESOLVE_MODE_SAMPLE_ZERO_BIT and VK_RESOLVE_MODE_MAX_BIT produce different values. 2717 { 2718 const TestParams::PerPass &perPass = params.perPass[0]; 2719 2720 // The shader outputs up to 16 samples 2721 const deUint32 numSamples = static_cast<deUint32>(perPass.numSamples); 2722 2723 DE_ASSERT(numSamples <= 16); 2724 2725 std::ostringstream src; 2726 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2727 << "\n" 2728 << "layout(location = " << perPass.floatColor1Location << ") out vec4 o_color1;\n" 2729 << "layout(location = " << perPass.floatColor2Location << ") out vec4 o_color2;\n" 2730 << "layout(location = " << perPass.intColorLocation << ") out " << intTypePrefix << "vec4 o_color3;\n" 2731 << "\n" 2732 << "layout(push_constant) uniform PushConstants {\n" 2733 << " uvec4 area;\n" 2734 << "} params;\n" 2735 << "\n" 2736 << "void main(void)\n" 2737 << "{\n" 2738 << " vec2 uv = (gl_FragCoord.xy - vec2(params.area.xy)) / vec2(params.area.zw);\n"; 2739 for (deUint32 sampleID = 0; sampleID < numSamples; ++sampleID) 2740 { 2741 const char* uvComponent = sampleID % 2 == 0 ? "uv.x" : "uv.y"; 2742 2743 const float floatValue = 1 - static_cast<float>(sampleID / 4) * 0.2f; 2744 const deUint32 intValue = (sampleID + 1) * (sampleID + 1) * 10; 2745 const float depthValue = 1 - static_cast<float>(sampleID ^ 1) / 16.0f; 2746 2747 const Vec4 floatChannels(sampleID % 4 == 0 ? 0 : floatValue, 2748 sampleID % 4 == 1 ? 0 : floatValue, 2749 sampleID % 4 == 2 ? 0 : floatValue, 2750 sampleID % 4 == 3 ? 0 : floatValue); 2751 const UVec4 intChannels(intValue, intValue + 1, intValue + 2, intValue + 3); 2752 2753 src << " " << (sampleID == 0 ? "" : "else ") << "if (gl_SampleID == " << sampleID << ")\n" 2754 << " {\n" 2755 << " o_color1 = vec4(" << floatChannels.x() << ", " << floatChannels.y() << ", " << floatChannels.z() << ", " << floatChannels.w() << ") * " << uvComponent << ";\n" 2756 << " o_color2 = vec4(" << floatChannels.x() << ", " << floatChannels.y() << ", " << floatChannels.z() << ", " << floatChannels.w() << ") * " << uvComponent << ";\n" 2757 << " o_color3 = " << intTypePrefix << "vec4(vec4(" << intChannels.x() << ", " << intChannels.y() << ", " << intChannels.z() << ", " << intChannels.w() << ") * " << uvComponent << ");\n" 2758 << " gl_FragDepth = " << depthValue << ";\n" 2759 << " }\n"; 2760 } 2761 src << "}\n"; 2762 2763 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); 2764 } 2765 2766 // Compute shader - verify the results of rendering 2767 // 2768 // Take the formulas used for the fragment shader. Note the following: 2769 // 2770 // n-1 2771 // sum(1 - s*0.2) 2772 // 0 n - (n*(n-1))/2 * 0.2 2773 // ----------------- = ----------------------- = 1 - (n-1)*0.1 2774 // n n 2775 // 2776 // When rendering is done to every sample and the attachment is resolved, we expect: 2777 // 2778 // - For float attachments, average of: 2779 // * Horizontal gradient: 2780 // 2781 // Vec4(0, 1, 1, 1) if 2 samples 2782 // Vec4(0.5v, v, 0.5v, v) o.w. where v = 1 - (n - 1)*0.1 where n = floor(sampleCount / 4). 2783 // 2784 // * Vertical gradient: 2785 // 2786 // Vec4(1, 0, 1, 1) if 2 samples 2787 // Vec4(v, 0.5v, v, 0.5v) o.w. where v = 1 - (n - 1)*0.1 where n = floor(sampleCount / 4). 2788 // 2789 // - For the int attachments, any of UVec4(v, v + 1, v + 2, v + 3) where v = (s+1)*(s+1)*10 2790 // - For the depth attachment, either 1 or 1-1/16 based on whether MAX or SAMPLE_ZERO resolve modes are selected respectively. 2791 // - For the stencil attachment, expect the clear value + 1. 2792 { 2793 const TestParams::PerPass &perPass = params.perPass[0]; 2794 2795 // The shader outputs up to 16 samples 2796 const deUint32 numSamples = static_cast<deUint32>(perPass.numSamples); 2797 2798 const float floatValue = 1 - static_cast<float>((numSamples / 4) - 1) * 0.1f; 2799 2800 const Vec4 floatExpectHorizontal = numSamples == 2 ? Vec4(0, 1, 1, 1) 2801 : Vec4(0.5f * floatValue, floatValue, 0.5f * floatValue, floatValue); 2802 const Vec4 floatExpectVertical = numSamples == 2 ? Vec4(1, 0, 1, 1) 2803 : Vec4(floatValue, 0.5f * floatValue, floatValue, 0.5f * floatValue); 2804 2805 std::ostringstream src; 2806 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 2807 << "#extension GL_EXT_samplerless_texture_functions : require\n" 2808 << "\n" 2809 << "layout(push_constant) uniform PushConstants {\n" 2810 << " uvec4 area;\n" 2811 << " uint stencilExpect;\n" 2812 << "} params;\n" 2813 << "\n" 2814 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 2815 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 2816 << " uint colorVerification[3];\n" 2817 << " uint depthVerification;\n" 2818 << " uint stencilVerification;\n" 2819 << "} sb_out;\n" 2820 << "layout(set = 0, binding = 1) uniform texture2D color1Image;\n" 2821 << "layout(set = 0, binding = 2) uniform texture2D color2Image;\n" 2822 << "layout(set = 0, binding = 3) uniform " << (usesSignedIntFormat ? "i" : "u") << "texture2D color3Image;\n"; 2823 if (isDepthFormat(params.depthStencilFormat)) 2824 src << "layout(set = 0, binding = 4) uniform texture2D depthImage;\n"; 2825 if (isStencilFormat(params.depthStencilFormat)) 2826 src << "layout(set = 0, binding = 5) uniform utexture2D stencilImage;\n"; 2827 src << "layout(set = 0, binding = 6, rgba8) uniform writeonly image2DArray verify;\n" 2828 << "\n" 2829 << "bool fmatches(float a, float b, float error)\n" 2830 << "{\n" 2831 << " return abs(a - b) < error;\n" 2832 << "}\n" 2833 << "bool umatches(uint a, uint b, uint error)\n" 2834 << "{\n" 2835 << " return abs(a - b) <= error;\n" 2836 << "}\n" 2837 << "bool v4matches(vec4 a, vec4 b, vec4 error)\n" 2838 << "{\n" 2839 << " return all(lessThan(abs(a - b), error));\n" 2840 << "}\n" 2841 << "bool i4matchesEither(ivec4 a, ivec4 b, ivec4 c, int errorB, int errorC)\n" 2842 << "{\n" 2843 << " return all(lessThanEqual(abs(a - b), ivec4(errorB))) || all(lessThanEqual(abs(a - c), ivec4(errorC)));\n" 2844 << "}\n" 2845 << "\n" 2846 << "void main (void)\n" 2847 << "{\n" 2848 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 2849 << " return;\n" 2850 << "\n" 2851 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 2852 << " vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5)) / vec2(params.area.zw);\n" 2853 << "\n" 2854 << " vec4 result1 = vec4(1, 0, 0, 1);\n" 2855 << " vec4 color1 = texelFetch(color1Image, ivec2(coords), 0);\n" 2856 << " vec4 expected1H = vec4(" << floatExpectHorizontal.x() << ", " 2857 << floatExpectHorizontal.y() << ", " 2858 << floatExpectHorizontal.z() << ", " 2859 << floatExpectHorizontal.w() << ");\n" 2860 << " vec4 expected1V = vec4(" << floatExpectVertical.x() << ", " 2861 << floatExpectVertical.y() << ", " 2862 << floatExpectVertical.z() << ", " 2863 << floatExpectVertical.w() << ");\n" 2864 << " vec4 expected1 = (expected1H * uv.x + expected1V * uv.y) / 2.0;\n" 2865 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 2866 << " if (v4matches(color1, expected1, max(expected1H / float(params.area.z), expected1V / float(params.area.w)) + 2.0/255.0))\n" 2867 << " {\n" 2868 << " atomicAdd(sb_out.colorVerification[0], 1);\n" 2869 << " result1 = vec4(0, 1, 0, 1);\n" 2870 << " }\n" 2871 << " imageStore(verify, ivec3(coords, 0), result1);\n" 2872 << "\n" 2873 << " vec4 result2 = vec4(1, 0, 0, 1);\n" 2874 << " vec4 color2 = texelFetch(color2Image, ivec2(coords), 0);\n" 2875 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 2876 << " if (v4matches(color2, expected1, max(expected1H / float(params.area.z), expected1V / float(params.area.w)) + 2.0/1024.0))\n" 2877 << " {\n" 2878 << " atomicAdd(sb_out.colorVerification[1], 1);\n" 2879 << " result2 = vec4(0, 1, 0, 1);\n" 2880 << " }\n" 2881 << " imageStore(verify, ivec3(coords, 1), result2);\n" 2882 << "\n" 2883 << " vec4 result3 = vec4(1, 0, 0, 1);\n" 2884 << " ivec4 color3 = ivec4(texelFetch(color3Image, ivec2(coords), 0));\n" 2885 << " if ("; 2886 for (deUint32 sampleID = 0; sampleID < numSamples; ++sampleID) 2887 { 2888 const deUint32 intValue = (sampleID + 1) * (sampleID + 1) * 10; 2889 const UVec4 intExpect(intValue, intValue + 1, intValue + 2, intValue + 3); 2890 2891 src << (sampleID == 0 ? "" : " || ") 2892 << "i4matchesEither(color3, ivec4(vec4(" << intExpect.x() << ", " << intExpect.y() << ", " << intExpect.z() << ", " << intExpect.w() << ") * uv.x), " 2893 << "ivec4(vec4(" << intExpect.x() << ", " << intExpect.y() << ", " << intExpect.z() << ", " << intExpect.w() << ") * uv.y), " 2894 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 2895 << intValue << " / int(params.area.z) + 1, " 2896 << intValue << " / int(params.area.w) + 1)" << (sampleID == numSamples - 1 ? ")" : "") << "\n"; 2897 } 2898 src << " {\n" 2899 << " atomicAdd(sb_out.colorVerification[2], 1);\n" 2900 << " result3 = vec4(0, 1, 0, 1);\n" 2901 << " }\n" 2902 << " imageStore(verify, ivec3(coords, 2), result3);\n" 2903 << "\n"; 2904 if (isDepthFormat(params.depthStencilFormat)) 2905 { 2906 const float expect = perPass.depthStencilResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT ? 1 - 1/16.0f : 1.0f; 2907 2908 src << " vec4 resultDepth = vec4(1, 0, 0, 1);\n" 2909 << " float depth = texelFetch(depthImage, ivec2(coords), 0).r;\n" 2910 << " if (fmatches(depth, " << expect << ", 0.01))\n" 2911 << " {\n" 2912 << " atomicAdd(sb_out.depthVerification, 1);\n" 2913 << " resultDepth = vec4(0, 1, 0, 1);\n" 2914 << " }\n" 2915 << " imageStore(verify, ivec3(coords, 3), resultDepth);\n"; 2916 } 2917 if (isStencilFormat(params.depthStencilFormat)) 2918 { 2919 src << " vec4 resultStencil = vec4(1, 0, 0, 1);\n" 2920 << " uint stencil = texelFetch(stencilImage, ivec2(coords), 0).r;\n" 2921 << " if (umatches(stencil, params.stencilExpect, 0))\n" 2922 << " {\n" 2923 << " atomicAdd(sb_out.stencilVerification, 1);\n" 2924 << " resultStencil = vec4(0, 1, 0, 1);\n" 2925 << " }\n" 2926 << " imageStore(verify, ivec3(coords, 4), resultStencil);\n"; 2927 } 2928 src << "}\n"; 2929 2930 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()); 2931 } 2932 2933 // Always generate constant-color checks as they are used by vkCmdClearAttachments tests 2934 initConstantColorVerifyPrograms(programCollection, params); 2935} 2936 2937void dispatchVerifyBasic(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 2938{ 2939 const DeviceInterface& vk = context.getDeviceInterface(); 2940 const VkDevice device = context.getDevice(); 2941 2942 postDrawBarrier(context, testObjects); 2943 2944 const VkPushConstantRange& verifyPushConstantRange = 2945 { 2946 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 2947 0, // uint32_t offset; 2948 static_cast<deUint32>(sizeof(UVec4) + sizeof(deUint32)), // uint32_t size; 2949 }; 2950 2951 Move<VkPipelineLayout> verifyPipelineLayout; 2952 setupVerifyDescriptorSetAndPipeline(context, params, wd, testObjects, &verifyPushConstantRange, verifyPipelineLayout); 2953 2954 const deUint32 stencilExpect = params.clearValues[3].depthStencil.stencil + 1; 2955 2956 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(UVec4), &wd.renderArea); 2957 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, sizeof(UVec4), sizeof(deUint32), &stencilExpect); 2958 vk.cmdDispatch(*testObjects.cmdBuffer, (wd.renderArea.z() + 7) / 8, (wd.renderArea.w() + 7) / 8, 1); 2959 2960 postVerifyBarrier(context, testObjects, wd.verificationBuffer); 2961 2962 invalidateAlloc(vk, device, *wd.verificationBufferAlloc); 2963} 2964 2965void drawBasic (Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 2966{ 2967 const InstanceInterface& vki = context.getInstanceInterface(); 2968 const DeviceInterface& vk = context.getDeviceInterface(); 2969 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 2970 const VkDevice device = context.getDevice(); 2971 VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo; 2972 std::vector<VkFormat> colorAttachmentFormats = { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }; 2973 std::vector<VkRenderingAttachmentInfo> colorAttachmentInfos(4u); 2974 VkRenderingAttachmentInfo depthStencilAttachmentInfo; 2975 2976 DE_ASSERT(params.perPass.size() == 1); 2977 2978 if (params.clearBeforeRenderPass) 2979 { 2980 clearImagesBeforeDraw(context, params, wd, testObjects); 2981 } 2982 2983 if (params.dynamicRendering) 2984 { 2985 preRenderingImageLayoutTransition(context, params, wd, testObjects); 2986 initResolveImageLayouts(context, params, wd, testObjects); 2987 } 2988 2989 // Create a render pass and a framebuffer 2990 { 2991 std::vector<VkSubpassDescription2> subpasses; 2992 std::vector<VkImage> images; 2993 std::vector<VkImageView> attachments; 2994 std::vector<VkAttachmentDescription2> attachmentDescriptions; 2995 std::vector<VkAttachmentReference2> attachmentReferences; 2996 std::vector<VkAttachmentReference2> resolveAttachmentReferences; 2997 VkMultisampledRenderToSingleSampledInfoEXT msrtss; 2998 VkSubpassDescriptionDepthStencilResolve depthStencilResolve; 2999 deInt32 attachmentNdxes[8] = {-1, -1, -1, -1, 3000 -1, -1, -1, -1}; 3001 deUint32 attachmentUseMask = 0; 3002 3003 initializeAttachments(params, wd, images, attachments, 0, attachmentNdxes); 3004 3005 if (params.dynamicRendering) 3006 { 3007 initializeRenderingAttachmentInfos(params, 3008 wd, 3009 colorAttachmentInfos, 3010 depthStencilAttachmentInfo, 3011 colorAttachmentFormats, 3012 attachmentNdxes, 3013 attachmentUseMask, 3014 0u); 3015 3016 pipelineRenderingCreateInfo = { 3017 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType 3018 DE_NULL, // const void* pNext 3019 0u, // uint32_t viewMask 3020 static_cast<uint32_t>(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount 3021 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats 3022 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat 3023 VK_FORMAT_UNDEFINED // VkFormat stencilAttachmentFormat 3024 }; 3025 3026 if (params.usesDepthStencilInPass(0)) 3027 { 3028 if (isDepthFormat(params.depthStencilFormat)) 3029 pipelineRenderingCreateInfo.depthAttachmentFormat = params.depthStencilFormat; 3030 if (isStencilFormat(params.depthStencilFormat)) 3031 pipelineRenderingCreateInfo.stencilAttachmentFormat = params.depthStencilFormat; 3032 } 3033 } 3034 else 3035 { 3036 initializeAttachmentDescriptions(params, attachmentDescriptions, params.clearBeforeRenderPass, attachmentNdxes, attachmentUseMask); 3037 3038 addSubpassDescription(params, 3039 0, 3040 attachmentReferences, 3041 resolveAttachmentReferences, 3042 depthStencilResolve, 3043 nullptr, 3044 msrtss, 3045 subpasses, 3046 {}, 3047 attachmentNdxes); 3048 3049 createRenderPassAndFramebuffer(context, wd, testObjects, params.pipelineConstructionType, images, attachments, attachmentDescriptions, subpasses, {}); 3050 } 3051 } 3052 3053 { 3054 const VkPushConstantRange& pushConstantRange = 3055 { 3056 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 3057 0, // uint32_t offset; 3058 static_cast<deUint32>(sizeof(UVec4)), // uint32_t size; 3059 }; 3060 3061 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 3062 const ShaderWrapper fragmentModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag"), 0u)); 3063 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, 0, DE_NULL, 1, &pushConstantRange); 3064 3065 testObjects.graphicsPipelines.push_back( 3066 pipeline::makeGraphicsPipeline(vki, 3067 vk, 3068 physicalDevice, 3069 device, 3070 context.getDeviceExtensions(), 3071 params.pipelineConstructionType, 3072 pipelineLayout, 3073 params.dynamicRendering ? DE_NULL : *testObjects.renderPassFramebuffers.back(), 3074 params.dynamicRendering ? &pipelineRenderingCreateInfo : DE_NULL, 3075 vertexModule, 3076 fragmentModule, 3077 false, 3078 true, 3079 false, 3080 0, 3081 0, 3082 params.perPass[0].intColorLocation, 3083 wd.renderArea, 3084 wd.renderArea, 3085 params.perPass[0].numSamples, 3086 params.useGarbageAttachment)); 3087 3088 if (params.dynamicRendering) 3089 { 3090 startRendering(context, params, wd, testObjects, static_cast<uint32_t>(colorAttachmentFormats.size()), colorAttachmentInfos, depthStencilAttachmentInfo, 0u); 3091 } 3092 else 3093 { 3094 startRenderPass(context, wd, testObjects, DE_LENGTH_OF_ARRAY(params.clearValues), params.clearValues); 3095 } 3096 3097 const VkDeviceSize vertexBufferOffset = 0; 3098 vk.cmdBindVertexBuffers(*testObjects.cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 3099 3100 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), &wd.renderArea); 3101 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 3102 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 3103 3104 if (params.dynamicRendering) 3105 { 3106 vk.cmdEndRendering(*testObjects.cmdBuffer); 3107 } 3108 else 3109 { 3110 testObjects.renderPassFramebuffers.back().end(vk, *testObjects.cmdBuffer); 3111 } 3112 } 3113 3114 if (params.dynamicRendering) 3115 { 3116 postRenderingResolveImageLayoutTransition(context, params, wd, testObjects); 3117 } 3118 3119 // Verify results 3120 dispatchVerifyBasic(context, params, wd, testObjects); 3121} 3122 3123//! Verify multisampled rendering is done with the exact number of samples. 3124tcu::TestStatus testBasic (Context& context, const TestParams params) 3125{ 3126 WorkingData wd; 3127 TestObjects testObjects(context); 3128 testStart(context, params, wd, testObjects); 3129 3130 drawBasic (context, params, wd, testObjects); 3131 3132 testEnd(context, params, wd, testObjects); 3133 return verify(context, params, wd); 3134} 3135 3136void generateBasicTest (de::Random& rng, TestParams& params, const VkSampleCountFlagBits sampleCount, const VkResolveModeFlagBits resolveMode, const bool renderToWholeFramebuffer) 3137{ 3138 params.perPass.resize(1); 3139 3140 TestParams::PerPass& perPass = params.perPass[0]; 3141 3142 // Set the sample count for attachments. 3143 if (params.isMultisampledRenderToSingleSampled) 3144 { 3145 params.numFloatColor1Samples = VK_SAMPLE_COUNT_1_BIT; 3146 params.numFloatColor2Samples = VK_SAMPLE_COUNT_1_BIT; 3147 params.numIntColorSamples = VK_SAMPLE_COUNT_1_BIT; 3148 params.numDepthStencilSamples = VK_SAMPLE_COUNT_1_BIT; 3149 3150 perPass.resolveFloatColor1 = false; 3151 perPass.resolveFloatColor2 = false; 3152 perPass.resolveIntColor = false; 3153 perPass.resolveDepthStencil = false; 3154 } 3155 else 3156 { 3157 params.numFloatColor1Samples = sampleCount; 3158 params.numFloatColor2Samples = sampleCount; 3159 params.numIntColorSamples = sampleCount; 3160 params.numDepthStencilSamples = sampleCount; 3161 3162 perPass.resolveFloatColor1 = true; 3163 perPass.resolveFloatColor2 = true; 3164 perPass.resolveIntColor = true; 3165 perPass.resolveDepthStencil = true; 3166 } 3167 perPass.depthStencilResolveMode = resolveMode; 3168 3169 perPass.numSamples = sampleCount; 3170 3171 // Set locations for the color attachments. 3172 perPass.floatColor1Location = 0; 3173 perPass.floatColor2Location = 1; 3174 perPass.intColorLocation = 2; 3175 3176 // Depth/stencil is always used 3177 perPass.hasDepthStencil = true; 3178 3179 // Always clear before render pass so outside render area can be verified. 3180 params.clearBeforeRenderPass = true; 3181 params.renderToWholeFramebuffer = renderToWholeFramebuffer; 3182 params.testBlendsColors = false; 3183 3184 // Set random clear values. 3185 generateRandomClearValues(rng, params, params.clearValues, false); 3186 3187 params.rngSeed = rng.getUint32(); 3188} 3189 3190void dispatchVerifyClearAttachments(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects, const UVec4 regions[RegionCount], const VkClearValue clearValues[RegionCount - 1][4]) 3191{ 3192 const DeviceInterface& vk = context.getDeviceInterface(); 3193 const VkDevice device = context.getDevice(); 3194 3195 postDrawBarrier(context, testObjects); 3196 3197 const VkPushConstantRange& verifyPushConstantRange = 3198 { 3199 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 3200 0, // uint32_t offset; 3201 static_cast<deUint32>(sizeof(UVec4) + sizeof(deUint32)), // uint32_t size; 3202 }; 3203 3204 Move<VkPipelineLayout> verifyPipelineLayout; 3205 setupVerifyDescriptorSetAndPipeline(context, params, wd, testObjects, &verifyPushConstantRange, verifyPipelineLayout); 3206 3207 const deUint32 stencilExpect[2] = 3208 { 3209 // For region 0, there's a single draw that increments the cleared stencil 3210 params.clearValues[3].depthStencil.stencil + 1, 3211 // For region 1, there's a vkCmdClearAttachments followed by a draw that increments that stencil value 3212 clearValues[0][3].depthStencil.stencil + 1, 3213 }; 3214 3215 // Verify regions 0 and 1 have gradient colors. 3216 for (deUint32 regionNdx = 0; regionNdx < 2; ++regionNdx) 3217 { 3218 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 3219 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, sizeof(UVec4), sizeof(deUint32), &stencilExpect[regionNdx]); 3220 vk.cmdDispatch(*testObjects.cmdBuffer, (regions[regionNdx].z() + 7) / 8, (regions[regionNdx].w() + 7) / 8, 1); 3221 3222 postVerifyBarrier(context, testObjects, wd.verificationBuffer); 3223 } 3224 3225 // Verify the rest of the regions have clear values. Note that clearValues[0] is unused as it's overriden with a draw call to region 1. 3226 for (deUint32 regionNdx = 2; regionNdx < RegionCount; ++regionNdx) 3227 { 3228 const VkClearValue* regionClearValues = clearValues[regionNdx - 1]; 3229 const UVec4& region = regions[regionNdx]; 3230 3231 { 3232 const VerifySingleFloatPushConstants verifyColor1 = 3233 { 3234 region, 3235 Vec4(regionClearValues[0].color.float32[0], regionClearValues[0].color.float32[1], regionClearValues[0].color.float32[2], regionClearValues[0].color.float32[3]), 3236 0, 3237 }; 3238 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedFloatColorImage1View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.verificationBuffer, 3239 static_cast<deUint32>(sizeof(verifyColor1)), &verifyColor1, "comp_singleFloat"); 3240 } 3241 3242 { 3243 const VerifySingleFloatPushConstants verifyColor2 = 3244 { 3245 region, 3246 Vec4(regionClearValues[1].color.float32[0], regionClearValues[1].color.float32[1], regionClearValues[1].color.float32[2], regionClearValues[1].color.float32[3]), 3247 1, 3248 }; 3249 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedFloatColorImage2View(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.verificationBuffer, 3250 static_cast<deUint32>(sizeof(verifyColor2)), &verifyColor2, "comp_singleFloat"); 3251 } 3252 3253 { 3254 const VerifySingleIntPushConstants verifyColor3 = 3255 { 3256 region, 3257 IVec4(regionClearValues[2].color.int32[0], regionClearValues[2].color.int32[1], regionClearValues[2].color.int32[2], regionClearValues[2].color.int32[3]), 3258 2, 3259 }; 3260 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedIntColorImageView(params), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, wd.verify.view, wd.verificationBuffer, 3261 static_cast<deUint32>(sizeof(verifyColor3)), &verifyColor3, "comp_singleInt"); 3262 } 3263 3264 if (isDepthFormat(params.depthStencilFormat)) 3265 { 3266 const VerifySingleDepthPushConstants verifyDepth = 3267 { 3268 region, 3269 regionClearValues[3].depthStencil.depth, 3270 }; 3271 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedDepthOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, wd.verify.view, wd.verificationBuffer, 3272 static_cast<deUint32>(sizeof(verifyDepth)), &verifyDepth, "comp_singleDepth"); 3273 } 3274 3275 if (isStencilFormat(params.depthStencilFormat)) 3276 { 3277 const VerifySingleStencilPushConstants verifyStencil = 3278 { 3279 region, 3280 regionClearValues[3].depthStencil.stencil, 3281 }; 3282 dispatchVerifyConstantColor(context, testObjects, wd.getResolvedStencilOnlyImageView(params), VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, wd.verify.view, wd.verificationBuffer, 3283 static_cast<deUint32>(sizeof(verifyStencil)), &verifyStencil, "comp_singleStencil"); 3284 } 3285 } 3286 3287 invalidateAlloc(vk, device, *wd.verificationBufferAlloc); 3288} 3289 3290void drawClearAttachments (Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 3291{ 3292 const InstanceInterface& vki = context.getInstanceInterface(); 3293 const DeviceInterface& vk = context.getDeviceInterface(); 3294 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 3295 const VkDevice device = context.getDevice(); 3296 VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo; 3297 std::vector<VkFormat> colorAttachmentFormats = { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }; 3298 std::vector<VkRenderingAttachmentInfo> colorAttachmentInfos(4u); 3299 VkRenderingAttachmentInfo depthStencilAttachmentInfo; 3300 3301 DE_ASSERT(params.perPass.size() == 1); 3302 3303 if (params.clearBeforeRenderPass) 3304 { 3305 clearImagesBeforeDraw(context, params, wd, testObjects); 3306 } 3307 3308 if (params.dynamicRendering) 3309 { 3310 preRenderingImageLayoutTransition(context, params, wd, testObjects); 3311 initResolveImageLayouts(context, params, wd, testObjects); 3312 } 3313 3314 // Create a render pass and a framebuffer 3315 { 3316 std::vector<VkSubpassDescription2> subpasses; 3317 std::vector<VkImage> images; 3318 std::vector<VkImageView> attachments; 3319 std::vector<VkAttachmentDescription2> attachmentDescriptions; 3320 std::vector<VkAttachmentReference2> attachmentReferences; 3321 std::vector<VkAttachmentReference2> resolveAttachmentReferences; 3322 VkMultisampledRenderToSingleSampledInfoEXT msrtss; 3323 VkSubpassDescriptionDepthStencilResolve depthStencilResolve; 3324 deInt32 attachmentNdxes[8] = {-1, -1, -1, -1, 3325 -1, -1, -1, -1}; 3326 deUint32 attachmentUseMask = 0; 3327 3328 initializeAttachments(params, wd, images, attachments, 0, attachmentNdxes); 3329 3330 if (params.dynamicRendering) 3331 { 3332 initializeRenderingAttachmentInfos(params, 3333 wd, 3334 colorAttachmentInfos, 3335 depthStencilAttachmentInfo, 3336 colorAttachmentFormats, 3337 attachmentNdxes, 3338 attachmentUseMask, 3339 0u); 3340 3341 pipelineRenderingCreateInfo = { 3342 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType 3343 DE_NULL, // const void* pNext 3344 0u, // uint32_t viewMask 3345 static_cast<uint32_t>(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount 3346 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats 3347 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat 3348 VK_FORMAT_UNDEFINED // VkFormat stencilAttachmentFormat 3349 }; 3350 3351 if (params.usesDepthStencilInPass(0)) 3352 { 3353 if (isDepthFormat(params.depthStencilFormat)) 3354 pipelineRenderingCreateInfo.depthAttachmentFormat = params.depthStencilFormat; 3355 if (isStencilFormat(params.depthStencilFormat)) 3356 pipelineRenderingCreateInfo.stencilAttachmentFormat = params.depthStencilFormat; 3357 } 3358 } 3359 else 3360 { 3361 initializeAttachmentDescriptions(params, attachmentDescriptions, params.clearBeforeRenderPass, attachmentNdxes, attachmentUseMask); 3362 3363 addSubpassDescription(params, 3364 0, 3365 attachmentReferences, 3366 resolveAttachmentReferences, 3367 depthStencilResolve, 3368 nullptr, 3369 msrtss, 3370 subpasses, 3371 {}, 3372 attachmentNdxes); 3373 3374 createRenderPassAndFramebuffer(context, wd, testObjects, params.pipelineConstructionType, images, attachments, attachmentDescriptions, subpasses, {}); 3375 } 3376 } 3377 3378 UVec4 regions[RegionCount]; 3379 getDrawRegions(wd, regions); 3380 3381 VkClearValue clearValues[RegionCount - 1][4]; 3382 de::Random rng(params.rngSeed); 3383 for (deUint32 regionNdx = 0; regionNdx < RegionCount - 1; ++regionNdx) 3384 generateRandomClearValues(rng, params, clearValues[regionNdx], false); 3385 3386 { 3387 const VkPushConstantRange& pushConstantRange = 3388 { 3389 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 3390 0, // uint32_t offset; 3391 static_cast<deUint32>(sizeof(UVec4)), // uint32_t size; 3392 }; 3393 3394 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 3395 const ShaderWrapper fragmentModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag"), 0u)); 3396 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, 0, DE_NULL, 1, &pushConstantRange); 3397 3398 if (params.dynamicRendering) 3399 { 3400 startRendering(context, params, wd, testObjects, static_cast<uint32_t>(colorAttachmentFormats.size()), colorAttachmentInfos, depthStencilAttachmentInfo, 0u); 3401 } 3402 else 3403 { 3404 startRenderPass(context, wd, testObjects, DE_LENGTH_OF_ARRAY(params.clearValues), params.clearValues); 3405 } 3406 3407 // Draw to region[0] 3408 testObjects.graphicsPipelines.push_back( 3409 pipeline::makeGraphicsPipeline(vki, 3410 vk, 3411 physicalDevice, 3412 device, 3413 context.getDeviceExtensions(), 3414 params.pipelineConstructionType, 3415 pipelineLayout, 3416 params.dynamicRendering ? DE_NULL : *testObjects.renderPassFramebuffers.back(), 3417 params.dynamicRendering ? &pipelineRenderingCreateInfo : DE_NULL, 3418 vertexModule, 3419 fragmentModule, 3420 false, 3421 true, 3422 false, 3423 0, 3424 0, 3425 params.perPass[0].intColorLocation, 3426 regions[0], 3427 regions[0], 3428 params.perPass[0].numSamples, 3429 params.useGarbageAttachment)); 3430 3431 const VkDeviceSize vertexBufferOffset = 0; 3432 vk.cmdBindVertexBuffers(*testObjects.cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 3433 3434 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[0]); 3435 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 3436 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 3437 3438 // Clear all regions except region 0 3439 { 3440 for (deUint32 regionNdx = 0; regionNdx < RegionCount - 1; ++regionNdx) 3441 { 3442 const VkClearAttachment attachments[4] = { 3443 { VK_IMAGE_ASPECT_COLOR_BIT, static_cast<deUint32>(params.perPass[0].floatColor1Location), clearValues[regionNdx][0], }, 3444 { VK_IMAGE_ASPECT_COLOR_BIT, static_cast<deUint32>(params.perPass[0].floatColor2Location), clearValues[regionNdx][1], }, 3445 { VK_IMAGE_ASPECT_COLOR_BIT, static_cast<deUint32>(params.perPass[0].intColorLocation), clearValues[regionNdx][2], }, 3446 { getDepthStencilAspectFlags(params.depthStencilFormat), 0, clearValues[regionNdx][3], }, 3447 }; 3448 const UVec4& region = regions[regionNdx + 1]; 3449 const VkClearRect clearRegions = 3450 { 3451 { 3452 {static_cast<deInt32>(region.x()), static_cast<deInt32>(region.y())}, 3453 {region.z(), region.w()} 3454 }, 0, 1 3455 }; 3456 3457 vk.cmdClearAttachments(*testObjects.cmdBuffer, 4, attachments, 1, &clearRegions); 3458 } 3459 } 3460 3461 // Draw to region[1], overriding the clear value 3462 testObjects.graphicsPipelines.push_back( 3463 makeGraphicsPipeline(vki, 3464 vk, 3465 physicalDevice, 3466 device, 3467 context.getDeviceExtensions(), 3468 params.pipelineConstructionType, 3469 pipelineLayout, 3470 params.dynamicRendering ? DE_NULL : *testObjects.renderPassFramebuffers.back(), 3471 params.dynamicRendering ? &pipelineRenderingCreateInfo : DE_NULL, 3472 vertexModule, 3473 fragmentModule, 3474 false, 3475 true, 3476 false, 3477 0, 3478 0, 3479 params.perPass[0].intColorLocation, 3480 regions[1], 3481 regions[1], 3482 params.perPass[0].numSamples, 3483 params.useGarbageAttachment)); 3484 3485 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[1]); 3486 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 3487 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 3488 3489 if (params.dynamicRendering) 3490 { 3491 vk.cmdEndRendering(*testObjects.cmdBuffer); 3492 } 3493 else 3494 { 3495 testObjects.renderPassFramebuffers.back().end(vk, *testObjects.cmdBuffer); 3496 } 3497 } 3498 3499 if (params.dynamicRendering) 3500 { 3501 postRenderingResolveImageLayoutTransition(context, params, wd, testObjects); 3502 } 3503 3504 // Verify results 3505 dispatchVerifyClearAttachments(context, params, wd, testObjects, regions, clearValues); 3506} 3507 3508//! Verify vkCmdClearAttachments works. 3509tcu::TestStatus testClearAttachments (Context& context, const TestParams params) 3510{ 3511 WorkingData wd; 3512 TestObjects testObjects(context); 3513 testStart(context, params, wd, testObjects); 3514 3515 drawClearAttachments (context, params, wd, testObjects); 3516 3517 testEnd(context, params, wd, testObjects); 3518 return verify(context, params, wd); 3519} 3520 3521void drawOnePass(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects, 3522 const ShaderWrapper& vertexModule, const PipelineLayoutWrapper& pipelineLayout, const deUint32 passNdx, 3523 const deUint32 subpassNdx, UVec4 regions[RegionCount], VkPipelineRenderingCreateInfo* pipelineRenderingCreateInfo) 3524{ 3525 const InstanceInterface& vki = context.getInstanceInterface(); 3526 const DeviceInterface& vk = context.getDeviceInterface(); 3527 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 3528 const VkDevice device = context.getDevice(); 3529 3530 const VkDeviceSize vertexBufferOffset = 0; 3531 vk.cmdBindVertexBuffers(*testObjects.cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 3532 3533 const TestParams::PerPass& perPass = params.perPass[passNdx]; 3534 3535 // Each subpass performs 4 sets of one or two draw calls. Two if there is depth/stencil and one if not. 3536 // When depth/stencil is present, the first draw call writes to depth, while the second draw call does a depth test. 3537 // The four sets are draw calls with scissors dividing the render area in four: 3538 // 3539 // +--------+---------------+ 3540 // | | | 3541 // | 1 | 2 | 3542 // | | | 3543 // +--------+---------------+ 3544 // | | | 3545 // | | | 3546 // | 3 | 4 | 3547 // | | | 3548 // | | | 3549 // +--------+---------------+ 3550 // 3551 3552 std::ostringstream fragName; 3553 fragName << "frag_" << passNdx; 3554 const ShaderWrapper fragmentModule (ShaderWrapper(vk, device, context.getBinaryCollection().get(fragName.str().c_str()), 0u)); 3555 3556 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 3557 { 3558 testObjects.graphicsPipelines.push_back( 3559 pipeline::makeGraphicsPipeline(vki, 3560 vk, 3561 physicalDevice, 3562 device, 3563 context.getDeviceExtensions(), 3564 params.pipelineConstructionType, 3565 pipelineLayout, 3566 params.dynamicRendering ? DE_NULL : *testObjects.renderPassFramebuffers.back(), 3567 params.dynamicRendering ? pipelineRenderingCreateInfo : DE_NULL, 3568 vertexModule, 3569 fragmentModule, 3570 true, 3571 true, 3572 false, 3573 1 << passNdx, 3574 subpassNdx, 3575 perPass.intColorLocation, 3576 regions[regionNdx], 3577 regions[regionNdx], 3578 perPass.numSamples, 3579 params.useGarbageAttachment)); 3580 3581 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 3582 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(UVec4), sizeof(perPass.drawConstantsWithDepthWrite[regionNdx]), &perPass.drawConstantsWithDepthWrite[regionNdx]); 3583 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 3584 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 3585 3586 if (perPass.hasDepthStencil) 3587 { 3588 testObjects.graphicsPipelines.push_back( 3589 pipeline::makeGraphicsPipeline(vki, 3590 vk, 3591 physicalDevice, 3592 device, 3593 context.getDeviceExtensions(), 3594 params.pipelineConstructionType, 3595 pipelineLayout, 3596 params.dynamicRendering ? DE_NULL : *testObjects.renderPassFramebuffers.back(), 3597 params.dynamicRendering ? pipelineRenderingCreateInfo : DE_NULL, 3598 vertexModule, 3599 fragmentModule, 3600 true, 3601 false, 3602 true, 3603 1 << passNdx, 3604 subpassNdx, 3605 perPass.intColorLocation, 3606 regions[regionNdx], 3607 regions[regionNdx], 3608 perPass.numSamples, 3609 params.useGarbageAttachment)); 3610 3611 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 3612 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(UVec4), sizeof(perPass.drawConstantsWithDepthTest[regionNdx]), &perPass.drawConstantsWithDepthTest[regionNdx]); 3613 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 3614 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 3615 } 3616 } 3617} 3618 3619void dispatchVerifyMultiPassRendering(Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects, UVec4 regions[RegionCount]) 3620{ 3621 const DeviceInterface& vk = context.getDeviceInterface(); 3622 const VkDevice device = context.getDevice(); 3623 3624 postDrawBarrier(context, testObjects); 3625 3626 const VkPushConstantRange& verifyPushConstantRange = 3627 { 3628 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 3629 0, // uint32_t offset; 3630 static_cast<deUint32>(sizeof(UVec4) + sizeof(VerifyPushConstants)), // uint32_t size; 3631 }; 3632 3633 Move<VkPipelineLayout> verifyPipelineLayout; 3634 setupVerifyDescriptorSetAndPipeline(context, params, wd, testObjects, &verifyPushConstantRange, verifyPipelineLayout); 3635 3636 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 3637 { 3638 if (regionNdx != 0) 3639 { 3640 const VkMemoryBarrier preVerifyBarrier = 3641 { 3642 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 3643 DE_NULL, // const void* pNext; 3644 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 3645 VK_ACCESS_SHADER_WRITE_BIT | 3646 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 3647 }; 3648 3649 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 3650 1u, &preVerifyBarrier, 0u, DE_NULL, 0u, DE_NULL); 3651 } 3652 3653 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 3654 vk.cmdPushConstants(*testObjects.cmdBuffer, *verifyPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, sizeof(UVec4), sizeof(params.verifyConstants[regionNdx]), ¶ms.verifyConstants[regionNdx]); 3655 vk.cmdDispatch(*testObjects.cmdBuffer, (regions[regionNdx].z() + 7) / 8, (regions[regionNdx].w() + 7) / 8, 1); 3656 } 3657 3658 postVerifyBarrier(context, testObjects, wd.verificationBuffer); 3659 3660 invalidateAlloc(vk, device, *wd.verificationBufferAlloc); 3661} 3662 3663void drawSingleRenderPass (Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 3664{ 3665 const DeviceInterface& vk = context.getDeviceInterface(); 3666 const VkDevice device = context.getDevice(); 3667 const deUint32 numSubpasses = static_cast<deUint32>(params.perPass.size()); 3668 3669 if (params.clearBeforeRenderPass) 3670 { 3671 clearImagesBeforeDraw(context, params, wd, testObjects); 3672 } 3673 3674 // Create a render pass and a framebuffer 3675 { 3676 std::vector<VkSubpassDescription2> subpasses; 3677 std::vector<VkImage> images; 3678 std::vector<VkImageView> attachments; 3679 std::vector<VkAttachmentDescription2> attachmentDescriptions; 3680 std::vector<std::vector<VkAttachmentReference2>> attachmentReferences(numSubpasses); 3681 std::vector<std::vector<VkAttachmentReference2>> resolveAttachmentReferences(numSubpasses); 3682 std::vector<std::vector<deUint32>> preserveAttachments(numSubpasses); 3683 std::vector<VkSubpassDependency2> subpassDependencies; 3684 std::vector<VkMultisampledRenderToSingleSampledInfoEXT> msrtss(numSubpasses); 3685 std::vector<VkSubpassDescriptionDepthStencilResolve> depthStencilResolve(numSubpasses); 3686 deInt32 attachmentNdxes[8] = {-1, -1, -1, -1, 3687 -1, -1, -1, -1}; 3688 deUint32 attachmentUseMask = 0; 3689 3690 initializeAttachments(params, wd, images, attachments, params.perPass.size(), attachmentNdxes); 3691 initializeAttachmentDescriptions(params, attachmentDescriptions, params.clearBeforeRenderPass, attachmentNdxes, attachmentUseMask); 3692 3693 for (deUint32 passNdx = 0; passNdx < numSubpasses; ++passNdx) 3694 { 3695 addSubpassDescription(params, 3696 passNdx, 3697 attachmentReferences[passNdx], 3698 resolveAttachmentReferences[passNdx], 3699 depthStencilResolve[passNdx], 3700 &preserveAttachments[passNdx], 3701 msrtss[passNdx], 3702 subpasses, 3703 {}, 3704 attachmentNdxes); 3705 3706 if (passNdx > 0) 3707 addSubpassDependency(passNdx, subpassDependencies); 3708 } 3709 3710 createRenderPassAndFramebuffer(context, wd, testObjects, params.pipelineConstructionType, images, attachments, attachmentDescriptions, subpasses, subpassDependencies); 3711 } 3712 3713 const VkPushConstantRange& pushConstantRange = 3714 { 3715 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 3716 0, // uint32_t offset; 3717 static_cast<deUint32>(sizeof(UVec4) + sizeof(DrawPushConstants)), // uint32_t size; 3718 }; 3719 3720 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 3721 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, 0, DE_NULL, 1, &pushConstantRange); 3722 3723 UVec4 regions[RegionCount]; 3724 getDrawRegions(wd, regions); 3725 3726 startRenderPass(context, wd, testObjects, DE_LENGTH_OF_ARRAY(params.clearValues), params.clearValues); 3727 3728 for (deUint32 passNdx = 0; passNdx < numSubpasses; ++passNdx) 3729 { 3730 if (passNdx != 0) 3731 testObjects.renderPassFramebuffers.back().nextSubpass(vk, *testObjects.cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 3732 3733 drawOnePass(context, params, wd, testObjects, vertexModule, pipelineLayout, passNdx, passNdx, regions, DE_NULL); 3734 } 3735 3736 testObjects.renderPassFramebuffers.back().end(vk, *testObjects.cmdBuffer); 3737 3738 // Verify results 3739 dispatchVerifyMultiPassRendering(context, params, wd, testObjects, regions); 3740} 3741 3742//! Verify multisampled rendering in subpasses 3743tcu::TestStatus testSingleRenderPass (Context& context, const TestParams params) 3744{ 3745 WorkingData wd; 3746 TestObjects testObjects(context); 3747 testStart(context, params, wd, testObjects); 3748 3749 drawSingleRenderPass (context, params, wd, testObjects); 3750 3751 testEnd(context, params, wd, testObjects); 3752 return verify(context, params, wd); 3753} 3754 3755void drawMultiRenderPass (Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 3756{ 3757 const DeviceInterface& vk = context.getDeviceInterface(); 3758 const VkDevice device = context.getDevice(); 3759 const deUint32 numRenderPasses = static_cast<deUint32>(params.perPass.size()); 3760 3761 if (params.clearBeforeRenderPass) 3762 { 3763 clearImagesBeforeDraw(context, params, wd, testObjects); 3764 } 3765 3766 if (params.dynamicRendering) 3767 { 3768 preRenderingImageLayoutTransition(context, params, wd, testObjects); 3769 initResolveImageLayouts(context, params, wd, testObjects); 3770 } 3771 3772 const VkPushConstantRange& pushConstantRange = 3773 { 3774 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 3775 0, // uint32_t offset; 3776 static_cast<deUint32>(sizeof(UVec4) + sizeof(DrawPushConstants)), // uint32_t size; 3777 }; 3778 3779 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 3780 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, 0, DE_NULL, 1, &pushConstantRange); 3781 3782 UVec4 regions[RegionCount]; 3783 getDrawRegions(wd, regions); 3784 3785 deUint32 attachmentUseMask = 0; 3786 3787 for (deUint32 renderPassNdx = 0; renderPassNdx < numRenderPasses; ++renderPassNdx) 3788 { 3789 // Create a render pass and a framebuffer 3790 std::vector<VkSubpassDescription2> subpasses; 3791 std::vector<VkImage> images; 3792 std::vector<VkImageView> attachments; 3793 std::vector<VkAttachmentDescription2> attachmentDescriptions; 3794 std::vector<VkAttachmentReference2> attachmentReferences; 3795 std::vector<VkAttachmentReference2> resolveAttachmentReferences; 3796 VkMultisampledRenderToSingleSampledInfoEXT msrtss; 3797 VkSubpassDescriptionDepthStencilResolve depthStencilResolve; 3798 deInt32 attachmentNdxes[8] = {-1, -1, -1, -1, 3799 -1, -1, -1, -1}; 3800 VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo; 3801 std::vector<VkFormat> colorAttachmentFormats = { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }; 3802 std::vector<VkRenderingAttachmentInfo> colorAttachmentInfos(4u); 3803 VkRenderingAttachmentInfo depthStencilAttachmentInfo; 3804 3805 std::vector<VkClearValue> clearValues; 3806 3807 initializeAttachments(params, wd, images, attachments, renderPassNdx, attachmentNdxes); 3808 if (params.dynamicRendering) 3809 { 3810 initializeRenderingAttachmentInfos(params, 3811 wd, 3812 colorAttachmentInfos, 3813 depthStencilAttachmentInfo, 3814 colorAttachmentFormats, 3815 attachmentNdxes, 3816 attachmentUseMask, 3817 renderPassNdx); 3818 3819 pipelineRenderingCreateInfo = { 3820 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType 3821 DE_NULL, // const void* pNext 3822 0u, // uint32_t viewMask 3823 static_cast<uint32_t>(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount 3824 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats 3825 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat 3826 VK_FORMAT_UNDEFINED // VkFormat stencilAttachmentFormat 3827 }; 3828 3829 if (params.usesDepthStencilInPass(renderPassNdx)) 3830 { 3831 if (isDepthFormat(params.depthStencilFormat)) 3832 pipelineRenderingCreateInfo.depthAttachmentFormat = params.depthStencilFormat; 3833 if (isStencilFormat(params.depthStencilFormat)) 3834 pipelineRenderingCreateInfo.stencilAttachmentFormat = params.depthStencilFormat; 3835 } 3836 } 3837 else 3838 { 3839 initializeAttachmentDescriptions(params, attachmentDescriptions, params.clearBeforeRenderPass, attachmentNdxes, attachmentUseMask); 3840 3841 addSubpassDescription(params, 3842 renderPassNdx, 3843 attachmentReferences, 3844 resolveAttachmentReferences, 3845 depthStencilResolve, 3846 nullptr, 3847 msrtss, 3848 subpasses, 3849 {}, 3850 attachmentNdxes); 3851 3852 createRenderPassAndFramebuffer(context, wd, testObjects, params.pipelineConstructionType, images, attachments, attachmentDescriptions, subpasses, {}); 3853 3854 // Init clear values 3855 if (attachmentNdxes[0] >= 0) 3856 clearValues.push_back(params.clearValues[0]); 3857 if (attachmentNdxes[1] >= 0) 3858 clearValues.push_back(params.clearValues[1]); 3859 if (attachmentNdxes[2] >= 0) 3860 clearValues.push_back(params.clearValues[2]); 3861 if (attachmentNdxes[3] >= 0) 3862 clearValues.push_back(params.clearValues[3]); 3863 } 3864 3865 if (renderPassNdx > 0) 3866 { 3867 const VkMemoryBarrier interRenderPassBarrier = 3868 { 3869 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 3870 DE_NULL, // const void* pNext; 3871 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 3872 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 3873 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 3874 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 3875 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 3876 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 3877 }; 3878 3879 vk.cmdPipelineBarrier(*testObjects.cmdBuffer, 3880 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 3881 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 3882 0u, 1u, &interRenderPassBarrier, 0u, DE_NULL, 0u, DE_NULL); 3883 } 3884 3885 if (params.dynamicRendering) 3886 { 3887 startRendering(context, params, wd, testObjects, static_cast<uint32_t>(colorAttachmentFormats.size()), colorAttachmentInfos, depthStencilAttachmentInfo, renderPassNdx); 3888 } 3889 else 3890 { 3891 startRenderPass(context, wd, testObjects, static_cast<deUint32>(clearValues.size()), dataOrNullPtr(clearValues)); 3892 } 3893 3894 drawOnePass(context, params, wd, testObjects, vertexModule, pipelineLayout, renderPassNdx, 0, regions, &pipelineRenderingCreateInfo); 3895 3896 if (params.dynamicRendering) 3897 { 3898 vk.cmdEndRendering(*testObjects.cmdBuffer); 3899 } 3900 else 3901 { 3902 testObjects.renderPassFramebuffers.back().end(vk, *testObjects.cmdBuffer); 3903 } 3904 } 3905 3906 if (params.dynamicRendering) 3907 { 3908 postRenderingResolveImageLayoutTransition(context, params, wd, testObjects); 3909 } 3910 3911 // Verify results 3912 dispatchVerifyMultiPassRendering(context, params, wd, testObjects, regions); 3913} 3914 3915//! Verify multisampled rendering in multiple render passes 3916tcu::TestStatus testMultiRenderPass (Context& context, const TestParams params) 3917{ 3918 WorkingData wd; 3919 TestObjects testObjects(context); 3920 testStart(context, params, wd, testObjects); 3921 3922 drawMultiRenderPass (context, params, wd, testObjects); 3923 3924 testEnd(context, params, wd, testObjects); 3925 return verify(context, params, wd); 3926} 3927 3928void generateMultiPassTest (de::Random& rng, TestParams& params) 3929{ 3930 const VkSampleCountFlagBits sampleRange[] = 3931 { 3932 // 4x multisampling is always supported. A higher chance is given to that to avoid too many tests being skipped. 3933 VK_SAMPLE_COUNT_2_BIT, 3934 VK_SAMPLE_COUNT_4_BIT, 3935 VK_SAMPLE_COUNT_4_BIT, 3936 VK_SAMPLE_COUNT_4_BIT, 3937 VK_SAMPLE_COUNT_8_BIT, 3938 VK_SAMPLE_COUNT_16_BIT, 3939 }; 3940 3941 const VkResolveModeFlagBits depthStencilResolveModeRange[] = 3942 { 3943 // SAMPLE_ZERO is always supported, while MAX may not be. A higher chance is given to SAMPLE_ZERO to avoid too many tests being skipped. 3944 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 3945 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 3946 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 3947 VK_RESOLVE_MODE_MAX_BIT, 3948 }; 3949 3950 // Generate a random number of passes (either subpass or render pass) 3951 const deUint32 passCount = rng.getInt(1, 4); 3952 3953 params.perPass.resize(passCount); 3954 3955 std::vector<deUint32> passAttachments; 3956 3957 deUint32 usedAttachmentMask = 0; 3958 if (params.isMultisampledRenderToSingleSampled) 3959 { 3960 // Decide which attachments will be used in which pass. This is a bit mask. 3961 for (deUint32 passNdx = 0; passNdx < passCount; ++passNdx) 3962 { 3963 passAttachments.push_back(rng.getInt(1, 15)); 3964 usedAttachmentMask |= passAttachments.back(); 3965 } 3966 } 3967 else 3968 { 3969 passAttachments.push_back(15); // Make sure all attachments have the same sample count 3970 for (deUint32 passNdx = 1; passNdx < passCount; ++passNdx) 3971 passAttachments.push_back(rng.getInt(1, 15)); 3972 } 3973 3974 // Decide which attachments will be single-sampled. This is a bit mask. 3975 // Include any attachment that is not used in any subpass just to make all attachments valid. 3976 const deUint32 singleSampledAttachmentsMask = params.isMultisampledRenderToSingleSampled ? rng.getInt(1, 15) | (~usedAttachmentMask & 0xF) : 0; 3977 3978 DBG("Generating test for %u passes\n", passCount); 3979 3980 // Set the sample count for attachments. Multisampled attachments that are used in the same pass will get the same number of samples. 3981 if ((singleSampledAttachmentsMask & 1) != 0) 3982 params.numFloatColor1Samples = VK_SAMPLE_COUNT_1_BIT; 3983 if ((singleSampledAttachmentsMask & 2) != 0) 3984 params.numFloatColor2Samples = VK_SAMPLE_COUNT_1_BIT; 3985 if ((singleSampledAttachmentsMask & 4) != 0) 3986 params.numIntColorSamples = VK_SAMPLE_COUNT_1_BIT; 3987 if ((singleSampledAttachmentsMask & 8) != 0) 3988 params.numDepthStencilSamples = VK_SAMPLE_COUNT_1_BIT; 3989 3990 for (deUint32 passNdx = 0; passNdx < passCount; ++passNdx) 3991 { 3992 TestParams::PerPass& perPass = params.perPass[passNdx]; 3993 3994 const deUint32 multisampledAttachments = passAttachments[passNdx] & ~singleSampledAttachmentsMask; 3995 const VkSampleCountFlagBits randomSampleCount = sampleRange[rng.getInt(0, DE_LENGTH_OF_ARRAY(sampleRange) - 1)]; 3996 DBG(" + random samples: %d, multisampled attachments: %#x\n", randomSampleCount, multisampledAttachments); 3997 3998 if (multisampledAttachments == 0) 3999 { 4000 // If all attachments are single-sampled, choose a random number of samples for the render pass. 4001 perPass.numSamples = randomSampleCount; 4002 } 4003 else 4004 { 4005 // Otherwise see if any of the attachments has already been decided what number of samples it has. 4006 VkSampleCountFlagBits sampleCount = (multisampledAttachments & 1) != 0 && params.numFloatColor1Samples != 0 ? params.numFloatColor1Samples 4007 : (multisampledAttachments & 2) != 0 && params.numFloatColor2Samples != 0 ? params.numFloatColor2Samples 4008 : (multisampledAttachments & 4) != 0 && params.numIntColorSamples != 0 ? params.numIntColorSamples 4009 : (multisampledAttachments & 8) != 0 && params.numDepthStencilSamples != 0 ? params.numDepthStencilSamples 4010 // If none of the attachments already have a defined sample, generate a random sample count to use for all of them. 4011 : randomSampleCount; 4012 DBG(" + sample count from attachments or random: %d (already: %d %d %d %d)\n", sampleCount, 4013 params.numFloatColor1Samples, params.numFloatColor2Samples, params.numIntColorSamples, params.numDepthStencilSamples); 4014 4015 perPass.numSamples = sampleCount; 4016 4017 // Make all multisampled attachments used in the pass have the same number of samples. Additionally, make all the multisampled attachments 4018 // used in conjunction with the these ones in future passes also have the same number of samples. 4019 for (deUint32 followingPassNdx = passNdx; followingPassNdx < passCount; ++followingPassNdx) 4020 { 4021 const deUint32 followingMultisampledAttachments = passAttachments[followingPassNdx] & ~singleSampledAttachmentsMask; 4022 4023 if ((followingMultisampledAttachments & 1) != 0) 4024 params.numFloatColor1Samples = sampleCount; 4025 if ((followingMultisampledAttachments & 2) != 0) 4026 params.numFloatColor2Samples = sampleCount; 4027 if ((followingMultisampledAttachments & 4) != 0) 4028 params.numIntColorSamples = sampleCount; 4029 if ((followingMultisampledAttachments & 8) != 0) 4030 params.numDepthStencilSamples = sampleCount; 4031 } 4032 } 4033 4034 // Generate random locations for the color attachments. 4035 deInt32 locations[] = {0, 1, 2, 3}; 4036 for (int i = 0; i < 3; ++i) 4037 { 4038 int j = rng.getInt(i, 3); 4039 std::swap(locations[i], locations[j]); 4040 } 4041 size_t nextLocation = 0; 4042 perPass.floatColor1Location = (passAttachments[passNdx] & 1) != 0 ? locations[nextLocation++] : -1; 4043 perPass.floatColor2Location = (passAttachments[passNdx] & 2) != 0 ? locations[nextLocation++] : -1; 4044 perPass.intColorLocation = (passAttachments[passNdx] & 4) != 0 ? locations[nextLocation++] : -1; 4045 4046 // Specify if depth/stencil is used 4047 perPass.hasDepthStencil = (passAttachments[passNdx] & 8) != 0; 4048 4049 perPass.resolveFloatColor1 = false; 4050 perPass.resolveFloatColor2 = false; 4051 perPass.resolveIntColor = false; 4052 perPass.resolveDepthStencil = false; 4053 perPass.depthStencilResolveMode = VK_RESOLVE_MODE_NONE; 4054 4055 DBG(" - %u samples, locations: %d %d %d has D/S? %d\n", perPass.numSamples, 4056 perPass.floatColor1Location, perPass.floatColor2Location, perPass.intColorLocation, perPass.hasDepthStencil); 4057 } 4058 4059 DBG(" Sample counts: %u %u %u %u\n", params.numFloatColor1Samples, params.numFloatColor2Samples, params.numIntColorSamples, params.numDepthStencilSamples); 4060 4061 // Assert that generated passes are valid 4062 for (deUint32 passNdx = 0; passNdx < passCount; ++passNdx) 4063 { 4064 const VkSampleCountFlagBits sampleCounts[4] = {params.numFloatColor1Samples, params.numFloatColor2Samples, params.numIntColorSamples, params.numDepthStencilSamples}; 4065 VkSampleCountFlagBits subpassSampleCount = VK_SAMPLE_COUNT_1_BIT; 4066 4067 for (deUint32 attachmentNdx = 0; attachmentNdx < 4; ++attachmentNdx) 4068 { 4069 if ((passAttachments[passNdx] & (1 << attachmentNdx)) == 0) 4070 continue; 4071 4072 const VkSampleCountFlagBits attachmentSampleCount = sampleCounts[attachmentNdx] == VK_SAMPLE_COUNT_1_BIT 4073 ? params.perPass[passNdx].numSamples 4074 : sampleCounts[attachmentNdx]; 4075 4076 if (subpassSampleCount == VK_SAMPLE_COUNT_1_BIT) 4077 subpassSampleCount = attachmentSampleCount; 4078 4079 DE_ASSERT(subpassSampleCount == attachmentSampleCount); 4080 } 4081 } 4082 4083 // Determine when multisampled attachments should resolve. 4084 deUint32 resolvedAttachmentsMask = singleSampledAttachmentsMask; 4085 for (deUint32 passNdx = passCount; passNdx > 0; --passNdx) 4086 { 4087 TestParams::PerPass& perPass = params.perPass[passNdx - 1]; 4088 const deUint32 unresolvedAttachments = passAttachments[passNdx - 1] & ~resolvedAttachmentsMask; 4089 4090 // Make every multisampled attachment resolve in the last pass it's used. 4091 if ((unresolvedAttachments & 1) != 0) 4092 perPass.resolveFloatColor1 = true; 4093 if ((unresolvedAttachments & 2) != 0) 4094 perPass.resolveFloatColor2 = true; 4095 if ((unresolvedAttachments & 4) != 0) 4096 perPass.resolveIntColor = true; 4097 if ((unresolvedAttachments & 8) != 0) 4098 perPass.resolveDepthStencil = true; 4099 4100 if (perPass.resolveDepthStencil || params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT) 4101 perPass.depthStencilResolveMode = depthStencilResolveModeRange[rng.getInt(0, DE_LENGTH_OF_ARRAY(depthStencilResolveModeRange) - 1)]; 4102 4103 resolvedAttachmentsMask |= unresolvedAttachments; 4104 4105 DBG(" - Resolved 0x%x in pass %u\n", unresolvedAttachments, passNdx - 1); 4106 } 4107 4108 // Decide whether clear should be done as part of the render pass. Tests loadOp=CLEAR vs loadOp=LOAD. 4109 params.clearBeforeRenderPass = rng.getBool(); 4110 // Decide whether should render to the whole framebuffer or a subarea. 4111 params.renderToWholeFramebuffer = rng.getBool(); 4112 // These tests blend color so they can verify the results all at once at the end. 4113 params.testBlendsColors = true; 4114 4115 // Set random clear values. Use small values as draw calls do additive blending. 4116 generateRandomClearValues(rng, params, params.clearValues, true); 4117 4118 // Decide DrawPushConstants 4119 for (deUint32 passNdx = 0; passNdx < passCount; ++passNdx) 4120 { 4121 TestParams::PerPass& perPass = params.perPass[passNdx]; 4122 4123 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4124 { 4125 perPass.drawConstantsWithDepthWrite[regionNdx] = DrawPushConstants{ 4126 {Vec4(rng.getFloat(0.05f, 0.1f), 0, rng.getFloat(0.05f, 0.1f), 0), Vec4(0, rng.getFloat(0.05f, 0.1f), 0, rng.getFloat(0.05f, 0.1f))}, 4127 {Vec4(rng.getFloat(0.05f, 0.1f), rng.getFloat(0.05f, 0.1f), 0, 0), Vec4(0, 0, rng.getFloat(0.05f, 0.1f), rng.getFloat(0.05f, 0.1f))}, 4128 {IVec4(0, 0, 0, 0), IVec4(0, 0, 0, 0)}, 4129 // Use quantized values to avoid values that are too close and may cause precision issues 4130 Vec2(0.1f * static_cast<float>(rng.getInt(2, 9)), 0.1f * static_cast<float>(rng.getInt(2, 9))), 4131 }; 4132 4133 perPass.drawConstantsWithDepthTest[regionNdx] = DrawPushConstants{ 4134 {Vec4(rng.getFloat(0.05f, 0.1f), 0, rng.getFloat(0.05f, 0.1f), 0), Vec4(0, rng.getFloat(0.05f, 0.1f), 0, rng.getFloat(0.05f, 0.1f))}, 4135 {Vec4(rng.getFloat(0.05f, 0.1f), rng.getFloat(0.05f, 0.1f), 0, 0), Vec4(0, 0, rng.getFloat(0.05f, 0.1f), rng.getFloat(0.05f, 0.1f))}, 4136 {IVec4(0, 0, 0, 0), IVec4(0, 0, 0, 0)}, 4137 Vec2(0.1f * static_cast<float>(rng.getInt(2, 9)) + 0.05f, 0.1f * static_cast<float>(rng.getInt(2, 8)) + 0.05f), 4138 }; 4139 4140 // Integer resolve may choose any sample, so we modify only one channel per pass (hence the maximum of 4 passes). This way, the verification 4141 // shader can accept two values per channel. 4142 perPass.drawConstantsWithDepthWrite[regionNdx].color3Data[0][passNdx] = rng.getInt(1000, 5000); 4143 perPass.drawConstantsWithDepthWrite[regionNdx].color3Data[1][passNdx] = rng.getInt(1000, 5000); 4144 perPass.drawConstantsWithDepthTest[regionNdx].color3Data[0][passNdx] = rng.getInt(1000, 5000); 4145 perPass.drawConstantsWithDepthTest[regionNdx].color3Data[1][passNdx] = rng.getInt(1000, 5000); 4146 } 4147 } 4148 4149 // Calculate VerifyPushConstants. Walk through the passes and emulate what the draw calls would produce. 4150 // Note: Color clear value is not applied and is added by the verification shader. This is because the verification shader interpolates colors with black, 4151 // so the baseline (clear value) is added afterwards. 4152 Vec2 depthResult[RegionCount]; 4153 UVec2 stencilResult[RegionCount]; 4154 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4155 { 4156 depthResult[regionNdx] = Vec2(params.clearValues[3].depthStencil.depth, params.clearValues[3].depthStencil.depth); 4157 stencilResult[regionNdx] = UVec2(params.clearValues[3].depthStencil.stencil, params.clearValues[3].depthStencil.stencil); 4158 } 4159 4160 for (deUint32 passNdx = 0; passNdx < passCount; ++passNdx) 4161 { 4162 TestParams::PerPass& perPass = params.perPass[passNdx]; 4163 4164 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4165 { 4166 // Apply the draw call output to enabled attachments. Note that the tests always do additive blending, and when depth test succeeds, stencil is incremented. 4167 4168 // First draw call overwrites depth and always succeeds. 4169 // Second draw call overwrites only the samples that pass the depth test (which is GREATER). 4170 const bool evenSamplesPassDepthTest = perPass.hasDepthStencil && 4171 (!isDepthFormat(params.depthStencilFormat) || perPass.drawConstantsWithDepthTest[regionNdx].depthData[0] > perPass.drawConstantsWithDepthWrite[regionNdx].depthData[0]); 4172 const bool oddSamplesPassDepthTest = perPass.hasDepthStencil && 4173 (!isDepthFormat(params.depthStencilFormat) || perPass.drawConstantsWithDepthTest[regionNdx].depthData[1] > perPass.drawConstantsWithDepthWrite[regionNdx].depthData[1]); 4174 4175 if (perPass.floatColor1Location >= 0) 4176 { 4177 params.verifyConstants[regionNdx].color1Data[0] += perPass.drawConstantsWithDepthWrite[regionNdx].color1Data[0]; 4178 params.verifyConstants[regionNdx].color1Data[1] += perPass.drawConstantsWithDepthWrite[regionNdx].color1Data[1]; 4179 if (evenSamplesPassDepthTest) 4180 params.verifyConstants[regionNdx].color1Data[0] += perPass.drawConstantsWithDepthTest[regionNdx].color1Data[0]; 4181 if (oddSamplesPassDepthTest) 4182 params.verifyConstants[regionNdx].color1Data[1] += perPass.drawConstantsWithDepthTest[regionNdx].color1Data[1]; 4183 } 4184 if (perPass.floatColor2Location >= 0) 4185 { 4186 params.verifyConstants[regionNdx].color2Data[0] += perPass.drawConstantsWithDepthWrite[regionNdx].color2Data[0]; 4187 params.verifyConstants[regionNdx].color2Data[1] += perPass.drawConstantsWithDepthWrite[regionNdx].color2Data[1]; 4188 if (evenSamplesPassDepthTest) 4189 params.verifyConstants[regionNdx].color2Data[0] += perPass.drawConstantsWithDepthTest[regionNdx].color2Data[0]; 4190 if (oddSamplesPassDepthTest) 4191 params.verifyConstants[regionNdx].color2Data[1] += perPass.drawConstantsWithDepthTest[regionNdx].color2Data[1]; 4192 } 4193 if (perPass.intColorLocation >= 0) 4194 { 4195 // Note that integer formats don't blend, so always take the last value that's written. Each pass writes to only one channel, and color mask is used 4196 // to emulate the effect of blending. 4197 if (evenSamplesPassDepthTest) 4198 params.verifyConstants[regionNdx].color3Data[0] += perPass.drawConstantsWithDepthTest[regionNdx].color3Data[0]; 4199 else 4200 params.verifyConstants[regionNdx].color3Data[0] += perPass.drawConstantsWithDepthWrite[regionNdx].color3Data[0]; 4201 4202 if (oddSamplesPassDepthTest) 4203 params.verifyConstants[regionNdx].color3Data[1] += perPass.drawConstantsWithDepthTest[regionNdx].color3Data[1]; 4204 else 4205 params.verifyConstants[regionNdx].color3Data[1] += perPass.drawConstantsWithDepthWrite[regionNdx].color3Data[1]; 4206 } 4207 if (perPass.hasDepthStencil) 4208 { 4209 depthResult[regionNdx] = perPass.drawConstantsWithDepthWrite[regionNdx].depthData; 4210 stencilResult[regionNdx] += UVec2(1); 4211 4212 if (evenSamplesPassDepthTest) 4213 ++stencilResult[regionNdx][0]; 4214 if (oddSamplesPassDepthTest) 4215 ++stencilResult[regionNdx][1]; 4216 } 4217 4218 // There is no need to resolve color attachments between passes. For float formats, the additive nature of blend and resolve means we can continue adding to 4219 // the two color vectors and get the same result in the end, no matter when and how often resolve happens. For the integer formats this is not true (because resolve 4220 // does not average), so the test makes sure every channel is written to in only one pass, which again means there's no need to perform a resolve in between passes. 4221 // Depth/stencil needs to resolve though, either if multisampled and requested or if it's single sampled. 4222 if (perPass.resolveDepthStencil || params.numDepthStencilSamples == VK_SAMPLE_COUNT_1_BIT) 4223 { 4224 DE_ASSERT(perPass.depthStencilResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT || perPass.depthStencilResolveMode == VK_RESOLVE_MODE_MAX_BIT); 4225 if (perPass.depthStencilResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) 4226 { 4227 params.verifyConstants[regionNdx].depthData = depthResult[regionNdx][0]; 4228 params.verifyConstants[regionNdx].stencilData = stencilResult[regionNdx][0]; 4229 } 4230 else 4231 { 4232 params.verifyConstants[regionNdx].depthData = std::max(depthResult[regionNdx][0], depthResult[regionNdx][1]); 4233 params.verifyConstants[regionNdx].stencilData = std::max(stencilResult[regionNdx][0], stencilResult[regionNdx][1]); 4234 } 4235 4236 // If depth/stencil is single-sampled, prepare the data for the next pass. If multisampled, it will no longer be used after the resolve. 4237 depthResult[regionNdx][0] = depthResult[regionNdx][1] = params.verifyConstants[regionNdx].depthData; 4238 stencilResult[regionNdx][0] = stencilResult[regionNdx][1] = params.verifyConstants[regionNdx].stencilData; 4239 } 4240 } 4241 } 4242 4243 params.rngSeed = rng.getUint32(); 4244 4245 // Note: formats are decided outside this function 4246} 4247 4248void initMultipassPrograms (SourceCollections& programCollection, const TestParams params) 4249{ 4250 // Vertex shader - position 4251 { 4252 std::ostringstream src; 4253 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4254 << "\n" 4255 << "layout(location = 0) in vec4 in_position;\n" 4256 << "\n" 4257 << "out gl_PerVertex {\n" 4258 << " vec4 gl_Position;\n" 4259 << "};\n" 4260 << "\n" 4261 << "void main(void)\n" 4262 << "{\n" 4263 << " gl_Position = in_position;\n" 4264 << "}\n"; 4265 4266 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 4267 } 4268 4269 const bool usesSignedIntFormat = params.intColorFormat == VK_FORMAT_R16G16B16A16_SINT; 4270 const char* intTypePrefix = usesSignedIntFormat ? "i" : "u"; 4271 4272 // Fragment shader - output color based on sample index and push constants 4273 for (size_t passNdx = 0; passNdx < params.perPass.size(); ++passNdx) 4274 { 4275 const TestParams::PerPass &perPass = params.perPass[passNdx]; 4276 4277 // The framebuffer contains four attachments with a mixture of samples. A subpass can only contain a mixture of 1x and Nx samples with the pipelines configured at Nx multisampled rendering. 4278 // The fragment shader is adjusted based on which of these attachments are used in the subpass. The output of the fragment shader is determined by push constants 4279 // as such (2 colors specified per output in uniform data): 4280 // 4281 // - For even samples, output color is interpolation of color 0 and transparent black from left to right 4282 // - For odd samples, output color is interpolation of color 1 and transparent black from top to bottom 4283 // 4284 // Additionally, the fragment shader outputs depth based on the sample index as well. 4285 // 4286 std::ostringstream src; 4287 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4288 << "\n"; 4289 4290 if (perPass.floatColor1Location >= 0) 4291 src << "layout(location = " << perPass.floatColor1Location << ") out vec4 o_color1;\n"; 4292 if (perPass.floatColor2Location >= 0) 4293 src << "layout(location = " << perPass.floatColor2Location << ") out vec4 o_color2;\n"; 4294 if (perPass.intColorLocation >= 0) 4295 src << "layout(location = " << perPass.intColorLocation << ") out " << intTypePrefix << "vec4 o_color3;\n"; 4296 4297 src << "\n" 4298 << "layout(push_constant) uniform PushConstants {\n" 4299 << " uvec4 area;\n" 4300 << " vec4 color1Data[2];\n" 4301 << " vec4 color2Data[2];\n" 4302 << " ivec4 color3Data[2];\n" 4303 << " vec2 depthData;\n" 4304 << "} params;\n" 4305 << "\n" 4306 << "void main(void)\n" 4307 << "{\n" 4308 << " vec2 uv = (gl_FragCoord.xy - vec2(params.area.xy)) / vec2(params.area.zw);\n" 4309 << " if (gl_SampleID % 2 == 0)\n" 4310 << " {\n"; 4311 4312 if (perPass.floatColor1Location >= 0) 4313 src << " o_color1 = params.color1Data[0] * uv.x;\n"; 4314 if (perPass.floatColor2Location >= 0) 4315 src << " o_color2 = params.color2Data[0] * uv.x;\n"; 4316 if (perPass.intColorLocation >= 0) 4317 src << " o_color3 = " << intTypePrefix << "vec4(vec4(params.color3Data[0]) * uv.x);\n"; 4318 if (perPass.hasDepthStencil) 4319 src << " gl_FragDepth = params.depthData.x;\n"; 4320 4321 src << " }\n" 4322 << " else\n" 4323 << " {\n"; 4324 4325 if (perPass.floatColor1Location >= 0) 4326 src << " o_color1 = params.color1Data[1] * uv.y;\n"; 4327 if (perPass.floatColor2Location >= 0) 4328 src << " o_color2 = params.color2Data[1] * uv.y;\n"; 4329 if (perPass.intColorLocation >= 0) 4330 src << " o_color3 = " << intTypePrefix << "vec4(vec4(params.color3Data[1]) * uv.y);\n"; 4331 if (perPass.hasDepthStencil) 4332 src << " gl_FragDepth = params.depthData.y;\n"; 4333 4334 src << " }\n" 4335 << "}\n"; 4336 4337 std::ostringstream name; 4338 name << "frag_" << passNdx; 4339 4340 programCollection.glslSources.add(name.str()) << glu::FragmentSource(src.str()); 4341 } 4342 4343 // Compute shader - verify the results of rendering 4344 { 4345 // The images are cleared and rendered to, possibly multiple times with blend, by blending between one color and black horizontally and another color and black vertically for every other sample. 4346 // Once resolved, the resulting image is verified by interpolating one color and black horizontally, another color and black vertically, averaging them and adding in the clear color. For integer 4347 // formats, instead of averaging the two interpolated colors, either of the colors is accepted as integer resolves selects any sample. A comparison threshold is used to avoid precision issues. 4348 // Each pixel that passes the test atomically increments an integer in the output buffer. The test passes if the final number in the output buffer is the same as the number of pixels in the area being verified. 4349 4350 std::ostringstream src; 4351 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4352 << "#extension GL_EXT_samplerless_texture_functions : require\n" 4353 << "\n" 4354 << "layout(push_constant) uniform PushConstants {\n" 4355 << " uvec4 area;\n" 4356 << " vec4 color1Data[2];\n" 4357 << " vec4 color2Data[2];\n" 4358 << " ivec4 color3Data[2];\n" 4359 << " float depthData;\n" 4360 << " uint stencilData;\n" 4361 << "} params;\n" 4362 << "\n" 4363 << "layout(local_size_x = 8, local_size_y = 8) in;\n" 4364 << "layout(set = 0, binding = 0, std430) writeonly buffer Output {\n" 4365 << " uint colorVerification[3];\n" 4366 << " uint depthVerification;\n" 4367 << " uint stencilVerification;\n" 4368 << "} sb_out;\n" 4369 << "layout(set = 0, binding = 1) uniform texture2D color1Image;\n" 4370 << "layout(set = 0, binding = 2) uniform texture2D color2Image;\n" 4371 << "layout(set = 0, binding = 3) uniform " << (usesSignedIntFormat ? "i" : "u") << "texture2D color3Image;\n"; 4372 if (isDepthFormat(params.depthStencilFormat)) 4373 src << "layout(set = 0, binding = 4) uniform texture2D depthImage;\n"; 4374 if (isStencilFormat(params.depthStencilFormat)) 4375 src << "layout(set = 0, binding = 5) uniform utexture2D stencilImage;\n"; 4376 src << "layout(set = 0, binding = 6, rgba8) uniform writeonly image2DArray verify;\n" 4377 << "\n" 4378 << "bool fmatches(float a, float b, float error)\n" 4379 << "{\n" 4380 << " return abs(a - b) < error;\n" 4381 << "}\n" 4382 << "bool umatches(uint a, uint b, uint error)\n" 4383 << "{\n" 4384 << " return abs(a - b) <= error;\n" 4385 << "}\n" 4386 << "bool v4matches(vec4 a, vec4 b, vec4 error)\n" 4387 << "{\n" 4388 << " return all(lessThan(abs(a - b), error));\n" 4389 << "}\n" 4390 << "bool i4matchesEither(ivec4 a, ivec4 b, ivec4 c, ivec4 errorB, ivec4 errorC)\n" 4391 << "{\n" 4392 << " const bvec4 bMatches = lessThanEqual(abs(a - b), errorB);\n" 4393 << " const bvec4 cMatches = lessThanEqual(abs(a - c), errorC);\n" 4394 << " return all(bvec4(bMatches.x || cMatches.x, bMatches.y || cMatches.y, bMatches.z || cMatches.z, bMatches.w || cMatches.w));\n" 4395 << "}\n" 4396 << "\n" 4397 << "void main (void)\n" 4398 << "{\n" 4399 << " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, params.area.zw)))\n" 4400 << " return;\n" 4401 << "\n" 4402 << " uvec2 coords = params.area.xy + gl_GlobalInvocationID.xy;\n" 4403 << " vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5)) / vec2(params.area.zw);\n" 4404 << "\n" 4405 << " vec4 result1 = vec4(1, 0, 0, 1);\n" 4406 << " vec4 color1 = texelFetch(color1Image, ivec2(coords), 0);\n" 4407 << " vec4 expected1 = (params.color1Data[0] * uv.x + params.color1Data[1] * uv.y) / 2.0"; 4408 if (params.testBlendsColors) 4409 src << " + vec4(" << params.clearValues[0].color.float32[0] << ", " 4410 << params.clearValues[0].color.float32[1] << ", " 4411 << params.clearValues[0].color.float32[2] << ", " 4412 << params.clearValues[0].color.float32[3] << ")"; 4413 src << ";\n" 4414 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 4415 << " if (v4matches(color1, expected1, max(params.color1Data[0] / float(params.area.z), params.color1Data[1] / float(params.area.w)) + 2.0/255.0))\n" 4416 << " {\n" 4417 << " atomicAdd(sb_out.colorVerification[0], 1);\n" 4418 << " result1 = vec4(0, 1, 0, 1);\n" 4419 << " }\n" 4420 << " imageStore(verify, ivec3(coords, 0), result1);\n" 4421 << "\n" 4422 << " vec4 result2 = vec4(1, 0, 0, 1);\n" 4423 << " vec4 color2 = texelFetch(color2Image, ivec2(coords), 0);\n" 4424 << " vec4 expected2 = (params.color2Data[0] * uv.x + params.color2Data[1] * uv.y) / 2.0"; 4425 if (params.testBlendsColors) 4426 src << " + vec4(" << params.clearValues[1].color.float32[0] << ", " 4427 << params.clearValues[1].color.float32[1] << ", " 4428 << params.clearValues[1].color.float32[2] << ", " 4429 << params.clearValues[1].color.float32[3] << ")"; 4430 src << ";\n" 4431 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 4432 << " if (v4matches(color2, expected2, max(params.color2Data[0] / float(params.area.z), params.color2Data[1] / float(params.area.w)) + 2.0/1024.0))\n" 4433 << " {\n" 4434 << " atomicAdd(sb_out.colorVerification[1], 1);\n" 4435 << " result2 = vec4(0, 1, 0, 1);\n" 4436 << " }\n" 4437 << " imageStore(verify, ivec3(coords, 1), result2);\n" 4438 << "\n" 4439 << " vec4 result3 = vec4(1, 0, 0, 1);\n" 4440 << " ivec4 color3 = ivec4(texelFetch(color3Image, ivec2(coords), 0));\n"; 4441 // Note that integer formats don't blend, so clear values are discarded, except for channels that are never written to. Each pass 4442 // outputs only to one channel. 4443 if (params.testBlendsColors) 4444 src << " ivec4 clearValue3 = ivec4(" << (params.perPass[0].intColorLocation < 0 ? params.clearValues[2].color.int32[0] : 0) << ", " 4445 << (params.perPass.size() < 2 || params.perPass[1].intColorLocation < 0 ? params.clearValues[2].color.int32[1] : 0) << ", " 4446 << (params.perPass.size() < 3 || params.perPass[2].intColorLocation < 0 ? params.clearValues[2].color.int32[2] : 0) << ", " 4447 << (params.perPass.size() < 4 || params.perPass[3].intColorLocation < 0 ? params.clearValues[2].color.int32[3] : 0) << ")" << ";\n"; 4448 else 4449 src << " ivec4 clearValue3 = ivec4(0);\n"; 4450 src << " ivec4 expected3_0 = ivec4(params.color3Data[0] * uv.x) + clearValue3;\n" 4451 << " ivec4 expected3_1 = ivec4(params.color3Data[1] * uv.y) + clearValue3;\n" 4452 // Allow room for precision errors. Rendering happens at sample locations while verification uv is in the middle of pixel. 4453 << " if (i4matchesEither(color3, expected3_0, expected3_1, params.color3Data[0] / int(params.area.z), params.color3Data[1] / int(params.area.w)))\n" 4454 << " {\n" 4455 << " atomicAdd(sb_out.colorVerification[2], 1);\n" 4456 << " result3 = vec4(0, 1, 0, 1);\n" 4457 << " }\n" 4458 << " imageStore(verify, ivec3(coords, 2), result3);\n" 4459 << "\n"; 4460 if (isDepthFormat(params.depthStencilFormat)) 4461 src << " vec4 resultDepth = vec4(1, 0, 0, 1);\n" 4462 << " float depth = texelFetch(depthImage, ivec2(coords), 0).r;\n" 4463 << " if (fmatches(depth, params.depthData, 0.01))\n" 4464 << " {\n" 4465 << " atomicAdd(sb_out.depthVerification, 1);\n" 4466 << " resultDepth = vec4(0, 1, 0, 1);\n" 4467 << " }\n" 4468 << " imageStore(verify, ivec3(coords, 3), resultDepth);\n"; 4469 if (isStencilFormat(params.depthStencilFormat)) 4470 src << " vec4 resultStencil = vec4(1, 0, 0, 1);\n" 4471 << " uint stencil = texelFetch(stencilImage, ivec2(coords), 0).r;\n" 4472 << " if (umatches(stencil, params.stencilData, 0))\n" 4473 << " {\n" 4474 << " atomicAdd(sb_out.stencilVerification, 1);\n" 4475 << " resultStencil = vec4(0, 1, 0, 1);\n" 4476 << " }\n" 4477 << " imageStore(verify, ivec3(coords, 4), resultStencil);\n"; 4478 src << "}\n"; 4479 4480 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()); 4481 } 4482 4483 const bool verifyOutsideRenderArea = params.clearBeforeRenderPass && !params.renderToWholeFramebuffer; 4484 if (verifyOutsideRenderArea) 4485 initConstantColorVerifyPrograms(programCollection, params); 4486} 4487 4488void drawInputAttachments (Context& context, const TestParams& params, WorkingData& wd, TestObjects& testObjects) 4489{ 4490 const InstanceInterface& vki = context.getInstanceInterface(); 4491 const DeviceInterface& vk = context.getDeviceInterface(); 4492 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 4493 const VkDevice device = context.getDevice(); 4494 const deUint32 numSubpasses = static_cast<deUint32>(params.perPass.size()); 4495 4496 if (params.clearBeforeRenderPass) 4497 { 4498 clearImagesBeforeDraw(context, params, wd, testObjects); 4499 } 4500 4501 // Create a render pass and a framebuffer 4502 { 4503 std::vector<VkSubpassDescription2> subpasses; 4504 std::vector<VkImage> images; 4505 std::vector<VkImageView> attachments; 4506 std::vector<VkAttachmentDescription2> attachmentDescriptions; 4507 std::vector<std::vector<VkAttachmentReference2>> attachmentReferences(numSubpasses); 4508 std::vector<std::vector<VkAttachmentReference2>> resolveAttachmentReferences(numSubpasses); 4509 std::vector<std::vector<deUint32>> preserveAttachments(numSubpasses); 4510 std::vector<VkAttachmentReference2> inputAttachmentReferences; 4511 std::vector<VkSubpassDependency2> subpassDependencies; 4512 std::vector<VkMultisampledRenderToSingleSampledInfoEXT> msrtss(numSubpasses); 4513 std::vector<VkSubpassDescriptionDepthStencilResolve> depthStencilResolve(numSubpasses); 4514 deInt32 attachmentNdxes[8] = {-1, -1, -1, -1, 4515 -1, -1, -1, -1}; 4516 deUint32 attachmentUseMask = 0; 4517 4518 initializeAttachments(params, wd, images, attachments, params.perPass.size(), attachmentNdxes); 4519 initializeAttachmentDescriptions(params, attachmentDescriptions, params.clearBeforeRenderPass, attachmentNdxes, attachmentUseMask); 4520 4521 DE_ASSERT(numSubpasses == 2); 4522 inputAttachmentReferences.resize(2, VkAttachmentReference2{ 4523 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType; 4524 DE_NULL, // const void* pNext; 4525 VK_ATTACHMENT_UNUSED, // uint32_t attachment; 4526 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout layout; 4527 0, // VkImageAspectFlags aspectMask; 4528 }); 4529 // Color attachment 1 and depth/stencil attachment are used as input attachments in subpass 1. 4530 initializeAttachmentReference(inputAttachmentReferences[0], attachmentNdxes[0], VK_FORMAT_UNDEFINED, true); 4531 initializeAttachmentReference(inputAttachmentReferences[1], attachmentNdxes[3], params.depthStencilFormat, true); 4532 4533 for (deUint32 passNdx = 0; passNdx < numSubpasses; ++passNdx) 4534 { 4535 const std::vector<VkAttachmentReference2> noInputAttachments; 4536 4537 addSubpassDescription(params, 4538 passNdx, 4539 attachmentReferences[passNdx], 4540 resolveAttachmentReferences[passNdx], 4541 depthStencilResolve[passNdx], 4542 &preserveAttachments[passNdx], 4543 msrtss[passNdx], 4544 subpasses, 4545 passNdx == 0 ? noInputAttachments : inputAttachmentReferences, 4546 attachmentNdxes); 4547 } 4548 4549 subpassDependencies.push_back(VkSubpassDependency2{ 4550 VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, // VkStructureType sType; 4551 DE_NULL, // const void* pNext; 4552 0, // uint32_t srcSubpass; 4553 1, // uint32_t dstSubpass; 4554 4555 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 4556 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask; 4557 4558 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask; 4559 4560 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 4561 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 4562 4563 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; 4564 4565 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; 4566 0, // int32_t viewOffset; 4567 }); 4568 4569 createRenderPassAndFramebuffer(context, wd, testObjects, params.pipelineConstructionType, images, attachments, attachmentDescriptions, subpasses, subpassDependencies); 4570 } 4571 4572 const VkPushConstantRange& pushConstantRange = 4573 { 4574 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 4575 0, // uint32_t offset; 4576 static_cast<deUint32>(sizeof(UVec4) + sizeof(DrawPushConstants)), // uint32_t size; 4577 }; 4578 4579 const ShaderWrapper vertexModule (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 4580 const ShaderWrapper fragmentModule0 (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag_0"), 0u)); 4581 const ShaderWrapper fragmentModule1 (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag_1"), 0u)); 4582 const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, 0, DE_NULL, 1, &pushConstantRange); 4583 4584 // Descriptor set and layout for the draw call that uses input attachments 4585 const Unique<VkDescriptorSetLayout> descriptorSetLayout( 4586 DescriptorSetLayoutBuilder() 4587 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) 4588 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) 4589 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) 4590 .build(vk, device)); 4591 4592 testObjects.descriptorPools.emplace_back( 4593 DescriptorPoolBuilder() 4594 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u) 4595 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u) 4596 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u) 4597 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 4598 4599 testObjects.descriptorSets.emplace_back(makeDescriptorSet(vk, device, *testObjects.descriptorPools.back(), *descriptorSetLayout)); 4600 4601 const VkDescriptorImageInfo color1Info = makeDescriptorImageInfo(DE_NULL, *wd.floatColor1.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 4602 const VkDescriptorImageInfo depthInfo = makeDescriptorImageInfo(DE_NULL, isDepthFormat(params.depthStencilFormat) ? *wd.depthOnlyImageView : *wd.stencilOnlyImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 4603 const VkDescriptorImageInfo stencilInfo = makeDescriptorImageInfo(DE_NULL, isStencilFormat(params.depthStencilFormat) ? *wd.stencilOnlyImageView : *wd.depthOnlyImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 4604 4605 DescriptorSetUpdateBuilder builder; 4606 4607 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &color1Info); 4608 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &depthInfo); 4609 builder.writeSingle(*testObjects.descriptorSets.back(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &stencilInfo); 4610 4611 builder.update(vk, device); 4612 4613 const VkPushConstantRange& inputPushConstantRange = 4614 { 4615 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 4616 0, // uint32_t offset; 4617 static_cast<deUint32>(sizeof(UVec4)), // uint32_t size; 4618 }; 4619 4620 const ShaderWrapper fragmentModuleIn (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag_in"), 0u)); 4621 const PipelineLayoutWrapper inputPipelineLayout (params.pipelineConstructionType, vk, device, 1, &*descriptorSetLayout, 1, &inputPushConstantRange); 4622 4623 UVec4 regions[RegionCount]; 4624 getDrawRegions(wd, regions); 4625 4626 startRenderPass(context, wd, testObjects, DE_LENGTH_OF_ARRAY(params.clearValues), params.clearValues); 4627 4628 { 4629 DE_ASSERT(numSubpasses == 2); 4630 4631 const VkDeviceSize vertexBufferOffset = 0; 4632 vk.cmdBindVertexBuffers(*testObjects.cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 4633 4634 // First draw call outputs to color attachment 1 and depth/stencil. It doesn't blend with clear for simplicity of the verification code. 4635 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4636 { 4637 testObjects.graphicsPipelines.push_back( 4638 pipeline::makeGraphicsPipeline(vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType, pipelineLayout, *testObjects.renderPassFramebuffers.back(), DE_NULL, vertexModule, fragmentModule0, false, true, false, 0, 0, 4639 params.perPass[0].intColorLocation, regions[regionNdx], regions[regionNdx], params.perPass[0].numSamples, params.useGarbageAttachment)); 4640 4641 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 4642 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(UVec4), sizeof(params.perPass[0].drawConstantsWithDepthWrite[regionNdx]), ¶ms.perPass[0].drawConstantsWithDepthWrite[regionNdx]); 4643 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 4644 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 4645 } 4646 4647 // Next subpass initializes color attachments 2 and 3 from color attachment 1 and depth/stencil, then issues a draw call that modifies those attachments. 4648 testObjects.renderPassFramebuffers.back().nextSubpass(vk, *testObjects.cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 4649 4650 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4651 { 4652 testObjects.graphicsPipelines.push_back( 4653 pipeline::makeGraphicsPipeline(vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType, inputPipelineLayout, *testObjects.renderPassFramebuffers.back(), DE_NULL, vertexModule, fragmentModuleIn, false, false, false, 0, 1, 4654 params.perPass[1].intColorLocation, regions[regionNdx], regions[regionNdx], params.perPass[1].numSamples, params.useGarbageAttachment)); 4655 4656 vk.cmdPushConstants(*testObjects.cmdBuffer, *inputPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 4657 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 4658 vk.cmdBindDescriptorSets(*testObjects.cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *inputPipelineLayout, 0u, 1u, &testObjects.descriptorSets.back().get(), 0u, DE_NULL); 4659 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 4660 } 4661 4662 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4663 { 4664 testObjects.graphicsPipelines.push_back( 4665 pipeline::makeGraphicsPipeline(vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType, pipelineLayout, *testObjects.renderPassFramebuffers.back(), DE_NULL, vertexModule, fragmentModule1, true, false, false, 0xC, 1, 4666 params.perPass[1].intColorLocation, regions[regionNdx], regions[regionNdx], params.perPass[1].numSamples, params.useGarbageAttachment)); 4667 4668 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(UVec4), ®ions[regionNdx]); 4669 vk.cmdPushConstants(*testObjects.cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(UVec4), sizeof(params.perPass[1].drawConstantsWithDepthWrite[regionNdx]), ¶ms.perPass[1].drawConstantsWithDepthWrite[regionNdx]); 4670 (*testObjects.graphicsPipelines.back()).bind(*testObjects.cmdBuffer); 4671 vk.cmdDraw(*testObjects.cmdBuffer, 3, 1u, 0u, 0u); 4672 } 4673 } 4674 4675 testObjects.renderPassFramebuffers.back().end(vk, *testObjects.cmdBuffer); 4676 4677 // Verify results 4678 dispatchVerifyMultiPassRendering(context, params, wd, testObjects, regions); 4679} 4680 4681//! Verify input attachments and multisampled rendering interact correctly. 4682tcu::TestStatus testInputAttachments (Context& context, const TestParams params) 4683{ 4684 WorkingData wd; 4685 TestObjects testObjects(context); 4686 testStart(context, params, wd, testObjects); 4687 4688 drawInputAttachments (context, params, wd, testObjects); 4689 4690 testEnd(context, params, wd, testObjects); 4691 return verify(context, params, wd); 4692} 4693 4694void generateInputAttachmentsTest (de::Random& rng, TestParams& params, const VkSampleCountFlagBits sampleCount, const VkResolveModeFlagBits resolveMode, const bool renderToWholeFramebuffer) 4695{ 4696 params.perPass.resize(2); 4697 4698 // Set the sample count for attachments. 4699 if (params.isMultisampledRenderToSingleSampled) 4700 { 4701 params.numFloatColor1Samples = VK_SAMPLE_COUNT_1_BIT; 4702 params.numFloatColor2Samples = VK_SAMPLE_COUNT_1_BIT; 4703 params.numIntColorSamples = VK_SAMPLE_COUNT_1_BIT; 4704 params.numDepthStencilSamples = VK_SAMPLE_COUNT_1_BIT; 4705 4706 params.perPass[0].resolveFloatColor1 = false; 4707 params.perPass[0].resolveDepthStencil = false; 4708 4709 params.perPass[1].resolveFloatColor2 = false; 4710 params.perPass[1].resolveIntColor = false; 4711 } 4712 else 4713 { 4714 params.numFloatColor1Samples = sampleCount; 4715 params.numFloatColor2Samples = sampleCount; 4716 params.numIntColorSamples = sampleCount; 4717 params.numDepthStencilSamples = sampleCount; 4718 4719 params.perPass[0].resolveFloatColor1 = true; 4720 params.perPass[0].resolveDepthStencil = true; 4721 4722 params.perPass[1].resolveFloatColor2 = true; 4723 params.perPass[1].resolveIntColor = true; 4724 } 4725 4726 // Subpass 0 renders to color1 and depth/stencil only. They are resolved at the end of the pass. 4727 params.perPass[0].resolveFloatColor2 = false; 4728 params.perPass[0].resolveIntColor = false; 4729 params.perPass[0].depthStencilResolveMode = resolveMode; 4730 4731 params.perPass[0].numSamples = sampleCount; 4732 4733 params.perPass[0].floatColor1Location = 0; 4734 params.perPass[0].floatColor2Location = -1; 4735 params.perPass[0].intColorLocation = -1; 4736 params.perPass[0].hasDepthStencil = true; 4737 4738 // Subpass 1 uses color1 and depth/stencil as input attachments and outputs to color2 and color3. 4739 params.perPass[1].resolveFloatColor1 = false; 4740 params.perPass[1].resolveDepthStencil = false; 4741 4742 params.perPass[1].numSamples = params.isMultisampledRenderToSingleSampled ? VK_SAMPLE_COUNT_1_BIT : sampleCount; 4743 4744 params.perPass[1].floatColor1Location = -1; 4745 params.perPass[1].floatColor2Location = 3; 4746 params.perPass[1].intColorLocation = 2; 4747 params.perPass[1].hasDepthStencil = false; 4748 4749 // Always clear before render pass so outside render area can be verified. 4750 params.clearBeforeRenderPass = true; 4751 params.renderToWholeFramebuffer = renderToWholeFramebuffer; 4752 params.testBlendsColors = false; 4753 4754 // Set random clear values. 4755 generateRandomClearValues(rng, params, params.clearValues, true); 4756 4757 // Decide DrawPushConstants 4758 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4759 { 4760 // Subpass 0 writes to color 1, depth and stencil. 4761 params.perPass[0].drawConstantsWithDepthWrite[regionNdx] = DrawPushConstants{ 4762 {Vec4(rng.getFloat(0.2f, 0.4f), 0, rng.getFloat(0.2f, 0.4f), 0), Vec4(0, rng.getFloat(0.2f, 0.4f), 0, rng.getFloat(0.2f, 0.4f))}, 4763 {Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0)}, 4764 {IVec4(0, 0, 0, 0), IVec4(0, 0, 0, 0)}, 4765 // Use quantized values to avoid values that are too close and may cause precision issues 4766 Vec2(0.025f * static_cast<float>(rng.getInt(2, 38)), 0.025f * static_cast<float>(rng.getInt(2, 38))), 4767 }; 4768 4769 // Subpass 1 writes to color 2 and color 3. 4770 params.perPass[1].drawConstantsWithDepthWrite[regionNdx] = DrawPushConstants{ 4771 {Vec4(0, 0, 0, 0), Vec4(0, 0, 0, 0)}, 4772 {Vec4(rng.getFloat(0.2f, 0.4f), rng.getFloat(0.2f, 0.4f), 0, 0), Vec4(0, 0, rng.getFloat(0.2f, 0.4f), rng.getFloat(0.2f, 0.4f))}, 4773 {IVec4(0, 0, 0, 0), IVec4(0, 0, 0, 0)}, 4774 // Use quantized values to avoid values that are too close and may cause precision issues 4775 Vec2(0, 0), 4776 }; 4777 4778 // Integer resolve may choose any sample, so we modify only one channel. This way, the verification 4779 // shader can accept two values per channel. 4780 params.perPass[0].drawConstantsWithDepthWrite[regionNdx].color3Data[0][0] = rng.getInt(1000, 5000); 4781 params.perPass[0].drawConstantsWithDepthWrite[regionNdx].color3Data[1][1] = rng.getInt(1000, 5000); 4782 params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color3Data[0][2] = rng.getInt(1000, 5000); 4783 params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color3Data[1][3] = rng.getInt(1000, 5000); 4784 } 4785 4786 // Calculate VerifyPushConstants. Walk through the passes and emulate what the draw calls would produce. 4787 for (deUint32 regionNdx = 0; regionNdx < RegionCount; ++regionNdx) 4788 { 4789 // First, subpass[0]'s data is written to every sample of color1 and depth/stencil. 4790 params.verifyConstants[regionNdx].color1Data[0] = params.perPass[0].drawConstantsWithDepthWrite[regionNdx].color1Data[0]; 4791 params.verifyConstants[regionNdx].color1Data[1] = params.perPass[0].drawConstantsWithDepthWrite[regionNdx].color1Data[1]; 4792 4793 // Then depth/stencil is resolved 4794 DE_ASSERT(resolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT || resolveMode == VK_RESOLVE_MODE_MAX_BIT); 4795 if (resolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) 4796 { 4797 params.verifyConstants[regionNdx].depthData = params.perPass[0].drawConstantsWithDepthWrite[regionNdx].depthData[0]; 4798 } 4799 else 4800 { 4801 params.verifyConstants[regionNdx].depthData = std::max(params.perPass[0].drawConstantsWithDepthWrite[regionNdx].depthData[0], params.perPass[0].drawConstantsWithDepthWrite[regionNdx].depthData[1]); 4802 } 4803 params.verifyConstants[regionNdx].stencilData = params.clearValues[3].depthStencil.stencil + 1; 4804 4805 // Then subpass 1 initializes color2 and color3 based on the previous subpass' color1 and depth/stencil values. 4806 params.verifyConstants[regionNdx].color2Data[0] = params.verifyConstants[regionNdx].color1Data[0]; 4807 params.verifyConstants[regionNdx].color2Data[1] = params.verifyConstants[regionNdx].color1Data[1]; 4808 4809 if (isDepthFormat(params.depthStencilFormat)) 4810 { 4811 if (params.isMultisampledRenderToSingleSampled) 4812 { 4813 params.verifyConstants[regionNdx].color3Data[0][0] = deInt32(10000 * params.verifyConstants[regionNdx].depthData); 4814 params.verifyConstants[regionNdx].color3Data[1][0] = deInt32(10000 * params.verifyConstants[regionNdx].depthData); 4815 } 4816 else 4817 { 4818 params.verifyConstants[regionNdx].color3Data[0][0] = deInt32(10000 * params.perPass[0].drawConstantsWithDepthWrite[regionNdx].depthData[0]); 4819 params.verifyConstants[regionNdx].color3Data[1][0] = deInt32(10000 * params.perPass[0].drawConstantsWithDepthWrite[regionNdx].depthData[1]); 4820 } 4821 } 4822 4823 if (isStencilFormat(params.depthStencilFormat)) 4824 { 4825 params.verifyConstants[regionNdx].color3Data[0][1] = 100 * params.verifyConstants[regionNdx].stencilData; 4826 params.verifyConstants[regionNdx].color3Data[1][1] = 100 * params.verifyConstants[regionNdx].stencilData; 4827 } 4828 4829 // Finally, a draw call in subpass 1 blends on top of those values. 4830 if (params.isMultisampledRenderToSingleSampled) 4831 { 4832 // If subpass 1 is single-sampled, there's only one sample to write to which is interpolated along X. Additionally, there's no resolve. 4833 // The verification code expects the following: 4834 // 4835 // color@uv = (color_even_samples*u + color_odd_samples*v) / 2 4836 // 4837 // In this case, we want color@uv to be color_even_samples*u. We can have the verification shader arrive at this value 4838 // by providing color_even_samples twice what it should be and zero for color_odd_samples: 4839 // 4840 // color@uv = (color_even_samples*2*u + 0*v) / 2 = color_even_samples*u 4841 params.verifyConstants[regionNdx].color2Data[0] += params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color2Data[0] * Vec4(2, 2, 2, 2); 4842 } 4843 else 4844 { 4845 params.verifyConstants[regionNdx].color2Data[0] += params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color2Data[0]; 4846 params.verifyConstants[regionNdx].color2Data[1] += params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color2Data[1]; 4847 } 4848 4849 params.verifyConstants[regionNdx].color3Data[0] += params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color3Data[0]; 4850 params.verifyConstants[regionNdx].color3Data[1] += params.perPass[1].drawConstantsWithDepthWrite[regionNdx].color3Data[1]; 4851 } 4852 4853 params.rngSeed = rng.getUint32(); 4854} 4855 4856void initInputAttachmentsPrograms (SourceCollections& programCollection, const TestParams params) 4857{ 4858 // This test reuses the same programs as the multipass tests for rendering and verification. 4859 initMultipassPrograms(programCollection, params); 4860 4861 const bool usesSignedIntFormat = params.intColorFormat == VK_FORMAT_R16G16B16A16_SINT; 4862 const char* intTypePrefix = usesSignedIntFormat ? "i" : "u"; 4863 const char* subpassInputSuffix = params.perPass[1].numSamples == VK_SAMPLE_COUNT_1_BIT ? "" : "MS"; 4864 const char* subpassLoadParam = params.perPass[1].numSamples == VK_SAMPLE_COUNT_1_BIT ? "" : ", gl_SampleID"; 4865 4866 // Fragment shader - initialize color attachments 2 and 3 with data from color attachments 1 and depth/stencil 4867 { 4868 const TestParams::PerPass &perPass = params.perPass[1]; 4869 4870 // Data from color attachment 1 is replicated in color attachment 2. Data from the depth/stencil attachment is replicated in the red and green 4871 // channels of color attachment 3. Depth is multiplied by 10000 and interpolated along x and stencil by 100 and interpolated along y. This makes 4872 // the result look like the other draw calls that produce a gradient and simplifies the verification code. 4873 std::ostringstream src; 4874 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 4875 << "\n" 4876 << "layout(location = " << perPass.floatColor2Location << ") out vec4 o_color2;\n" 4877 << "layout(location = " << perPass.intColorLocation << ") out " << intTypePrefix << "vec4 o_color3;\n" 4878 << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput" << subpassInputSuffix << " i_color1;\n"; 4879 if (isDepthFormat(params.depthStencilFormat)) 4880 src << "layout(input_attachment_index = 1, set = 0, binding = 1) uniform subpassInput" << subpassInputSuffix << " i_depth;\n"; 4881 if (isStencilFormat(params.depthStencilFormat)) 4882 src << "layout(input_attachment_index = 1, set = 0, binding = 2) uniform usubpassInput" << subpassInputSuffix << " i_stencil;\n"; 4883 src << "\n" 4884 << "layout(push_constant) uniform PushConstants {\n" 4885 << " uvec4 area;\n" 4886 << "} params;\n" 4887 << "\n" 4888 << "void main(void)\n" 4889 << "{\n" 4890 << " vec2 uv = (gl_FragCoord.xy - vec2(params.area.xy)) / vec2(params.area.zw);\n" 4891 << " o_color2 = subpassLoad(i_color1" << subpassLoadParam << ");\n" 4892 << " if (gl_SampleID % 2 != 0)\n" 4893 << " uv.xy = uv.yx;\n" 4894 << " uvec4 color3Value = uvec4(0);\n"; 4895 if (isDepthFormat(params.depthStencilFormat)) 4896 src << " color3Value.x = uint(subpassLoad(i_depth" << subpassLoadParam << ").x * 10000 * uv.x);\n"; 4897 if (isStencilFormat(params.depthStencilFormat)) 4898 src << " color3Value.y = uint(subpassLoad(i_stencil" << subpassLoadParam << ").x * 100 * uv.y);\n"; 4899 src << " o_color3 = " << intTypePrefix << "vec4(color3Value);\n" 4900 << "}\n"; 4901 4902 programCollection.glslSources.add("frag_in") << glu::FragmentSource(src.str()); 4903 } 4904} 4905 4906//! Verify that subpass resolve perf query works. 4907tcu::TestStatus testPerfQuery (Context& context, VkFormat format) 4908{ 4909 const InstanceInterface& vki = context.getInstanceInterface(); 4910 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 4911 VkFormatProperties2 formatProperties = {}; 4912 VkSubpassResolvePerformanceQueryEXT perfQuery = {}; 4913 4914 perfQuery.sType = VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT; 4915 perfQuery.optimal = 0xDEADBEEF; 4916 4917 formatProperties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; 4918 formatProperties.pNext = &perfQuery; 4919 4920 vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties); 4921 4922 // There is actually nothing to verify other than that the above query was successful. 4923 // Regardless of optimal resolve or not, the operations must succeed. We'll just make sure 4924 // the driver did produce a valid response. 4925 if (perfQuery.optimal != VK_FALSE && perfQuery.optimal != VK_TRUE) 4926 { 4927 std::string errorMsg = "VkSubpassResolvePerformanceQueryEXT::optimal is not populated after query"; 4928 return tcu::TestStatus::fail(errorMsg); 4929 } 4930 4931 return tcu::TestStatus::pass("Pass"); 4932} 4933 4934std::string getFormatShortString (const VkFormat format) 4935{ 4936 std::string s(de::toLower(getFormatName(format))); 4937 return s.substr(10); 4938} 4939 4940std::string getFormatCaseName (const VkFormat color1Format, 4941 const VkFormat color2Format, 4942 const VkFormat color3Format, 4943 const VkFormat depthStencilFormat) 4944{ 4945 std::ostringstream str; 4946 str << getFormatShortString(color1Format) 4947 << "_" << getFormatShortString(color2Format) 4948 << "_" << getFormatShortString(color3Format) 4949 << "_" << getFormatShortString(depthStencilFormat); 4950 return str.str(); 4951} 4952 4953std::string getSampleCountCaseName (const VkSampleCountFlagBits sampleCount) 4954{ 4955 std::ostringstream str; 4956 str << sampleCount << "x"; 4957 return str.str(); 4958} 4959 4960std::string getResolveModeCaseName (const VkResolveModeFlagBits resolveMode) 4961{ 4962 std::ostringstream str; 4963 if (resolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) 4964 str << "ds_resolve_sample_zero"; 4965 else if (resolveMode == VK_RESOLVE_MODE_MAX_BIT) 4966 str << "ds_resolve_max"; 4967 else 4968 DE_ASSERT(false); 4969 return str.str(); 4970} 4971 4972void createMultisampledTestsInGroup (tcu::TestCaseGroup* rootGroup, 4973 const bool isMultisampledRenderToSingleSampled, 4974 PipelineConstructionType pipelineConstructionType, 4975 const bool dynamicRendering) 4976{ 4977 // Color 1 is a float format 4978 const VkFormat color1FormatRange[] = 4979 { 4980 VK_FORMAT_R8G8B8A8_UNORM, 4981 }; 4982 constexpr deUint32 color1FormatCount = DE_LENGTH_OF_ARRAY(color1FormatRange); 4983 4984 // Color 2 is a float format 4985 const VkFormat color2FormatRange[] = 4986 { 4987 VK_FORMAT_R16G16B16A16_SFLOAT, 4988 }; 4989 constexpr deUint32 color2FormatCount = DE_LENGTH_OF_ARRAY(color2FormatRange); 4990 4991 // Color 3 is an integer format 4992 const VkFormat color3FormatRange[] = 4993 { 4994 VK_FORMAT_R32G32B32A32_UINT, 4995 VK_FORMAT_R16G16B16A16_SINT, 4996 }; 4997 constexpr deUint32 color3FormatCount = DE_LENGTH_OF_ARRAY(color3FormatRange); 4998 4999 // Test formats with only depth, only stencil or both 5000 const VkFormat depthStencilFormatRange[] = 5001 { 5002 VK_FORMAT_D16_UNORM, //!< Must be supported 5003 VK_FORMAT_S8_UINT, //!< May not be supported 5004 VK_FORMAT_D24_UNORM_S8_UINT, //!< Either this, or the next one must be supported 5005 VK_FORMAT_D32_SFLOAT_S8_UINT, 5006 }; 5007 constexpr deUint32 depthStencilFormatCount = DE_LENGTH_OF_ARRAY(depthStencilFormatRange); 5008 5009 const VkSampleCountFlagBits sampleRange[] = 5010 { 5011 VK_SAMPLE_COUNT_2_BIT, 5012 VK_SAMPLE_COUNT_4_BIT, 5013 VK_SAMPLE_COUNT_8_BIT, 5014 VK_SAMPLE_COUNT_16_BIT, 5015 }; 5016 5017 const VkResolveModeFlagBits depthStencilResolveModeRange[] = 5018 { 5019 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 5020 VK_RESOLVE_MODE_MAX_BIT, 5021 }; 5022 5023 const bool boolRange[] = { false, true }; 5024 5025 // Test 1: Simple tests that verify Nx multisampling actually uses N samples. 5026 { 5027 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "basic")); 5028 5029 de::Random rng(0xDEADBEEF); 5030 5031 for (const VkFormat color1Format : color1FormatRange) 5032 for (const VkFormat color2Format : color2FormatRange) 5033 for (const VkFormat color3Format : color3FormatRange) 5034 for (const VkFormat depthStencilFormat : depthStencilFormatRange) 5035 { 5036 MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup( 5037 rootGroup->getTestContext(), getFormatCaseName(color1Format, color2Format, color3Format, depthStencilFormat).c_str(), "Combination of framebuffer attachment formats")); 5038 5039 for (const VkSampleCountFlagBits sampleCount : sampleRange) 5040 { 5041 MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup( 5042 rootGroup->getTestContext(), getSampleCountCaseName(sampleCount).c_str(), "Sample count")); 5043 5044 for (const VkResolveModeFlagBits resolveMode : depthStencilResolveModeRange) 5045 { 5046 MovePtr<tcu::TestCaseGroup> resolveGroup(new tcu::TestCaseGroup( 5047 rootGroup->getTestContext(), getResolveModeCaseName(resolveMode).c_str(), "Depth/stencil resolve mode")); 5048 5049 for (const bool renderToWholeFramebuffer : boolRange) 5050 { 5051 TestParams testParams; 5052 deMemset(&testParams, 0, sizeof(testParams)); 5053 5054 testParams.pipelineConstructionType = pipelineConstructionType; 5055 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5056 testParams.floatColor1Format = color1Format; 5057 testParams.floatColor2Format = color2Format; 5058 testParams.intColorFormat = color3Format; 5059 testParams.depthStencilFormat = depthStencilFormat; 5060 testParams.dynamicRendering = dynamicRendering; 5061 testParams.useGarbageAttachment = false; 5062 5063 generateBasicTest(rng, testParams, sampleCount, resolveMode, renderToWholeFramebuffer); 5064 5065 addFunctionCaseWithPrograms( 5066 resolveGroup.get(), 5067 renderToWholeFramebuffer ? "whole_framebuffer" : "sub_framebuffer", 5068 checkRequirements, 5069 initBasicPrograms, 5070 testBasic, 5071 testParams); 5072 } 5073 5074 sampleGroup->addChild(resolveGroup.release()); 5075 } 5076 formatGroup->addChild(sampleGroup.release()); 5077 } 5078 group->addChild(formatGroup.release()); 5079 } 5080 5081 rootGroup->addChild(group.release()); 5082 } 5083 5084 // Test 2: Test that vkCmdClearAttachments works. 5085 { 5086 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "clear_attachments")); 5087 5088 de::Random rng(0x0FEDCBA9); 5089 5090 for (const VkFormat color1Format : color1FormatRange) 5091 for (const VkFormat color2Format : color2FormatRange) 5092 for (const VkFormat color3Format : color3FormatRange) 5093 for (const VkFormat depthStencilFormat : depthStencilFormatRange) 5094 { 5095 MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup( 5096 rootGroup->getTestContext(), getFormatCaseName(color1Format, color2Format, color3Format, depthStencilFormat).c_str(), "Combination of framebuffer attachment formats")); 5097 5098 for (const VkSampleCountFlagBits sampleCount : sampleRange) 5099 { 5100 MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup( 5101 rootGroup->getTestContext(), getSampleCountCaseName(sampleCount).c_str(), "Sample count")); 5102 5103 for (const VkResolveModeFlagBits resolveMode : depthStencilResolveModeRange) 5104 { 5105 MovePtr<tcu::TestCaseGroup> resolveGroup(new tcu::TestCaseGroup( 5106 rootGroup->getTestContext(), getResolveModeCaseName(resolveMode).c_str(), "Depth/stencil resolve mode")); 5107 5108 for (const bool renderToWholeFramebuffer : boolRange) 5109 { 5110 TestParams testParams; 5111 deMemset(&testParams, 0, sizeof(testParams)); 5112 5113 testParams.pipelineConstructionType = pipelineConstructionType; 5114 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5115 testParams.floatColor1Format = color1Format; 5116 testParams.floatColor2Format = color2Format; 5117 testParams.intColorFormat = color3Format; 5118 testParams.depthStencilFormat = depthStencilFormat; 5119 testParams.dynamicRendering = dynamicRendering; 5120 testParams.useGarbageAttachment = false; 5121 5122 generateBasicTest(rng, testParams, sampleCount, resolveMode, renderToWholeFramebuffer); 5123 5124 addFunctionCaseWithPrograms( 5125 resolveGroup.get(), 5126 renderToWholeFramebuffer ? "whole_framebuffer" : "sub_framebuffer", 5127 checkRequirements, 5128 initBasicPrograms, 5129 testClearAttachments, 5130 testParams); 5131 } 5132 sampleGroup->addChild(resolveGroup.release()); 5133 } 5134 formatGroup->addChild(sampleGroup.release()); 5135 } 5136 group->addChild(formatGroup.release()); 5137 } 5138 5139 rootGroup->addChild(group.release()); 5140 } 5141 5142 // Test 3: Tests with a single render pass, potentially with multiple subpasses. 5143 // Multiple subpasses can't be tested with dynamic rendering. 5144 if (!dynamicRendering) 5145 { 5146 // Single render pass with multiple subpasses 5147 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "multi_subpass")); 5148 MovePtr<tcu::TestCaseGroup> formatGroup[color1FormatCount][color2FormatCount][color3FormatCount][depthStencilFormatCount]; 5149 5150 for (deUint32 color1FormatNdx = 0; color1FormatNdx < color1FormatCount; ++color1FormatNdx) 5151 for (deUint32 color2FormatNdx = 0; color2FormatNdx < color2FormatCount; ++color2FormatNdx) 5152 for (deUint32 color3FormatNdx = 0; color3FormatNdx < color3FormatCount; ++color3FormatNdx) 5153 for (deUint32 depthStencilFormatNdx = 0; depthStencilFormatNdx < depthStencilFormatCount; ++depthStencilFormatNdx) 5154 { 5155 formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx] = MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup( 5156 rootGroup->getTestContext(), getFormatCaseName(color1FormatRange[color1FormatNdx], 5157 color2FormatRange[color2FormatNdx], 5158 color3FormatRange[color3FormatNdx], 5159 depthStencilFormatRange[depthStencilFormatNdx]).c_str(), 5160 "Combination of framebuffer attachment formats")); 5161 } 5162 5163 de::Random rng(0x12345678); 5164 5165 for (deUint32 iteration = 0; iteration < (isMultisampledRenderToSingleSampled ? 1000 : 250); ++iteration) 5166 { 5167 TestParams testParams; 5168 deMemset(&testParams, 0, sizeof(testParams)); 5169 5170 const deUint32 color1FormatNdx = iteration % color1FormatCount; 5171 const deUint32 color2FormatNdx = iteration % color2FormatCount; 5172 const deUint32 color3FormatNdx = iteration % color3FormatCount; 5173 const deUint32 depthStencilFormatNdx = iteration % depthStencilFormatCount; 5174 5175 testParams.pipelineConstructionType = pipelineConstructionType; 5176 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5177 testParams.floatColor1Format = color1FormatRange[color1FormatNdx]; 5178 testParams.floatColor2Format = color2FormatRange[color2FormatNdx]; 5179 testParams.intColorFormat = color3FormatRange[color3FormatNdx]; 5180 testParams.depthStencilFormat = depthStencilFormatRange[depthStencilFormatNdx]; 5181 testParams.dynamicRendering = false; 5182 testParams.useGarbageAttachment = false; 5183 5184 generateMultiPassTest(rng, testParams); 5185 5186 std::ostringstream name; 5187 name << "random_" << iteration; 5188 5189 addFunctionCaseWithPrograms( 5190 formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx].get(), 5191 name.str().c_str(), 5192 checkRequirements, 5193 initMultipassPrograms, 5194 testSingleRenderPass, 5195 testParams); 5196 } 5197 5198 for (deUint32 color1FormatNdx = 0; color1FormatNdx < color1FormatCount; ++color1FormatNdx) 5199 for (deUint32 color2FormatNdx = 0; color2FormatNdx < color2FormatCount; ++color2FormatNdx) 5200 for (deUint32 color3FormatNdx = 0; color3FormatNdx < color3FormatCount; ++color3FormatNdx) 5201 for (deUint32 depthStencilFormatNdx = 0; depthStencilFormatNdx < depthStencilFormatCount; ++depthStencilFormatNdx) 5202 { 5203 group->addChild(formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx].release()); 5204 } 5205 5206 rootGroup->addChild(group.release()); 5207 } 5208 5209 // Test 4: Tests with a multiple render passes, a single subpass each. 5210 { 5211 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "multi_renderpass")); 5212 MovePtr<tcu::TestCaseGroup> formatGroup[color1FormatCount][color2FormatCount][color3FormatCount][depthStencilFormatCount]; 5213 5214 for (deUint32 color1FormatNdx = 0; color1FormatNdx < color1FormatCount; ++color1FormatNdx) 5215 for (deUint32 color2FormatNdx = 0; color2FormatNdx < color2FormatCount; ++color2FormatNdx) 5216 for (deUint32 color3FormatNdx = 0; color3FormatNdx < color3FormatCount; ++color3FormatNdx) 5217 for (deUint32 depthStencilFormatNdx = 0; depthStencilFormatNdx < depthStencilFormatCount; ++depthStencilFormatNdx) 5218 { 5219 formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx] = MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup( 5220 rootGroup->getTestContext(), getFormatCaseName(color1FormatRange[color1FormatNdx], 5221 color2FormatRange[color2FormatNdx], 5222 color3FormatRange[color3FormatNdx], 5223 depthStencilFormatRange[depthStencilFormatNdx]).c_str(), 5224 "Combination of framebuffer attachment formats")); 5225 } 5226 5227 de::Random rng(0x87654321); 5228 5229 for (deUint32 iteration = 0; iteration < (isMultisampledRenderToSingleSampled ? 1000 : 250); ++iteration) 5230 { 5231 TestParams testParams; 5232 deMemset(&testParams, 0, sizeof(testParams)); 5233 5234 const deUint32 color1FormatNdx = iteration % color1FormatCount; 5235 const deUint32 color2FormatNdx = iteration % color2FormatCount; 5236 const deUint32 color3FormatNdx = iteration % color3FormatCount; 5237 const deUint32 depthStencilFormatNdx = iteration % depthStencilFormatCount; 5238 5239 testParams.pipelineConstructionType = pipelineConstructionType; 5240 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5241 testParams.floatColor1Format = color1FormatRange[color1FormatNdx]; 5242 testParams.floatColor2Format = color2FormatRange[color2FormatNdx]; 5243 testParams.intColorFormat = color3FormatRange[color3FormatNdx]; 5244 testParams.depthStencilFormat = depthStencilFormatRange[depthStencilFormatNdx]; 5245 testParams.dynamicRendering = dynamicRendering; 5246 testParams.useGarbageAttachment = false; 5247 5248 generateMultiPassTest(rng, testParams); 5249 5250 std::ostringstream name; 5251 name << "random_" << iteration; 5252 5253 addFunctionCaseWithPrograms( 5254 formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx].get(), 5255 name.str().c_str(), 5256 checkRequirements, 5257 initMultipassPrograms, 5258 testMultiRenderPass, 5259 testParams); 5260 } 5261 5262 for (deUint32 color1FormatNdx = 0; color1FormatNdx < color1FormatCount; ++color1FormatNdx) 5263 for (deUint32 color2FormatNdx = 0; color2FormatNdx < color2FormatCount; ++color2FormatNdx) 5264 for (deUint32 color3FormatNdx = 0; color3FormatNdx < color3FormatCount; ++color3FormatNdx) 5265 for (deUint32 depthStencilFormatNdx = 0; depthStencilFormatNdx < depthStencilFormatCount; ++depthStencilFormatNdx) 5266 { 5267 group->addChild(formatGroup[color1FormatNdx][color2FormatNdx][color3FormatNdx][depthStencilFormatNdx].release()); 5268 } 5269 5270 rootGroup->addChild(group.release()); 5271 } 5272 5273 // Test 5: Tests multisampled rendering followed by use as input attachment. 5274 // These tests have two subpasses, so these can't be tested with dynamic rendering. 5275 if (!dynamicRendering && !vk::isConstructionTypeShaderObject(pipelineConstructionType)) 5276 { 5277 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "input_attachments", "Tests that input attachment interaction with multisampled rendering works")); 5278 5279 de::Random rng(0x18273645); 5280 5281 for (const VkFormat color1Format : color1FormatRange) 5282 for (const VkFormat color2Format : color2FormatRange) 5283 for (const VkFormat color3Format : color3FormatRange) 5284 for (const VkFormat depthStencilFormat : depthStencilFormatRange) 5285 { 5286 MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup( 5287 rootGroup->getTestContext(), getFormatCaseName(color1Format, color2Format, color3Format, depthStencilFormat).c_str(), "Combination of framebuffer attachment formats")); 5288 5289 for (const VkSampleCountFlagBits sampleCount : sampleRange) 5290 { 5291 MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup( 5292 rootGroup->getTestContext(), getSampleCountCaseName(sampleCount).c_str(), "Sample count")); 5293 5294 for (const VkResolveModeFlagBits resolveMode : depthStencilResolveModeRange) 5295 { 5296 MovePtr<tcu::TestCaseGroup> resolveGroup(new tcu::TestCaseGroup( 5297 rootGroup->getTestContext(), getResolveModeCaseName(resolveMode).c_str(), "Depth/stencil resolve mode")); 5298 5299 for (const bool renderToWholeFramebuffer : boolRange) 5300 { 5301 TestParams testParams; 5302 deMemset(&testParams, 0, sizeof(testParams)); 5303 5304 testParams.pipelineConstructionType = pipelineConstructionType; 5305 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5306 testParams.floatColor1Format = color1Format; 5307 testParams.floatColor2Format = color2Format; 5308 testParams.intColorFormat = color3Format; 5309 testParams.depthStencilFormat = depthStencilFormat; 5310 testParams.dynamicRendering = false; 5311 testParams.useGarbageAttachment = false; 5312 5313 generateInputAttachmentsTest(rng, testParams, sampleCount, resolveMode, renderToWholeFramebuffer); 5314 5315 addFunctionCaseWithPrograms( 5316 resolveGroup.get(), 5317 renderToWholeFramebuffer ? "whole_framebuffer" : "sub_framebuffer", 5318 checkRequirements, 5319 initInputAttachmentsPrograms, 5320 testInputAttachments, 5321 testParams); 5322 } 5323 sampleGroup->addChild(resolveGroup.release()); 5324 } 5325 formatGroup->addChild(sampleGroup.release()); 5326 } 5327 group->addChild(formatGroup.release()); 5328 } 5329 5330 rootGroup->addChild(group.release()); 5331 } 5332 5333 5334 // Test 6: Tests subpass resolve efficiency query. 5335 // Efficiency query tests don't need to be tested with different pipeline construction types and with dynamic rendering. 5336 if (isMultisampledRenderToSingleSampled && pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC && !dynamicRendering) 5337 { 5338 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "subpass_resolve_efficiency_query", "Tests that subpass resolve efficiency performance query works")); 5339 5340 for (const VkFormat format : color1FormatRange) 5341 { 5342 addFunctionCase( 5343 group.get(), 5344 getFormatShortString(format), 5345 checkHasMsrtss, 5346 testPerfQuery, 5347 format); 5348 } 5349 5350 for (const VkFormat format : color2FormatRange) 5351 { 5352 addFunctionCase( 5353 group.get(), 5354 getFormatShortString(format), 5355 checkHasMsrtss, 5356 testPerfQuery, 5357 format); 5358 } 5359 5360 for (const VkFormat format : color3FormatRange) 5361 { 5362 addFunctionCase( 5363 group.get(), 5364 getFormatShortString(format), 5365 checkHasMsrtss, 5366 testPerfQuery, 5367 format); 5368 } 5369 5370 for (const VkFormat format : depthStencilFormatRange) 5371 { 5372 addFunctionCase( 5373 group.get(), 5374 getFormatShortString(format), 5375 checkHasMsrtss, 5376 testPerfQuery, 5377 format); 5378 } 5379 5380 rootGroup->addChild(group.release()); 5381 } 5382 5383 // Test 7: Test that work with garbage color attachments 5384 if (dynamicRendering && pipelineConstructionType != vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) 5385 { 5386 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(rootGroup->getTestContext(), "garbage_color_attachment", "Tests that work with garbage color attachments")); 5387 5388 de::Random rng(0x12348765); 5389 5390 for (const VkFormat color1Format : color1FormatRange) 5391 for (const VkFormat color2Format : color2FormatRange) 5392 for (const VkFormat color3Format : color3FormatRange) 5393 for (const VkFormat depthStencilFormat : depthStencilFormatRange) 5394 { 5395 TestParams testParams; 5396 deMemset(&testParams, 0, sizeof(testParams)); 5397 5398 testParams.pipelineConstructionType = pipelineConstructionType; 5399 testParams.isMultisampledRenderToSingleSampled = isMultisampledRenderToSingleSampled; 5400 testParams.floatColor1Format = color1Format; 5401 testParams.floatColor2Format = color2Format; 5402 testParams.intColorFormat = color3Format; 5403 testParams.depthStencilFormat = depthStencilFormat; 5404 testParams.dynamicRendering = dynamicRendering; 5405 testParams.useGarbageAttachment = true; 5406 5407 generateBasicTest(rng, testParams, VK_SAMPLE_COUNT_2_BIT, VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, DE_TRUE); 5408 5409 // Combination of framebuffer attachment formats 5410 addFunctionCaseWithPrograms( 5411 group.get(), 5412 getFormatCaseName(color1Format, color2Format, color3Format, depthStencilFormat).c_str(), 5413 checkRequirements, 5414 initBasicPrograms, 5415 testBasic, 5416 testParams); 5417 } 5418 5419 rootGroup->addChild(group.release()); 5420 } 5421} 5422 5423void createMultisampledRenderToSingleSampledTestsInGroup (tcu::TestCaseGroup* rootGroup, PipelineConstructionType pipelineConstructionType) 5424{ 5425 createMultisampledTestsInGroup(rootGroup, true, pipelineConstructionType, false); 5426 5427 MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), "dynamic_rendering", "Multisampled rendering to single-sampled tests with dynamic rendering")); 5428 createMultisampledTestsInGroup(dynamicRenderingGroup.get(), true, pipelineConstructionType, true); 5429 rootGroup->addChild(dynamicRenderingGroup.release()); 5430} 5431 5432void createMultisampledMiscTestsInGroup (tcu::TestCaseGroup* rootGroup, PipelineConstructionType pipelineConstructionType) 5433{ 5434 createMultisampledTestsInGroup(rootGroup, false, pipelineConstructionType, false); 5435 5436 MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), "dynamic_rendering", "Miscellaneous multisampled rendering tests with dynamic rendering")); 5437 createMultisampledTestsInGroup(dynamicRenderingGroup.get(), false, pipelineConstructionType, true); 5438 rootGroup->addChild(dynamicRenderingGroup.release()); 5439} 5440 5441} // anonymous ns 5442 5443tcu::TestCaseGroup* createMultisampledRenderToSingleSampledTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType) 5444{ 5445 // Test multisampled rendering to single-sampled framebuffer attachments 5446 return createTestGroup(testCtx, "multisampled_render_to_single_sampled", createMultisampledRenderToSingleSampledTestsInGroup, pipelineConstructionType); 5447} 5448 5449tcu::TestCaseGroup* createMultisampledMiscTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType) 5450{ 5451 return createTestGroup(testCtx, "misc", createMultisampledMiscTestsInGroup, pipelineConstructionType); 5452} 5453 5454} // pipeline 5455} // vkt 5456