1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief RenderPass tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktRenderPassTests.hpp" 25 26 #include "vktRenderPassMultisampleTests.hpp" 27 #include "vktRenderPassMultisampleResolveTests.hpp" 28 29 #include "vktTestCaseUtil.hpp" 30 #include "vktTestGroupUtil.hpp" 31 32 #include "vkDefs.hpp" 33 #include "vkDeviceUtil.hpp" 34 #include "vkImageUtil.hpp" 35 #include "vkMemUtil.hpp" 36 #include "vkPlatform.hpp" 37 #include "vkPrograms.hpp" 38 #include "vkQueryUtil.hpp" 39 #include "vkRef.hpp" 40 #include "vkRefUtil.hpp" 41 #include "vkStrUtil.hpp" 42 #include "vkTypeUtil.hpp" 43 44 #include "tcuFloat.hpp" 45 #include "tcuFormatUtil.hpp" 46 #include "tcuMaybe.hpp" 47 #include "tcuResultCollector.hpp" 48 #include "tcuTestLog.hpp" 49 #include "tcuTextureUtil.hpp" 50 #include "tcuVectorUtil.hpp" 51 52 #include "deRandom.hpp" 53 #include "deSTLUtil.hpp" 54 #include "deSharedPtr.hpp" 55 #include "deStringUtil.hpp" 56 #include "deUniquePtr.hpp" 57 58 #include <limits> 59 #include <set> 60 #include <string> 61 #include <vector> 62 63 using namespace vk; 64 65 using tcu::BVec4; 66 using tcu::IVec2; 67 using tcu::IVec4; 68 using tcu::UVec2; 69 using tcu::UVec4; 70 using tcu::Vec2; 71 using tcu::Vec4; 72 73 using tcu::Maybe; 74 using tcu::just; 75 using tcu::nothing; 76 77 using tcu::ConstPixelBufferAccess; 78 using tcu::PixelBufferAccess; 79 80 using tcu::TestLog; 81 82 using de::UniquePtr; 83 84 using std::pair; 85 using std::set; 86 using std::string; 87 using std::vector; 88 89 namespace vkt 90 { 91 namespace 92 { 93 enum AllocationKind 94 { 95 ALLOCATION_KIND_SUBALLOCATED, 96 ALLOCATION_KIND_DEDICATED, 97 }; 98 99 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki, 100 const DeviceInterface& vkd, 101 const VkPhysicalDevice& physDevice, 102 const VkDevice device, 103 const VkBuffer& buffer, 104 const MemoryRequirement requirement, 105 Allocator& allocator, 106 AllocationKind allocationKind) 107 { 108 switch (allocationKind) 109 { 110 case ALLOCATION_KIND_SUBALLOCATED: 111 { 112 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer); 113 114 return allocator.allocate(memoryRequirements, requirement); 115 } 116 117 case ALLOCATION_KIND_DEDICATED: 118 { 119 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement); 120 } 121 122 default: 123 { 124 TCU_THROW(InternalError, "Invalid allocation kind"); 125 } 126 } 127 } 128 129 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki, 130 const DeviceInterface& vkd, 131 const VkPhysicalDevice& physDevice, 132 const VkDevice device, 133 const VkImage& image, 134 const MemoryRequirement requirement, 135 Allocator& allocator, 136 AllocationKind allocationKind) 137 { 138 switch (allocationKind) 139 { 140 case ALLOCATION_KIND_SUBALLOCATED: 141 { 142 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image); 143 144 return allocator.allocate(memoryRequirements, requirement); 145 } 146 147 case ALLOCATION_KIND_DEDICATED: 148 { 149 return allocateDedicated(vki, vkd, physDevice, device, image, requirement); 150 } 151 152 default: 153 { 154 TCU_THROW(InternalError, "Invalid allocation kind"); 155 } 156 } 157 } 158 159 enum BoolOp 160 { 161 BOOLOP_AND, 162 BOOLOP_OR, 163 BOOLOP_EQ, 164 BOOLOP_NEQ 165 }; 166 167 const char* boolOpToString (BoolOp op) 168 { 169 switch (op) 170 { 171 case BOOLOP_OR: 172 return "||"; 173 174 case BOOLOP_AND: 175 return "&&"; 176 177 case BOOLOP_EQ: 178 return "=="; 179 180 case BOOLOP_NEQ: 181 return "!="; 182 183 default: 184 DE_FATAL("Unknown boolean operation."); 185 return DE_NULL; 186 } 187 } 188 189 bool performBoolOp (BoolOp op, bool a, bool b) 190 { 191 switch (op) 192 { 193 case BOOLOP_OR: 194 return a || b; 195 196 case BOOLOP_AND: 197 return a && b; 198 199 case BOOLOP_EQ: 200 return a == b; 201 202 case BOOLOP_NEQ: 203 return a != b; 204 205 default: 206 DE_FATAL("Unknown boolean operation."); 207 return false; 208 } 209 } 210 211 BoolOp boolOpFromIndex (size_t index) 212 { 213 const BoolOp ops[] = 214 { 215 BOOLOP_OR, 216 BOOLOP_AND, 217 BOOLOP_EQ, 218 BOOLOP_NEQ 219 }; 220 221 return ops[index % DE_LENGTH_OF_ARRAY(ops)]; 222 } 223 224 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk, 225 VkDevice device, 226 VkFramebufferCreateFlags pCreateInfo_flags, 227 VkRenderPass pCreateInfo_renderPass, 228 deUint32 pCreateInfo_attachmentCount, 229 const VkImageView* pCreateInfo_pAttachments, 230 deUint32 pCreateInfo_width, 231 deUint32 pCreateInfo_height, 232 deUint32 pCreateInfo_layers) 233 { 234 const VkFramebufferCreateInfo pCreateInfo = 235 { 236 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 237 DE_NULL, 238 pCreateInfo_flags, 239 pCreateInfo_renderPass, 240 pCreateInfo_attachmentCount, 241 pCreateInfo_pAttachments, 242 pCreateInfo_width, 243 pCreateInfo_height, 244 pCreateInfo_layers, 245 }; 246 return createFramebuffer(vk, device, &pCreateInfo); 247 } 248 249 Move<VkImage> createImage (const DeviceInterface& vk, 250 VkDevice device, 251 VkImageCreateFlags pCreateInfo_flags, 252 VkImageType pCreateInfo_imageType, 253 VkFormat pCreateInfo_format, 254 VkExtent3D pCreateInfo_extent, 255 deUint32 pCreateInfo_mipLevels, 256 deUint32 pCreateInfo_arrayLayers, 257 VkSampleCountFlagBits pCreateInfo_samples, 258 VkImageTiling pCreateInfo_tiling, 259 VkImageUsageFlags pCreateInfo_usage, 260 VkSharingMode pCreateInfo_sharingMode, 261 deUint32 pCreateInfo_queueFamilyCount, 262 const deUint32* pCreateInfo_pQueueFamilyIndices, 263 VkImageLayout pCreateInfo_initialLayout) 264 { 265 const VkImageCreateInfo pCreateInfo = 266 { 267 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 268 DE_NULL, 269 pCreateInfo_flags, 270 pCreateInfo_imageType, 271 pCreateInfo_format, 272 pCreateInfo_extent, 273 pCreateInfo_mipLevels, 274 pCreateInfo_arrayLayers, 275 pCreateInfo_samples, 276 pCreateInfo_tiling, 277 pCreateInfo_usage, 278 pCreateInfo_sharingMode, 279 pCreateInfo_queueFamilyCount, 280 pCreateInfo_pQueueFamilyIndices, 281 pCreateInfo_initialLayout 282 }; 283 return createImage(vk, device, &pCreateInfo); 284 } 285 286 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset) 287 { 288 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset)); 289 } 290 291 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset) 292 { 293 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset)); 294 } 295 296 Move<VkImageView> createImageView (const DeviceInterface& vk, 297 VkDevice device, 298 VkImageViewCreateFlags pCreateInfo_flags, 299 VkImage pCreateInfo_image, 300 VkImageViewType pCreateInfo_viewType, 301 VkFormat pCreateInfo_format, 302 VkComponentMapping pCreateInfo_components, 303 VkImageSubresourceRange pCreateInfo_subresourceRange) 304 { 305 const VkImageViewCreateInfo pCreateInfo = 306 { 307 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 308 DE_NULL, 309 pCreateInfo_flags, 310 pCreateInfo_image, 311 pCreateInfo_viewType, 312 pCreateInfo_format, 313 pCreateInfo_components, 314 pCreateInfo_subresourceRange, 315 }; 316 return createImageView(vk, device, &pCreateInfo); 317 } 318 319 Move<VkBuffer> createBuffer (const DeviceInterface& vk, 320 VkDevice device, 321 VkBufferCreateFlags pCreateInfo_flags, 322 VkDeviceSize pCreateInfo_size, 323 VkBufferUsageFlags pCreateInfo_usage, 324 VkSharingMode pCreateInfo_sharingMode, 325 deUint32 pCreateInfo_queueFamilyCount, 326 const deUint32* pCreateInfo_pQueueFamilyIndices) 327 { 328 const VkBufferCreateInfo pCreateInfo = 329 { 330 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 331 DE_NULL, 332 pCreateInfo_flags, 333 pCreateInfo_size, 334 pCreateInfo_usage, 335 pCreateInfo_sharingMode, 336 pCreateInfo_queueFamilyCount, 337 pCreateInfo_pQueueFamilyIndices, 338 }; 339 return createBuffer(vk, device, &pCreateInfo); 340 } 341 342 void cmdBeginRenderPass (const DeviceInterface& vk, 343 VkCommandBuffer cmdBuffer, 344 VkRenderPass pRenderPassBegin_renderPass, 345 VkFramebuffer pRenderPassBegin_framebuffer, 346 VkRect2D pRenderPassBegin_renderArea, 347 deUint32 pRenderPassBegin_clearValueCount, 348 const VkClearValue* pRenderPassBegin_pAttachmentClearValues, 349 VkSubpassContents contents) 350 { 351 const VkRenderPassBeginInfo pRenderPassBegin = 352 { 353 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 354 DE_NULL, 355 pRenderPassBegin_renderPass, 356 pRenderPassBegin_framebuffer, 357 pRenderPassBegin_renderArea, 358 pRenderPassBegin_clearValueCount, 359 pRenderPassBegin_pAttachmentClearValues, 360 }; 361 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents); 362 } 363 364 void beginCommandBuffer (const DeviceInterface& vk, 365 VkCommandBuffer cmdBuffer, 366 VkCommandBufferUsageFlags pBeginInfo_flags, 367 VkRenderPass pInheritanceInfo_renderPass, 368 deUint32 pInheritanceInfo_subpass, 369 VkFramebuffer pInheritanceInfo_framebuffer, 370 VkBool32 pInheritanceInfo_occlusionQueryEnable, 371 VkQueryControlFlags pInheritanceInfo_queryFlags, 372 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics) 373 { 374 const VkCommandBufferInheritanceInfo pInheritanceInfo = 375 { 376 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 377 DE_NULL, 378 pInheritanceInfo_renderPass, 379 pInheritanceInfo_subpass, 380 pInheritanceInfo_framebuffer, 381 pInheritanceInfo_occlusionQueryEnable, 382 pInheritanceInfo_queryFlags, 383 pInheritanceInfo_pipelineStatistics, 384 }; 385 const VkCommandBufferBeginInfo pBeginInfo = 386 { 387 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 388 DE_NULL, 389 pBeginInfo_flags, 390 &pInheritanceInfo, 391 }; 392 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo)); 393 } 394 395 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer) 396 { 397 VK_CHECK(vk.endCommandBuffer(cmdBuffer)); 398 } 399 400 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence) 401 { 402 const VkSubmitInfo submitInfo = 403 { 404 VK_STRUCTURE_TYPE_SUBMIT_INFO, 405 DE_NULL, 406 0u, // waitSemaphoreCount 407 (const VkSemaphore*)DE_NULL, // pWaitSemaphores 408 (const VkPipelineStageFlags*)DE_NULL, 409 cmdBufferCount, // commandBufferCount 410 pCmdBuffers, 411 0u, // signalSemaphoreCount 412 (const VkSemaphore*)DE_NULL, // pSignalSemaphores 413 }; 414 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence)); 415 } 416 417 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout) 418 { 419 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout)); 420 } 421 422 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat) 423 { 424 const tcu::TextureFormat format = mapVkFormat(vkFormat); 425 426 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21); 427 428 switch (format.order) 429 { 430 case tcu::TextureFormat::DS: 431 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; 432 433 case tcu::TextureFormat::D: 434 return VK_IMAGE_ASPECT_DEPTH_BIT; 435 436 case tcu::TextureFormat::S: 437 return VK_IMAGE_ASPECT_STENCIL_BIT; 438 439 default: 440 return VK_IMAGE_ASPECT_COLOR_BIT; 441 } 442 } 443 444 VkAccessFlags getAllMemoryReadFlags (void) 445 { 446 return VK_ACCESS_TRANSFER_READ_BIT 447 | VK_ACCESS_UNIFORM_READ_BIT 448 | VK_ACCESS_HOST_READ_BIT 449 | VK_ACCESS_INDEX_READ_BIT 450 | VK_ACCESS_SHADER_READ_BIT 451 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT 452 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT 453 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT 454 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT 455 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 456 } 457 458 VkAccessFlags getAllMemoryWriteFlags (void) 459 { 460 return VK_ACCESS_TRANSFER_WRITE_BIT 461 | VK_ACCESS_HOST_WRITE_BIT 462 | VK_ACCESS_SHADER_WRITE_BIT 463 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT 464 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 465 } 466 467 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout) 468 { 469 switch (layout) 470 { 471 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags(); 472 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 473 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 474 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 475 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT; 476 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT; 477 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT; 478 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT; 479 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT; 480 default: 481 return (VkAccessFlags)0; 482 } 483 } 484 485 VkPipelineStageFlags getAllPipelineStageFlags (void) 486 { 487 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT 488 | VK_PIPELINE_STAGE_TRANSFER_BIT 489 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT 490 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT 491 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT 492 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT 493 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT 494 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 495 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT 496 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 497 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT 498 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 499 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; 500 } 501 502 class AttachmentReference 503 { 504 public: 505 AttachmentReference (deUint32 attachment, 506 VkImageLayout layout) 507 : m_attachment (attachment) 508 , m_layout (layout) 509 { 510 } 511 512 deUint32 getAttachment (void) const { return m_attachment; } 513 VkImageLayout getImageLayout (void) const { return m_layout; } 514 515 private: 516 deUint32 m_attachment; 517 VkImageLayout m_layout; 518 }; 519 520 class Subpass 521 { 522 public: 523 Subpass (VkPipelineBindPoint pipelineBindPoint, 524 VkSubpassDescriptionFlags flags, 525 const vector<AttachmentReference>& inputAttachments, 526 const vector<AttachmentReference>& colorAttachments, 527 const vector<AttachmentReference>& resolveAttachments, 528 AttachmentReference depthStencilAttachment, 529 const vector<deUint32>& preserveAttachments) 530 : m_pipelineBindPoint (pipelineBindPoint) 531 , m_flags (flags) 532 , m_inputAttachments (inputAttachments) 533 , m_colorAttachments (colorAttachments) 534 , m_resolveAttachments (resolveAttachments) 535 , m_depthStencilAttachment (depthStencilAttachment) 536 , m_preserveAttachments (preserveAttachments) 537 { 538 } 539 540 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; } 541 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; } 542 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; } 543 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; } 544 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; } 545 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; } 546 const vector<deUint32>& getPreserveAttachments (void) const { return m_preserveAttachments; } 547 548 private: 549 VkPipelineBindPoint m_pipelineBindPoint; 550 VkSubpassDescriptionFlags m_flags; 551 552 vector<AttachmentReference> m_inputAttachments; 553 vector<AttachmentReference> m_colorAttachments; 554 vector<AttachmentReference> m_resolveAttachments; 555 AttachmentReference m_depthStencilAttachment; 556 557 vector<deUint32> m_preserveAttachments; 558 }; 559 560 class SubpassDependency 561 { 562 public: 563 SubpassDependency (deUint32 srcPass, 564 deUint32 dstPass, 565 566 VkPipelineStageFlags srcStageMask, 567 VkPipelineStageFlags dstStageMask, 568 569 VkAccessFlags outputMask, 570 VkAccessFlags inputMask, 571 572 VkDependencyFlags flags) 573 : m_srcPass (srcPass) 574 , m_dstPass (dstPass) 575 576 , m_srcStageMask (srcStageMask) 577 , m_dstStageMask (dstStageMask) 578 579 , m_outputMask (outputMask) 580 , m_inputMask (inputMask) 581 , m_flags (flags) 582 { 583 } 584 585 deUint32 getSrcPass (void) const { return m_srcPass; } 586 deUint32 getDstPass (void) const { return m_dstPass; } 587 588 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; } 589 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; } 590 591 VkAccessFlags getOutputMask (void) const { return m_outputMask; } 592 VkAccessFlags getInputMask (void) const { return m_inputMask; } 593 594 VkDependencyFlags getFlags (void) const { return m_flags; } 595 596 private: 597 deUint32 m_srcPass; 598 deUint32 m_dstPass; 599 600 VkPipelineStageFlags m_srcStageMask; 601 VkPipelineStageFlags m_dstStageMask; 602 603 VkAccessFlags m_outputMask; 604 VkAccessFlags m_inputMask; 605 VkDependencyFlags m_flags; 606 }; 607 608 class Attachment 609 { 610 public: 611 Attachment (VkFormat format, 612 VkSampleCountFlagBits samples, 613 614 VkAttachmentLoadOp loadOp, 615 VkAttachmentStoreOp storeOp, 616 617 VkAttachmentLoadOp stencilLoadOp, 618 VkAttachmentStoreOp stencilStoreOp, 619 620 VkImageLayout initialLayout, 621 VkImageLayout finalLayout) 622 : m_format (format) 623 , m_samples (samples) 624 625 , m_loadOp (loadOp) 626 , m_storeOp (storeOp) 627 628 , m_stencilLoadOp (stencilLoadOp) 629 , m_stencilStoreOp (stencilStoreOp) 630 631 , m_initialLayout (initialLayout) 632 , m_finalLayout (finalLayout) 633 { 634 } 635 636 VkFormat getFormat (void) const { return m_format; } 637 VkSampleCountFlagBits getSamples (void) const { return m_samples; } 638 639 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; } 640 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; } 641 642 643 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; } 644 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; } 645 646 VkImageLayout getInitialLayout (void) const { return m_initialLayout; } 647 VkImageLayout getFinalLayout (void) const { return m_finalLayout; } 648 649 private: 650 VkFormat m_format; 651 VkSampleCountFlagBits m_samples; 652 653 VkAttachmentLoadOp m_loadOp; 654 VkAttachmentStoreOp m_storeOp; 655 656 VkAttachmentLoadOp m_stencilLoadOp; 657 VkAttachmentStoreOp m_stencilStoreOp; 658 659 VkImageLayout m_initialLayout; 660 VkImageLayout m_finalLayout; 661 }; 662 663 class RenderPass 664 { 665 public: 666 RenderPass (const vector<Attachment>& attachments, 667 const vector<Subpass>& subpasses, 668 const vector<SubpassDependency>& dependencies, 669 const vector<VkInputAttachmentAspectReferenceKHR> inputAspects = vector<VkInputAttachmentAspectReferenceKHR>()) 670 : m_attachments (attachments) 671 , m_subpasses (subpasses) 672 , m_dependencies (dependencies) 673 , m_inputAspects (inputAspects) 674 { 675 } 676 677 const vector<Attachment>& getAttachments (void) const { return m_attachments; } 678 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; } 679 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; } 680 const vector<VkInputAttachmentAspectReferenceKHR> getInputAspects (void) const { return m_inputAspects; } 681 682 private: 683 const vector<Attachment> m_attachments; 684 const vector<Subpass> m_subpasses; 685 const vector<SubpassDependency> m_dependencies; 686 const vector<VkInputAttachmentAspectReferenceKHR> m_inputAspects; 687 }; 688 689 struct TestConfig 690 { 691 enum RenderTypes 692 { 693 RENDERTYPES_NONE = 0, 694 RENDERTYPES_CLEAR = (1<<1), 695 RENDERTYPES_DRAW = (1<<2) 696 }; 697 698 enum CommandBufferTypes 699 { 700 COMMANDBUFFERTYPES_INLINE = (1<<0), 701 COMMANDBUFFERTYPES_SECONDARY = (1<<1) 702 }; 703 704 enum ImageMemory 705 { 706 IMAGEMEMORY_STRICT = (1<<0), 707 IMAGEMEMORY_LAZY = (1<<1) 708 }; 709 710 TestConfig (const RenderPass& renderPass_, 711 RenderTypes renderTypes_, 712 CommandBufferTypes commandBufferTypes_, 713 ImageMemory imageMemory_, 714 const UVec2& targetSize_, 715 const UVec2& renderPos_, 716 const UVec2& renderSize_, 717 deUint32 seed_, 718 AllocationKind allocationKind_) 719 : renderPass (renderPass_) 720 , renderTypes (renderTypes_) 721 , commandBufferTypes (commandBufferTypes_) 722 , imageMemory (imageMemory_) 723 , targetSize (targetSize_) 724 , renderPos (renderPos_) 725 , renderSize (renderSize_) 726 , seed (seed_) 727 , allocationKind (allocationKind_) 728 { 729 } 730 731 RenderPass renderPass; 732 RenderTypes renderTypes; 733 CommandBufferTypes commandBufferTypes; 734 ImageMemory imageMemory; 735 UVec2 targetSize; 736 UVec2 renderPos; 737 UVec2 renderSize; 738 deUint32 seed; 739 AllocationKind allocationKind; 740 }; 741 742 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b) 743 { 744 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b)); 745 } 746 747 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b) 748 { 749 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b)); 750 } 751 752 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b) 753 { 754 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b)); 755 } 756 757 void logRenderPassInfo (TestLog& log, 758 const RenderPass& renderPass) 759 { 760 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass"); 761 762 { 763 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments"); 764 const vector<Attachment>& attachments = renderPass.getAttachments(); 765 766 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++) 767 { 768 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx)); 769 const Attachment& attachment = attachments[attachmentNdx]; 770 771 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage; 772 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage; 773 774 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage; 775 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage; 776 777 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage; 778 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage; 779 780 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage; 781 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage; 782 } 783 } 784 785 if (!renderPass.getInputAspects().empty()) 786 { 787 const tcu::ScopedLogSection inputAspectSection (log, "InputAspects", "InputAspects"); 788 789 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++) 790 { 791 const VkInputAttachmentAspectReferenceKHR& inputAspect (renderPass.getInputAspects()[aspectNdx]); 792 793 log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage; 794 log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex << TestLog::EndMessage; 795 log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask) << TestLog::EndMessage; 796 } 797 } 798 799 { 800 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses"); 801 const vector<Subpass>& subpasses = renderPass.getSubpasses(); 802 803 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++) 804 { 805 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx)); 806 const Subpass& subpass = subpasses[subpassNdx]; 807 808 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments(); 809 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments(); 810 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments(); 811 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments(); 812 813 if (!inputAttachments.empty()) 814 { 815 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs"); 816 817 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++) 818 { 819 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx)); 820 const AttachmentReference& inputAttachment = inputAttachments[inputNdx]; 821 822 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage; 823 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage; 824 } 825 } 826 827 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED) 828 { 829 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil"); 830 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment(); 831 832 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage; 833 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage; 834 } 835 836 if (!colorAttachments.empty()) 837 { 838 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors"); 839 840 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++) 841 { 842 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx)); 843 const AttachmentReference& colorAttachment = colorAttachments[colorNdx]; 844 845 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage; 846 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage; 847 } 848 } 849 850 if (!resolveAttachments.empty()) 851 { 852 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves"); 853 854 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++) 855 { 856 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx)); 857 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx]; 858 859 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage; 860 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage; 861 } 862 } 863 864 if (!preserveAttachments.empty()) 865 { 866 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves"); 867 868 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++) 869 { 870 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx)); 871 const deUint32 preserveAttachment = preserveAttachments[preserveNdx]; 872 873 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage; 874 } 875 } 876 } 877 878 } 879 880 if (!renderPass.getDependencies().empty()) 881 { 882 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies"); 883 884 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++) 885 { 886 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx)); 887 const SubpassDependency& dep = renderPass.getDependencies()[depNdx]; 888 889 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage; 890 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage; 891 892 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage; 893 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage; 894 895 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage; 896 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage; 897 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage; 898 } 899 } 900 } 901 902 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value) 903 { 904 const tcu::TextureFormat format = mapVkFormat(vkFormat); 905 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 906 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format); 907 908 std::ostringstream stream; 909 910 stream << "("; 911 912 switch (channelClass) 913 { 914 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 915 for (int i = 0; i < 4; i++) 916 { 917 if (i > 0) 918 stream << ", "; 919 920 if (channelMask[i]) 921 stream << value.int32[i]; 922 else 923 stream << "Undef"; 924 } 925 break; 926 927 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 928 for (int i = 0; i < 4; i++) 929 { 930 if (i > 0) 931 stream << ", "; 932 933 if (channelMask[i]) 934 stream << value.uint32[i]; 935 else 936 stream << "Undef"; 937 } 938 break; 939 940 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 941 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 942 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 943 for (int i = 0; i < 4; i++) 944 { 945 if (i > 0) 946 stream << ", "; 947 948 if (channelMask[i]) 949 stream << value.float32[i]; 950 else 951 stream << "Undef"; 952 } 953 break; 954 955 default: 956 DE_FATAL("Unknown channel class"); 957 } 958 959 stream << ")"; 960 961 return stream.str(); 962 } 963 964 std::string clearValueToString (VkFormat vkFormat, VkClearValue value) 965 { 966 const tcu::TextureFormat format = mapVkFormat(vkFormat); 967 968 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order)) 969 { 970 std::ostringstream stream; 971 972 stream << "("; 973 974 if (tcu::hasStencilComponent(format.order)) 975 stream << "stencil: " << value.depthStencil.stencil; 976 977 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order)) 978 stream << ", "; 979 980 if (tcu::hasDepthComponent(format.order)) 981 stream << "depth: " << value.depthStencil.depth; 982 983 stream << ")"; 984 985 return stream.str(); 986 } 987 else 988 return clearColorToString(vkFormat, value.color); 989 } 990 991 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng) 992 { 993 const float clearNan = tcu::Float32::nan().asFloat(); 994 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 995 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 996 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format); 997 VkClearColorValue clearColor; 998 999 switch (channelClass) 1000 { 1001 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1002 { 1003 for (int ndx = 0; ndx < 4; ndx++) 1004 { 1005 if (!channelMask[ndx]) 1006 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min(); 1007 else 1008 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u; 1009 } 1010 break; 1011 } 1012 1013 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1014 { 1015 for (int ndx = 0; ndx < 4; ndx++) 1016 { 1017 if (!channelMask[ndx]) 1018 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max(); 1019 else 1020 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u; 1021 } 1022 break; 1023 } 1024 1025 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1026 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1027 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1028 { 1029 for (int ndx = 0; ndx < 4; ndx++) 1030 { 1031 if (!channelMask[ndx]) 1032 clearColor.float32[ndx] = clearNan; 1033 else 1034 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f; 1035 } 1036 break; 1037 } 1038 1039 default: 1040 DE_FATAL("Unknown channel class"); 1041 } 1042 1043 return clearColor; 1044 } 1045 1046 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment) 1047 { 1048 const VkAttachmentDescription attachmentDescription = 1049 { 1050 0, // flags 1051 1052 attachment.getFormat(), // format 1053 attachment.getSamples(), // samples 1054 1055 attachment.getLoadOp(), // loadOp 1056 attachment.getStoreOp(), // storeOp 1057 1058 attachment.getStencilLoadOp(), // stencilLoadOp 1059 attachment.getStencilStoreOp(), // stencilStoreOp 1060 1061 attachment.getInitialLayout(), // initialLayout 1062 attachment.getFinalLayout(), // finalLayout 1063 }; 1064 1065 return attachmentDescription; 1066 } 1067 1068 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo) 1069 { 1070 const VkAttachmentReference reference = 1071 { 1072 referenceInfo.getAttachment(), // attachment; 1073 referenceInfo.getImageLayout() // layout; 1074 }; 1075 1076 return reference; 1077 } 1078 1079 VkSubpassDescription createSubpassDescription (const Subpass& subpass, 1080 vector<VkAttachmentReference>* attachmentReferenceLists, 1081 vector<deUint32>* preserveAttachmentReferences) 1082 { 1083 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0]; 1084 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1]; 1085 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2]; 1086 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3]; 1087 1088 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 1089 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx])); 1090 1091 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 1092 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx])); 1093 1094 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++) 1095 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx])); 1096 1097 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment())); 1098 1099 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++) 1100 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]); 1101 1102 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size()); 1103 1104 { 1105 const VkSubpassDescription subpassDescription = 1106 { 1107 subpass.getFlags(), // flags; 1108 subpass.getPipelineBindPoint(), // pipelineBindPoint; 1109 1110 (deUint32)inputAttachmentReferences.size(), // inputCount; 1111 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments; 1112 1113 (deUint32)colorAttachmentReferences.size(), // colorCount; 1114 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments; 1115 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments; 1116 1117 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment; 1118 (deUint32)preserveAttachmentReferences->size(), // preserveCount; 1119 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments; 1120 }; 1121 1122 return subpassDescription; 1123 } 1124 } 1125 1126 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo) 1127 { 1128 const VkSubpassDependency dependency = 1129 { 1130 dependencyInfo.getSrcPass(), // srcSubpass; 1131 dependencyInfo.getDstPass(), // destSubpass; 1132 1133 dependencyInfo.getSrcStageMask(), // srcStageMask; 1134 dependencyInfo.getDstStageMask(), // destStageMask; 1135 1136 dependencyInfo.getOutputMask(), // outputMask; 1137 dependencyInfo.getInputMask(), // inputMask; 1138 1139 dependencyInfo.getFlags() // dependencyFlags; 1140 }; 1141 1142 return dependency; 1143 } 1144 1145 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk, 1146 VkDevice device, 1147 const RenderPass& renderPassInfo) 1148 { 1149 const size_t perSubpassAttachmentReferenceLists = 4; 1150 vector<VkAttachmentDescription> attachments; 1151 vector<VkSubpassDescription> subpasses; 1152 vector<VkSubpassDependency> dependencies; 1153 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists); 1154 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size()); 1155 1156 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 1157 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx])); 1158 1159 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++) 1160 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx])); 1161 1162 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++) 1163 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx])); 1164 1165 if (renderPassInfo.getInputAspects().empty()) 1166 { 1167 const VkRenderPassCreateInfo createInfo = 1168 { 1169 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1170 DE_NULL, 1171 (VkRenderPassCreateFlags)0u, 1172 (deUint32)attachments.size(), 1173 (attachments.empty() ? DE_NULL : &attachments[0]), 1174 (deUint32)subpasses.size(), 1175 (subpasses.empty() ? DE_NULL : &subpasses[0]), 1176 (deUint32)dependencies.size(), 1177 (dependencies.empty() ? DE_NULL : &dependencies[0]) 1178 }; 1179 1180 return createRenderPass(vk, device, &createInfo); 1181 } 1182 else 1183 { 1184 const VkRenderPassInputAttachmentAspectCreateInfoKHR inputAspectCreateInfo = 1185 { 1186 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR, 1187 DE_NULL, 1188 1189 (deUint32)renderPassInfo.getInputAspects().size(), 1190 renderPassInfo.getInputAspects().data(), 1191 }; 1192 const VkRenderPassCreateInfo createInfo = 1193 { 1194 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1195 &inputAspectCreateInfo, 1196 (VkRenderPassCreateFlags)0u, 1197 (deUint32)attachments.size(), 1198 (attachments.empty() ? DE_NULL : &attachments[0]), 1199 (deUint32)subpasses.size(), 1200 (subpasses.empty() ? DE_NULL : &subpasses[0]), 1201 (deUint32)dependencies.size(), 1202 (dependencies.empty() ? DE_NULL : &dependencies[0]) 1203 }; 1204 1205 return createRenderPass(vk, device, &createInfo); 1206 } 1207 } 1208 1209 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk, 1210 VkDevice device, 1211 VkRenderPass renderPass, 1212 const UVec2& size, 1213 const vector<VkImageView>& attachments) 1214 { 1215 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u); 1216 } 1217 1218 Move<VkImage> createAttachmentImage (const DeviceInterface& vk, 1219 VkDevice device, 1220 deUint32 queueIndex, 1221 const UVec2& size, 1222 VkFormat format, 1223 VkSampleCountFlagBits samples, 1224 VkImageUsageFlags usageFlags, 1225 VkImageLayout layout) 1226 { 1227 VkImageUsageFlags targetUsageFlags = 0; 1228 const tcu::TextureFormat textureFormat = mapVkFormat(format); 1229 1230 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order)) 1231 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0)); 1232 1233 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order)) 1234 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)); 1235 1236 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order)) 1237 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 1238 else 1239 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1240 1241 return createImage(vk, device, 1242 (VkImageCreateFlags)0, 1243 VK_IMAGE_TYPE_2D, 1244 format, 1245 vk::makeExtent3D(size.x(), size.y(), 1u), 1246 1u /* mipLevels */, 1247 1u /* arraySize */, 1248 samples, 1249 VK_IMAGE_TILING_OPTIMAL, 1250 usageFlags | targetUsageFlags, 1251 VK_SHARING_MODE_EXCLUSIVE, 1252 1, 1253 &queueIndex, 1254 layout); 1255 } 1256 1257 de::MovePtr<Allocation> createImageMemory (const InstanceInterface& vki, 1258 const VkPhysicalDevice& vkd, 1259 const DeviceInterface& vk, 1260 VkDevice device, 1261 Allocator& allocator, 1262 VkImage image, 1263 bool lazy, 1264 AllocationKind allocationKind) 1265 { 1266 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any; 1267 de::MovePtr<Allocation> allocation = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind); 1268 1269 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset()); 1270 1271 return allocation; 1272 } 1273 1274 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk, 1275 VkDevice device, 1276 VkImage image, 1277 VkFormat format, 1278 VkImageAspectFlags aspect) 1279 { 1280 const VkImageSubresourceRange range = 1281 { 1282 aspect, 1283 0, 1284 1, 1285 0, 1286 1 1287 }; 1288 1289 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range); 1290 } 1291 1292 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng) 1293 { 1294 const float clearNan = tcu::Float32::nan().asFloat(); 1295 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 1296 1297 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order)) 1298 { 1299 VkClearValue clearValue; 1300 1301 clearValue.depthStencil.depth = clearNan; 1302 clearValue.depthStencil.stencil = 0xCDu; 1303 1304 if (tcu::hasStencilComponent(format.order)) 1305 clearValue.depthStencil.stencil = rng.getBool() 1306 ? 0xFFu 1307 : 0x0u; 1308 1309 if (tcu::hasDepthComponent(format.order)) 1310 clearValue.depthStencil.depth = rng.getBool() 1311 ? 1.0f 1312 : 0.0f; 1313 1314 return clearValue; 1315 } 1316 else 1317 { 1318 VkClearValue clearValue; 1319 1320 clearValue.color = randomColorClearValue(attachment, rng); 1321 1322 return clearValue; 1323 } 1324 } 1325 1326 class AttachmentResources 1327 { 1328 public: 1329 AttachmentResources (const InstanceInterface& vki, 1330 const VkPhysicalDevice& physDevice, 1331 const DeviceInterface& vk, 1332 VkDevice device, 1333 Allocator& allocator, 1334 deUint32 queueIndex, 1335 const UVec2& size, 1336 const Attachment& attachmentInfo, 1337 VkImageUsageFlags usageFlags, 1338 const AllocationKind allocationKind) 1339 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED)) 1340 , m_imageMemory (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind)) 1341 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat()))) 1342 { 1343 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat()); 1344 const bool isDepthFormat = tcu::hasDepthComponent(format.order); 1345 const bool isStencilFormat = tcu::hasStencilComponent(format.order); 1346 1347 if (isDepthFormat && isStencilFormat) 1348 { 1349 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT); 1350 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT); 1351 1352 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView); 1353 } 1354 else 1355 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u); 1356 1357 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0) 1358 { 1359 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) 1360 { 1361 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat()); 1362 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat()); 1363 1364 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize(); 1365 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize(); 1366 1367 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex); 1368 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind); 1369 1370 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset()); 1371 1372 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex); 1373 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind); 1374 1375 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset()); 1376 } 1377 else 1378 { 1379 m_bufferSize = size.x() * size.y() * format.getPixelSize(); 1380 1381 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex); 1382 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind); 1383 1384 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset()); 1385 } 1386 } 1387 } 1388 1389 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const 1390 { 1391 return m_inputAttachmentViews; 1392 } 1393 1394 ~AttachmentResources (void) 1395 { 1396 } 1397 1398 VkImageView getAttachmentView (void) const 1399 { 1400 return *m_attachmentView; 1401 } 1402 1403 VkImage getImage (void) const 1404 { 1405 return *m_image; 1406 } 1407 1408 VkBuffer getBuffer (void) const 1409 { 1410 DE_ASSERT(*m_buffer != DE_NULL); 1411 return *m_buffer; 1412 } 1413 1414 VkDeviceSize getBufferSize (void) const 1415 { 1416 DE_ASSERT(*m_buffer != DE_NULL); 1417 return m_bufferSize; 1418 } 1419 1420 const Allocation& getResultMemory (void) const 1421 { 1422 DE_ASSERT(m_bufferMemory); 1423 return *m_bufferMemory; 1424 } 1425 1426 VkBuffer getSecondaryBuffer (void) const 1427 { 1428 DE_ASSERT(*m_secondaryBuffer != DE_NULL); 1429 return *m_secondaryBuffer; 1430 } 1431 1432 VkDeviceSize getSecondaryBufferSize (void) const 1433 { 1434 DE_ASSERT(*m_secondaryBuffer != DE_NULL); 1435 return m_secondaryBufferSize; 1436 } 1437 1438 const Allocation& getSecondaryResultMemory (void) const 1439 { 1440 DE_ASSERT(m_secondaryBufferMemory); 1441 return *m_secondaryBufferMemory; 1442 } 1443 1444 private: 1445 const Unique<VkImage> m_image; 1446 const UniquePtr<Allocation> m_imageMemory; 1447 const Unique<VkImageView> m_attachmentView; 1448 1449 Move<VkImageView> m_depthInputAttachmentView; 1450 Move<VkImageView> m_stencilInputAttachmentView; 1451 pair<VkImageView, VkImageView> m_inputAttachmentViews; 1452 1453 Move<VkBuffer> m_buffer; 1454 VkDeviceSize m_bufferSize; 1455 de::MovePtr<Allocation> m_bufferMemory; 1456 1457 Move<VkBuffer> m_secondaryBuffer; 1458 VkDeviceSize m_secondaryBufferSize; 1459 de::MovePtr<Allocation> m_secondaryBufferMemory; 1460 }; 1461 1462 void uploadBufferData (const DeviceInterface& vk, 1463 VkDevice device, 1464 const Allocation& memory, 1465 size_t size, 1466 const void* data) 1467 { 1468 const VkMappedMemoryRange range = 1469 { 1470 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType; 1471 DE_NULL, // pNext; 1472 memory.getMemory(), // mem; 1473 memory.getOffset(), // offset; 1474 (VkDeviceSize)size // size; 1475 }; 1476 void* const ptr = memory.getHostPtr(); 1477 1478 deMemcpy(ptr, data, size); 1479 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range)); 1480 } 1481 1482 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order) 1483 { 1484 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21); 1485 1486 switch (order) 1487 { 1488 case tcu::TextureFormat::D: 1489 case tcu::TextureFormat::DS: 1490 return VK_IMAGE_ASPECT_DEPTH_BIT; 1491 1492 case tcu::TextureFormat::S: 1493 return VK_IMAGE_ASPECT_STENCIL_BIT; 1494 1495 default: 1496 return VK_IMAGE_ASPECT_COLOR_BIT; 1497 } 1498 } 1499 1500 class RenderQuad 1501 { 1502 public: 1503 RenderQuad (const Vec2& posA, const Vec2& posB) 1504 : m_vertices(6) 1505 { 1506 m_vertices[0] = posA; 1507 m_vertices[1] = Vec2(posA[0], posB[1]); 1508 m_vertices[2] = posB; 1509 1510 m_vertices[3] = posB; 1511 m_vertices[4] = Vec2(posB[0], posA[1]); 1512 m_vertices[5] = posA; 1513 } 1514 1515 const Vec2& getCornerA (void) const 1516 { 1517 return m_vertices[0]; 1518 } 1519 1520 const Vec2& getCornerB (void) const 1521 { 1522 return m_vertices[2]; 1523 } 1524 1525 const void* getVertexPointer (void) const 1526 { 1527 return &m_vertices[0]; 1528 } 1529 1530 size_t getVertexDataSize (void) const 1531 { 1532 return sizeof(Vec2) * m_vertices.size(); 1533 } 1534 1535 private: 1536 vector<Vec2> m_vertices; 1537 }; 1538 1539 class ColorClear 1540 { 1541 public: 1542 ColorClear (const UVec2& offset, 1543 const UVec2& size, 1544 const VkClearColorValue& color) 1545 : m_offset (offset) 1546 , m_size (size) 1547 , m_color (color) 1548 { 1549 } 1550 1551 const UVec2& getOffset (void) const { return m_offset; } 1552 const UVec2& getSize (void) const { return m_size; } 1553 const VkClearColorValue& getColor (void) const { return m_color; } 1554 1555 private: 1556 UVec2 m_offset; 1557 UVec2 m_size; 1558 VkClearColorValue m_color; 1559 }; 1560 1561 class DepthStencilClear 1562 { 1563 public: 1564 DepthStencilClear (const UVec2& offset, 1565 const UVec2& size, 1566 float depth, 1567 deUint32 stencil) 1568 : m_offset (offset) 1569 , m_size (size) 1570 , m_depth (depth) 1571 , m_stencil (stencil) 1572 { 1573 } 1574 1575 const UVec2& getOffset (void) const { return m_offset; } 1576 const UVec2& getSize (void) const { return m_size; } 1577 float getDepth (void) const { return m_depth; } 1578 deUint32 getStencil (void) const { return m_stencil; } 1579 1580 private: 1581 const UVec2 m_offset; 1582 const UVec2 m_size; 1583 1584 const float m_depth; 1585 const deUint32 m_stencil; 1586 }; 1587 1588 class SubpassRenderInfo 1589 { 1590 public: 1591 SubpassRenderInfo (const RenderPass& renderPass, 1592 deUint32 subpassIndex, 1593 1594 bool isSecondary_, 1595 1596 const UVec2& viewportOffset, 1597 const UVec2& viewportSize, 1598 1599 const Maybe<RenderQuad>& renderQuad, 1600 const vector<ColorClear>& colorClears, 1601 const Maybe<DepthStencilClear>& depthStencilClear) 1602 : m_viewportOffset (viewportOffset) 1603 , m_viewportSize (viewportSize) 1604 , m_subpassIndex (subpassIndex) 1605 , m_isSecondary (isSecondary_) 1606 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags()) 1607 , m_renderQuad (renderQuad) 1608 , m_colorClears (colorClears) 1609 , m_depthStencilClear (depthStencilClear) 1610 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments()) 1611 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments()) 1612 { 1613 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++) 1614 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]); 1615 1616 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED) 1617 { 1618 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment()); 1619 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]); 1620 } 1621 } 1622 1623 const UVec2& getViewportOffset (void) const { return m_viewportOffset; } 1624 const UVec2& getViewportSize (void) const { return m_viewportSize; } 1625 1626 deUint32 getSubpassIndex (void) const { return m_subpassIndex; } 1627 bool isSecondary (void) const { return m_isSecondary; } 1628 1629 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; } 1630 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; } 1631 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; } 1632 1633 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); } 1634 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); } 1635 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); } 1636 1637 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); } 1638 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); } 1639 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); } 1640 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; } 1641 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); } 1642 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); }; 1643 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; } 1644 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; } 1645 1646 private: 1647 UVec2 m_viewportOffset; 1648 UVec2 m_viewportSize; 1649 1650 deUint32 m_subpassIndex; 1651 bool m_isSecondary; 1652 VkSubpassDescriptionFlags m_flags; 1653 1654 Maybe<RenderQuad> m_renderQuad; 1655 vector<ColorClear> m_colorClears; 1656 Maybe<DepthStencilClear> m_depthStencilClear; 1657 1658 vector<AttachmentReference> m_colorAttachments; 1659 vector<Attachment> m_colorAttachmentInfo; 1660 1661 Maybe<AttachmentReference> m_depthStencilAttachment; 1662 Maybe<Attachment> m_depthStencilAttachmentInfo; 1663 1664 vector<AttachmentReference> m_inputAttachments; 1665 }; 1666 1667 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk, 1668 VkDevice device, 1669 VkRenderPass renderPass, 1670 VkShaderModule vertexShaderModule, 1671 VkShaderModule fragmentShaderModule, 1672 VkPipelineLayout pipelineLayout, 1673 const SubpassRenderInfo& renderInfo) 1674 { 1675 const VkSpecializationInfo emptyShaderSpecializations = 1676 { 1677 0u, // mapEntryCount 1678 DE_NULL, // pMap 1679 0u, // dataSize 1680 DE_NULL, // pData 1681 }; 1682 1683 Maybe<VkSampleCountFlagBits> rasterSamples; 1684 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates; 1685 1686 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++) 1687 { 1688 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx); 1689 1690 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples()); 1691 1692 rasterSamples = attachment.getSamples(); 1693 1694 { 1695 const VkPipelineColorBlendAttachmentState attachmentBlendState = 1696 { 1697 VK_FALSE, // blendEnable 1698 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor 1699 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor 1700 VK_BLEND_OP_ADD, // blendOpColor 1701 VK_BLEND_FACTOR_ONE, // srcBlendAlpha 1702 VK_BLEND_FACTOR_ONE, // destBlendAlpha 1703 VK_BLEND_OP_ADD, // blendOpAlpha 1704 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask 1705 }; 1706 1707 attachmentBlendStates.push_back(attachmentBlendState); 1708 } 1709 } 1710 1711 if (renderInfo.getDepthStencilAttachment()) 1712 { 1713 const Attachment& attachment = *renderInfo.getDepthStencilAttachment(); 1714 1715 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples()); 1716 rasterSamples = attachment.getSamples(); 1717 } 1718 1719 // If there are no attachment use single sample 1720 if (!rasterSamples) 1721 rasterSamples = VK_SAMPLE_COUNT_1_BIT; 1722 1723 const VkPipelineShaderStageCreateInfo shaderStages[2] = 1724 { 1725 { 1726 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1727 DE_NULL, // pNext 1728 (VkPipelineShaderStageCreateFlags)0u, 1729 VK_SHADER_STAGE_VERTEX_BIT, // stage 1730 vertexShaderModule, // shader 1731 "main", 1732 &emptyShaderSpecializations 1733 }, 1734 { 1735 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 1736 DE_NULL, // pNext 1737 (VkPipelineShaderStageCreateFlags)0u, 1738 VK_SHADER_STAGE_FRAGMENT_BIT, // stage 1739 fragmentShaderModule, // shader 1740 "main", 1741 &emptyShaderSpecializations 1742 } 1743 }; 1744 const VkVertexInputBindingDescription vertexBinding = 1745 { 1746 0u, // binding 1747 (deUint32)sizeof(tcu::Vec2), // strideInBytes 1748 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate 1749 }; 1750 const VkVertexInputAttributeDescription vertexAttrib = 1751 { 1752 0u, // location 1753 0u, // binding 1754 VK_FORMAT_R32G32_SFLOAT, // format 1755 0u, // offsetInBytes 1756 }; 1757 const VkPipelineVertexInputStateCreateInfo vertexInputState = 1758 { 1759 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType 1760 DE_NULL, // pNext 1761 (VkPipelineVertexInputStateCreateFlags)0u, 1762 1u, // bindingCount 1763 &vertexBinding, // pVertexBindingDescriptions 1764 1u, // attributeCount 1765 &vertexAttrib, // pVertexAttributeDescriptions 1766 }; 1767 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = 1768 { 1769 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType 1770 DE_NULL, // pNext 1771 (VkPipelineInputAssemblyStateCreateFlags)0u, 1772 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology 1773 VK_FALSE, // primitiveRestartEnable 1774 }; 1775 const VkViewport viewport = 1776 { 1777 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(), 1778 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(), 1779 0.0f, 1.0f 1780 }; 1781 const VkRect2D scissor = 1782 { 1783 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() }, 1784 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() } 1785 }; 1786 const VkPipelineViewportStateCreateInfo viewportState = 1787 { 1788 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 1789 DE_NULL, 1790 (VkPipelineViewportStateCreateFlags)0u, 1791 1u, 1792 &viewport, 1793 1u, 1794 &scissor 1795 }; 1796 const VkPipelineRasterizationStateCreateInfo rasterState = 1797 { 1798 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType 1799 DE_NULL, // pNext 1800 (VkPipelineRasterizationStateCreateFlags)0u, 1801 VK_TRUE, // depthClipEnable 1802 VK_FALSE, // rasterizerDiscardEnable 1803 VK_POLYGON_MODE_FILL, // fillMode 1804 VK_CULL_MODE_NONE, // cullMode 1805 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace 1806 VK_FALSE, // depthBiasEnable 1807 0.0f, // depthBias 1808 0.0f, // depthBiasClamp 1809 0.0f, // slopeScaledDepthBias 1810 1.0f // lineWidth 1811 }; 1812 const VkPipelineMultisampleStateCreateInfo multisampleState = 1813 { 1814 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType 1815 DE_NULL, // pNext 1816 (VkPipelineMultisampleStateCreateFlags)0u, 1817 *rasterSamples, // rasterSamples 1818 VK_FALSE, // sampleShadingEnable 1819 0.0f, // minSampleShading 1820 DE_NULL, // pSampleMask 1821 VK_FALSE, // alphaToCoverageEnable 1822 VK_FALSE, // alphaToOneEnable 1823 }; 1824 const size_t stencilIndex = renderInfo.getSubpassIndex(); 1825 const VkBool32 writeDepth = renderInfo.getDepthStencilAttachmentLayout() 1826 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 1827 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR 1828 ? VK_TRUE 1829 : VK_FALSE; 1830 const VkBool32 writeStencil = renderInfo.getDepthStencilAttachmentLayout() 1831 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 1832 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 1833 ? VK_TRUE 1834 : VK_FALSE; 1835 const VkPipelineDepthStencilStateCreateInfo depthStencilState = 1836 { 1837 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType 1838 DE_NULL, // pNext 1839 (VkPipelineDepthStencilStateCreateFlags)0u, 1840 writeDepth, // depthTestEnable 1841 writeDepth, // depthWriteEnable 1842 VK_COMPARE_OP_ALWAYS, // depthCompareOp 1843 VK_FALSE, // depthBoundsEnable 1844 writeStencil, // stencilTestEnable 1845 { 1846 VK_STENCIL_OP_REPLACE, // stencilFailOp 1847 VK_STENCIL_OP_REPLACE, // stencilPassOp 1848 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp 1849 VK_COMPARE_OP_ALWAYS, // stencilCompareOp 1850 ~0u, // stencilCompareMask 1851 ~0u, // stencilWriteMask 1852 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference 1853 }, // front 1854 { 1855 VK_STENCIL_OP_REPLACE, // stencilFailOp 1856 VK_STENCIL_OP_REPLACE, // stencilPassOp 1857 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp 1858 VK_COMPARE_OP_ALWAYS, // stencilCompareOp 1859 ~0u, // stencilCompareMask 1860 ~0u, // stencilWriteMask 1861 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference 1862 }, // back 1863 1864 0.0f, // minDepthBounds; 1865 1.0f // maxDepthBounds; 1866 }; 1867 const VkPipelineColorBlendStateCreateInfo blendState = 1868 { 1869 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType 1870 DE_NULL, // pNext 1871 (VkPipelineColorBlendStateCreateFlags)0u, 1872 VK_FALSE, // logicOpEnable 1873 VK_LOGIC_OP_COPY, // logicOp 1874 (deUint32)attachmentBlendStates.size(), // attachmentCount 1875 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments 1876 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst 1877 }; 1878 const VkGraphicsPipelineCreateInfo createInfo = 1879 { 1880 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType 1881 DE_NULL, // pNext 1882 (VkPipelineCreateFlags)0u, 1883 1884 2, // stageCount 1885 shaderStages, // pStages 1886 1887 &vertexInputState, // pVertexInputState 1888 &inputAssemblyState, // pInputAssemblyState 1889 DE_NULL, // pTessellationState 1890 &viewportState, // pViewportState 1891 &rasterState, // pRasterState 1892 &multisampleState, // pMultisampleState 1893 &depthStencilState, // pDepthStencilState 1894 &blendState, // pColorBlendState 1895 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState 1896 pipelineLayout, // layout 1897 1898 renderPass, // renderPass 1899 renderInfo.getSubpassIndex(), // subpass 1900 DE_NULL, // basePipelineHandle 1901 0u // basePipelineIndex 1902 }; 1903 1904 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo); 1905 } 1906 1907 class SubpassRenderer 1908 { 1909 public: 1910 SubpassRenderer (Context& context, 1911 const DeviceInterface& vk, 1912 VkDevice device, 1913 Allocator& allocator, 1914 VkRenderPass renderPass, 1915 VkFramebuffer framebuffer, 1916 VkCommandPool commandBufferPool, 1917 deUint32 queueFamilyIndex, 1918 const vector<VkImage>& attachmentImages, 1919 const vector<pair<VkImageView, VkImageView> >& attachmentViews, 1920 const SubpassRenderInfo& renderInfo, 1921 const vector<Attachment>& attachmentInfos, 1922 const AllocationKind allocationKind) 1923 : m_renderInfo (renderInfo) 1924 { 1925 const InstanceInterface& vki = context.getInstanceInterface(); 1926 const VkPhysicalDevice& physDevice = context.getPhysicalDevice(); 1927 const deUint32 subpassIndex = renderInfo.getSubpassIndex(); 1928 vector<VkDescriptorSetLayoutBinding> bindings; 1929 1930 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++) 1931 m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]); 1932 1933 if (renderInfo.getDepthStencilAttachmentIndex()) 1934 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()]; 1935 1936 if (renderInfo.getRenderQuad()) 1937 { 1938 const RenderQuad& renderQuad = *renderInfo.getRenderQuad(); 1939 1940 if (renderInfo.getInputAttachmentCount() > 0) 1941 { 1942 deUint32 bindingIndex = 0; 1943 1944 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++) 1945 { 1946 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)]; 1947 const VkImageLayout layout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx); 1948 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat()); 1949 const bool isDepthFormat = tcu::hasDepthComponent(format.order); 1950 const bool isStencilFormat = tcu::hasStencilComponent(format.order); 1951 const deUint32 bindingCount = (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 1952 && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 1953 ? 2u 1954 : 1u; 1955 1956 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++) 1957 { 1958 const VkDescriptorSetLayoutBinding binding = 1959 { 1960 bindingIndex, 1961 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1962 1u, 1963 vk::VK_SHADER_STAGE_FRAGMENT_BIT, 1964 DE_NULL 1965 }; 1966 1967 bindings.push_back(binding); 1968 bindingIndex++; 1969 } 1970 } 1971 1972 const VkDescriptorSetLayoutCreateInfo createInfo = 1973 { 1974 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 1975 DE_NULL, 1976 1977 0u, 1978 (deUint32)bindings.size(), 1979 &bindings[0] 1980 }; 1981 1982 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo); 1983 } 1984 1985 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout; 1986 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1987 { 1988 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType; 1989 DE_NULL, // pNext; 1990 (vk::VkPipelineLayoutCreateFlags)0, 1991 m_descriptorSetLayout ? 1u :0u , // setLayoutCount; 1992 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts; 1993 0u, // pushConstantRangeCount; 1994 DE_NULL, // pPushConstantRanges; 1995 }; 1996 1997 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u); 1998 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u); 1999 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams); 2000 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo); 2001 2002 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex); 2003 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind); 2004 2005 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()); 2006 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer()); 2007 2008 if (renderInfo.getInputAttachmentCount() > 0) 2009 { 2010 { 2011 const VkDescriptorPoolSize poolSize = 2012 { 2013 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2014 // \note Reserve 2 per input attachment since depthStencil attachments require 2. 2015 renderInfo.getInputAttachmentCount() * 2u 2016 }; 2017 const VkDescriptorPoolCreateInfo createInfo = 2018 { 2019 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 2020 DE_NULL, 2021 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2022 2023 // \note Reserve 2 per input attachment since depthStencil attachments require 2. 2024 renderInfo.getInputAttachmentCount() * 2u, 2025 1u, 2026 &poolSize 2027 }; 2028 2029 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo); 2030 } 2031 { 2032 const VkDescriptorSetAllocateInfo allocateInfo = 2033 { 2034 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2035 DE_NULL, 2036 2037 *m_descriptorPool, 2038 1u, 2039 &descriptorSetLayout 2040 }; 2041 2042 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo); 2043 } 2044 { 2045 vector<VkWriteDescriptorSet> writes (bindings.size()); 2046 vector<VkDescriptorImageInfo> imageInfos (bindings.size()); 2047 deUint32 bindingIndex = 0; 2048 2049 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++) 2050 { 2051 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)]; 2052 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat()); 2053 const bool isDepthFormat = tcu::hasDepthComponent(format.order); 2054 const bool isStencilFormat = tcu::hasStencilComponent(format.order); 2055 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx); 2056 2057 2058 if (isDepthFormat && isStencilFormat) 2059 { 2060 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 2061 { 2062 const VkDescriptorImageInfo imageInfo = 2063 { 2064 (VkSampler)0, 2065 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first, 2066 inputAttachmentLayout 2067 }; 2068 imageInfos[bindingIndex] = imageInfo; 2069 2070 { 2071 const VkWriteDescriptorSet write = 2072 { 2073 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 2074 DE_NULL, 2075 2076 *m_descriptorSet, 2077 bindingIndex, 2078 0u, 2079 1u, 2080 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2081 &imageInfos[bindingIndex], 2082 DE_NULL, 2083 DE_NULL 2084 }; 2085 writes[bindingIndex] = write; 2086 2087 bindingIndex++; 2088 } 2089 } 2090 2091 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 2092 { 2093 const VkDescriptorImageInfo imageInfo = 2094 { 2095 (VkSampler)0, 2096 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second, 2097 inputAttachmentLayout 2098 }; 2099 imageInfos[bindingIndex] = imageInfo; 2100 2101 { 2102 const VkWriteDescriptorSet write = 2103 { 2104 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 2105 DE_NULL, 2106 2107 *m_descriptorSet, 2108 bindingIndex, 2109 0u, 2110 1u, 2111 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2112 &imageInfos[bindingIndex], 2113 DE_NULL, 2114 DE_NULL 2115 }; 2116 writes[bindingIndex] = write; 2117 2118 bindingIndex++; 2119 } 2120 } 2121 } 2122 else 2123 { 2124 const VkDescriptorImageInfo imageInfo = 2125 { 2126 (VkSampler)0, 2127 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first, 2128 inputAttachmentLayout 2129 }; 2130 imageInfos[bindingIndex] = imageInfo; 2131 2132 { 2133 const VkWriteDescriptorSet write = 2134 { 2135 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 2136 DE_NULL, 2137 2138 *m_descriptorSet, 2139 bindingIndex, 2140 0u, 2141 1u, 2142 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2143 &imageInfos[bindingIndex], 2144 DE_NULL, 2145 DE_NULL 2146 }; 2147 writes[bindingIndex] = write; 2148 2149 bindingIndex++; 2150 } 2151 } 2152 } 2153 2154 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL); 2155 } 2156 } 2157 } 2158 2159 if (renderInfo.isSecondary()) 2160 { 2161 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 2162 2163 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 2164 pushRenderCommands(vk, *m_commandBuffer); 2165 endCommandBuffer(vk, *m_commandBuffer); 2166 } 2167 } 2168 2169 bool isSecondary (void) const 2170 { 2171 return m_commandBuffer; 2172 } 2173 2174 VkCommandBuffer getCommandBuffer (void) const 2175 { 2176 DE_ASSERT(isSecondary()); 2177 return *m_commandBuffer; 2178 } 2179 2180 void pushRenderCommands (const DeviceInterface& vk, 2181 VkCommandBuffer commandBuffer) 2182 { 2183 if (!m_renderInfo.getColorClears().empty()) 2184 { 2185 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears()); 2186 2187 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++) 2188 { 2189 const ColorClear& colorClear = colorClears[attachmentNdx]; 2190 const VkClearAttachment attachment = 2191 { 2192 VK_IMAGE_ASPECT_COLOR_BIT, 2193 attachmentNdx, 2194 makeClearValue(colorClear.getColor()), 2195 }; 2196 const VkClearRect rect = 2197 { 2198 { 2199 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() }, 2200 { colorClear.getSize().x(), colorClear.getSize().y() } 2201 }, // rect 2202 0u, // baseArrayLayer 2203 1u, // layerCount 2204 }; 2205 2206 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect); 2207 } 2208 } 2209 2210 if (m_renderInfo.getDepthStencilClear()) 2211 { 2212 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear(); 2213 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount(); 2214 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat()); 2215 const VkImageLayout layout = *m_renderInfo.getDepthStencilAttachmentLayout(); 2216 const VkClearAttachment attachment = 2217 { 2218 (VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) 2219 | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)), 2220 attachmentNdx, 2221 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil()) 2222 }; 2223 const VkClearRect rect = 2224 { 2225 { 2226 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() }, 2227 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() } 2228 }, // rect 2229 0u, // baseArrayLayer 2230 1u, // layerCount 2231 }; 2232 2233 if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 2234 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)) 2235 { 2236 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect); 2237 } 2238 } 2239 2240 vector<VkImageMemoryBarrier> selfDeps; 2241 VkPipelineStageFlags srcStages = 0; 2242 VkPipelineStageFlags dstStages = 0; 2243 2244 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++) 2245 { 2246 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++) 2247 { 2248 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx)) 2249 { 2250 const VkImageMemoryBarrier barrier = 2251 { 2252 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 2253 DE_NULL, // pNext 2254 2255 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask 2256 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask 2257 2258 VK_IMAGE_LAYOUT_GENERAL, // oldLayout 2259 VK_IMAGE_LAYOUT_GENERAL, // newLayout 2260 2261 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 2262 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex 2263 2264 m_colorAttachmentImages[colorAttachmentNdx], // image 2265 { // subresourceRange 2266 VK_IMAGE_ASPECT_COLOR_BIT, // aspect 2267 0, // baseMipLevel 2268 1, // mipLevels 2269 0, // baseArraySlice 2270 1 // arraySize 2271 } 2272 }; 2273 2274 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 2275 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 2276 2277 selfDeps.push_back(barrier); 2278 } 2279 } 2280 2281 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex())) 2282 { 2283 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat()); 2284 const bool hasDepth = hasDepthComponent(format.order); 2285 const bool hasStencil = hasStencilComponent(format.order); 2286 const VkImageMemoryBarrier barrier = 2287 { 2288 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType; 2289 DE_NULL, // pNext; 2290 2291 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask 2292 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask 2293 2294 VK_IMAGE_LAYOUT_GENERAL, // oldLayout 2295 VK_IMAGE_LAYOUT_GENERAL, // newLayout; 2296 2297 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex; 2298 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex; 2299 2300 m_depthStencilAttachmentImage, // image; 2301 { // subresourceRange; 2302 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 2303 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect; 2304 0, // baseMipLevel; 2305 1, // mipLevels; 2306 0, // baseArraySlice; 2307 1 // arraySize; 2308 } 2309 }; 2310 2311 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; 2312 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 2313 2314 selfDeps.push_back(barrier); 2315 } 2316 } 2317 2318 if (!selfDeps.empty()) 2319 { 2320 DE_ASSERT(srcStages != 0); 2321 DE_ASSERT(dstStages != 0); 2322 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]); 2323 } 2324 2325 if (m_renderInfo.getRenderQuad()) 2326 { 2327 const VkDeviceSize offset = 0; 2328 const VkBuffer vertexBuffer = *m_vertexBuffer; 2329 2330 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 2331 2332 if (m_descriptorSet) 2333 { 2334 const VkDescriptorSet descriptorSet = *m_descriptorSet; 2335 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL); 2336 } 2337 2338 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset); 2339 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u); 2340 } 2341 } 2342 2343 private: 2344 const SubpassRenderInfo m_renderInfo; 2345 Move<VkCommandBuffer> m_commandBuffer; 2346 Move<VkPipeline> m_pipeline; 2347 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 2348 Move<VkPipelineLayout> m_pipelineLayout; 2349 2350 Move<VkShaderModule> m_vertexShaderModule; 2351 Move<VkShaderModule> m_fragmentShaderModule; 2352 2353 Move<VkDescriptorPool> m_descriptorPool; 2354 Move<VkDescriptorSet> m_descriptorSet; 2355 Move<VkBuffer> m_vertexBuffer; 2356 de::MovePtr<Allocation> m_vertexBufferMemory; 2357 vector<VkImage> m_colorAttachmentImages; 2358 VkImage m_depthStencilAttachmentImage; 2359 }; 2360 2361 void pushImageInitializationCommands (const DeviceInterface& vk, 2362 VkCommandBuffer commandBuffer, 2363 const vector<Attachment>& attachmentInfo, 2364 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources, 2365 deUint32 queueIndex, 2366 const vector<Maybe<VkClearValue> >& clearValues) 2367 { 2368 { 2369 vector<VkImageMemoryBarrier> initializeLayouts; 2370 2371 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2372 { 2373 if (!clearValues[attachmentNdx]) 2374 continue; 2375 2376 const VkImageMemoryBarrier barrier = 2377 { 2378 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType; 2379 DE_NULL, // pNext; 2380 2381 (VkAccessFlags)0, // srcAccessMask 2382 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask 2383 2384 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout 2385 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout; 2386 2387 queueIndex, // srcQueueFamilyIndex; 2388 queueIndex, // destQueueFamilyIndex; 2389 2390 attachmentResources[attachmentNdx]->getImage(), // image; 2391 { // subresourceRange; 2392 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect; 2393 0, // baseMipLevel; 2394 1, // mipLevels; 2395 0, // baseArraySlice; 2396 1 // arraySize; 2397 } 2398 }; 2399 2400 initializeLayouts.push_back(barrier); 2401 } 2402 2403 if (!initializeLayouts.empty()) 2404 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, 2405 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 2406 0, (const VkMemoryBarrier*)DE_NULL, 2407 0, (const VkBufferMemoryBarrier*)DE_NULL, 2408 (deUint32)initializeLayouts.size(), &initializeLayouts[0]); 2409 } 2410 2411 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2412 { 2413 if (!clearValues[attachmentNdx]) 2414 continue; 2415 2416 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()); 2417 2418 if (hasStencilComponent(format.order) || hasDepthComponent(format.order)) 2419 { 2420 const float clearNan = tcu::Float32::nan().asFloat(); 2421 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan; 2422 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu; 2423 const VkClearDepthStencilValue depthStencil = 2424 { 2425 clearDepth, 2426 clearStencil 2427 }; 2428 const VkImageSubresourceRange range = 2429 { 2430 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) 2431 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)), 2432 0, 2433 1, 2434 0, 2435 1 2436 }; 2437 2438 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range); 2439 } 2440 else 2441 { 2442 const VkImageSubresourceRange range = 2443 { 2444 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask; 2445 0, // baseMipLevel; 2446 1, // mipLevels; 2447 0, // baseArrayLayer; 2448 1 // layerCount; 2449 }; 2450 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color; 2451 2452 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); 2453 } 2454 } 2455 2456 { 2457 vector<VkImageMemoryBarrier> renderPassLayouts; 2458 2459 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2460 { 2461 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; 2462 const VkImageMemoryBarrier barrier = 2463 { 2464 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType; 2465 DE_NULL, // pNext; 2466 2467 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask 2468 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask 2469 2470 oldLayout, // oldLayout 2471 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout; 2472 2473 queueIndex, // srcQueueFamilyIndex; 2474 queueIndex, // destQueueFamilyIndex; 2475 2476 attachmentResources[attachmentNdx]->getImage(), // image; 2477 { // subresourceRange; 2478 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect; 2479 0, // baseMipLevel; 2480 1, // mipLevels; 2481 0, // baseArraySlice; 2482 1 // arraySize; 2483 } 2484 }; 2485 2486 renderPassLayouts.push_back(barrier); 2487 } 2488 2489 if (!renderPassLayouts.empty()) 2490 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, 2491 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 2492 0, (const VkMemoryBarrier*)DE_NULL, 2493 0, (const VkBufferMemoryBarrier*)DE_NULL, 2494 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]); 2495 } 2496 } 2497 2498 void pushRenderPassCommands (const DeviceInterface& vk, 2499 VkCommandBuffer commandBuffer, 2500 VkRenderPass renderPass, 2501 VkFramebuffer framebuffer, 2502 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers, 2503 const UVec2& renderPos, 2504 const UVec2& renderSize, 2505 const vector<Maybe<VkClearValue> >& renderPassClearValues, 2506 TestConfig::RenderTypes render) 2507 { 2508 const float clearNan = tcu::Float32::nan().asFloat(); 2509 vector<VkClearValue> attachmentClearValues; 2510 2511 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++) 2512 { 2513 if (renderPassClearValues[attachmentNdx]) 2514 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]); 2515 else 2516 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan)); 2517 } 2518 2519 { 2520 const VkRect2D renderArea = 2521 { 2522 { (deInt32)renderPos.x(), (deInt32)renderPos.y() }, 2523 { renderSize.x(), renderSize.y() } 2524 }; 2525 2526 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++) 2527 { 2528 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE; 2529 2530 if (subpassNdx == 0) 2531 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents); 2532 else 2533 vk.cmdNextSubpass(commandBuffer, contents); 2534 2535 if (render) 2536 { 2537 if (contents == VK_SUBPASS_CONTENTS_INLINE) 2538 { 2539 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer); 2540 } 2541 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS) 2542 { 2543 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer(); 2544 vk.cmdExecuteCommands(commandBuffer, 1, &cmd); 2545 } 2546 else 2547 DE_FATAL("Invalid contents"); 2548 } 2549 } 2550 2551 vk.cmdEndRenderPass(commandBuffer); 2552 } 2553 } 2554 2555 void pushReadImagesToBuffers (const DeviceInterface& vk, 2556 VkCommandBuffer commandBuffer, 2557 deUint32 queueIndex, 2558 2559 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources, 2560 const vector<Attachment>& attachmentInfo, 2561 const vector<bool>& isLazy, 2562 2563 const UVec2& targetSize) 2564 { 2565 { 2566 vector<VkImageMemoryBarrier> imageBarriers; 2567 2568 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2569 { 2570 if (isLazy[attachmentNdx]) 2571 continue; 2572 2573 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout(); 2574 const VkImageMemoryBarrier barrier = 2575 { 2576 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 2577 DE_NULL, // pNext 2578 2579 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask 2580 getAllMemoryReadFlags(), // dstAccessMask 2581 2582 oldLayout, // oldLayout 2583 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout 2584 2585 queueIndex, // srcQueueFamilyIndex 2586 queueIndex, // destQueueFamilyIndex 2587 2588 attachmentResources[attachmentNdx]->getImage(), // image 2589 { // subresourceRange 2590 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect; 2591 0, // baseMipLevel 2592 1, // mipLevels 2593 0, // baseArraySlice 2594 1 // arraySize 2595 } 2596 }; 2597 2598 imageBarriers.push_back(barrier); 2599 } 2600 2601 if (!imageBarriers.empty()) 2602 vk.cmdPipelineBarrier(commandBuffer, 2603 getAllPipelineStageFlags(), 2604 getAllPipelineStageFlags(), 2605 (VkDependencyFlags)0, 2606 0, (const VkMemoryBarrier*)DE_NULL, 2607 0, (const VkBufferMemoryBarrier*)DE_NULL, 2608 (deUint32)imageBarriers.size(), &imageBarriers[0]); 2609 } 2610 2611 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2612 { 2613 if (isLazy[attachmentNdx]) 2614 continue; 2615 2616 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order; 2617 const VkBufferImageCopy rect = 2618 { 2619 0, // bufferOffset 2620 0, // bufferRowLength 2621 0, // bufferImageHeight 2622 { // imageSubresource 2623 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect 2624 0, // mipLevel 2625 0, // arraySlice 2626 1 // arraySize 2627 }, 2628 { 0, 0, 0 }, // imageOffset 2629 { targetSize.x(), targetSize.y(), 1u } // imageExtent 2630 }; 2631 2632 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect); 2633 2634 if (tcu::TextureFormat::DS == order) 2635 { 2636 const VkBufferImageCopy stencilRect = 2637 { 2638 0, // bufferOffset 2639 0, // bufferRowLength 2640 0, // bufferImageHeight 2641 { // imageSubresource 2642 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect 2643 0, // mipLevel 2644 0, // arraySlice 2645 1 // arraySize 2646 }, 2647 { 0, 0, 0 }, // imageOffset 2648 { targetSize.x(), targetSize.y(), 1u } // imageExtent 2649 }; 2650 2651 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect); 2652 } 2653 } 2654 2655 { 2656 vector<VkBufferMemoryBarrier> bufferBarriers; 2657 2658 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++) 2659 { 2660 if (isLazy[attachmentNdx]) 2661 continue; 2662 2663 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order; 2664 const VkBufferMemoryBarrier bufferBarrier = 2665 { 2666 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 2667 DE_NULL, 2668 2669 getAllMemoryWriteFlags(), 2670 getAllMemoryReadFlags(), 2671 2672 queueIndex, 2673 queueIndex, 2674 2675 attachmentResources[attachmentNdx]->getBuffer(), 2676 0, 2677 attachmentResources[attachmentNdx]->getBufferSize() 2678 }; 2679 2680 bufferBarriers.push_back(bufferBarrier); 2681 2682 if (tcu::TextureFormat::DS == order) 2683 { 2684 const VkBufferMemoryBarrier secondaryBufferBarrier = 2685 { 2686 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 2687 DE_NULL, 2688 2689 getAllMemoryWriteFlags(), 2690 getAllMemoryReadFlags(), 2691 2692 queueIndex, 2693 queueIndex, 2694 2695 attachmentResources[attachmentNdx]->getSecondaryBuffer(), 2696 0, 2697 attachmentResources[attachmentNdx]->getSecondaryBufferSize() 2698 }; 2699 2700 bufferBarriers.push_back(secondaryBufferBarrier); 2701 } 2702 } 2703 2704 if (!bufferBarriers.empty()) 2705 vk.cmdPipelineBarrier(commandBuffer, 2706 getAllPipelineStageFlags(), 2707 getAllPipelineStageFlags(), 2708 (VkDependencyFlags)0, 2709 0, (const VkMemoryBarrier*)DE_NULL, 2710 (deUint32)bufferBarriers.size(), &bufferBarriers[0], 2711 0, (const VkImageMemoryBarrier*)DE_NULL); 2712 } 2713 } 2714 2715 class PixelValue 2716 { 2717 public: 2718 PixelValue (const Maybe<bool>& x = nothing<bool>(), 2719 const Maybe<bool>& y = nothing<bool>(), 2720 const Maybe<bool>& z = nothing<bool>(), 2721 const Maybe<bool>& w = nothing<bool>()); 2722 2723 void setUndefined (size_t ndx); 2724 void setValue (size_t ndx, bool value); 2725 Maybe<bool> getValue (size_t ndx) const; 2726 2727 private: 2728 deUint16 m_status; 2729 }; 2730 2731 PixelValue::PixelValue (const Maybe<bool>& x, 2732 const Maybe<bool>& y, 2733 const Maybe<bool>& z, 2734 const Maybe<bool>& w) 2735 : m_status (0) 2736 { 2737 const Maybe<bool> values[] = 2738 { 2739 x, y, z, w 2740 }; 2741 2742 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++) 2743 { 2744 if (values[ndx]) 2745 setValue(ndx, *values[ndx]); 2746 else 2747 setUndefined(ndx); 2748 } 2749 2750 DE_ASSERT(m_status <= 0xFFu); 2751 } 2752 2753 void PixelValue::setUndefined (size_t ndx) 2754 { 2755 DE_ASSERT(ndx < 4); 2756 DE_ASSERT(m_status <= 0xFFu); 2757 2758 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2)); 2759 DE_ASSERT(m_status <= 0xFFu); 2760 } 2761 2762 void PixelValue::setValue (size_t ndx, bool value) 2763 { 2764 DE_ASSERT(ndx < 4); 2765 DE_ASSERT(m_status <= 0xFFu); 2766 2767 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2))); 2768 2769 if (value) 2770 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1))); 2771 else 2772 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1)); 2773 2774 DE_ASSERT(m_status <= 0xFFu); 2775 } 2776 2777 Maybe<bool> PixelValue::getValue (size_t ndx) const 2778 { 2779 DE_ASSERT(ndx < 4); 2780 DE_ASSERT(m_status <= 0xFFu); 2781 2782 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0) 2783 { 2784 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0); 2785 } 2786 else 2787 return nothing<bool>(); 2788 } 2789 2790 void clearReferenceValues (vector<PixelValue>& values, 2791 const UVec2& targetSize, 2792 const UVec2& offset, 2793 const UVec2& size, 2794 const BVec4& mask, 2795 const PixelValue& value) 2796 { 2797 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size()); 2798 DE_ASSERT(offset.x() + size.x() <= targetSize.x()); 2799 DE_ASSERT(offset.y() + size.y() <= targetSize.y()); 2800 2801 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++) 2802 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++) 2803 { 2804 for (int compNdx = 0; compNdx < 4; compNdx++) 2805 { 2806 if (mask[compNdx]) 2807 { 2808 if (value.getValue(compNdx)) 2809 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx)); 2810 else 2811 values[x + y * targetSize.x()].setUndefined(compNdx); 2812 } 2813 } 2814 } 2815 } 2816 2817 void markUndefined (vector<PixelValue>& values, 2818 const BVec4& mask, 2819 const UVec2& targetSize, 2820 const UVec2& offset, 2821 const UVec2& size) 2822 { 2823 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size()); 2824 2825 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++) 2826 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++) 2827 { 2828 for (int compNdx = 0; compNdx < 4; compNdx++) 2829 { 2830 if (mask[compNdx]) 2831 values[x + y * targetSize.x()].setUndefined(compNdx); 2832 } 2833 } 2834 } 2835 2836 PixelValue clearValueToPixelValue (const VkClearValue& value, 2837 const tcu::TextureFormat& format) 2838 { 2839 const bool isDepthAttachment = hasDepthComponent(format.order); 2840 const bool isStencilAttachment = hasStencilComponent(format.order); 2841 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment; 2842 PixelValue pixelValue; 2843 2844 if (isDepthOrStencilAttachment) 2845 { 2846 if (isDepthAttachment) 2847 { 2848 if (value.depthStencil.depth == 1.0f) 2849 pixelValue.setValue(0, true); 2850 else if (value.depthStencil.depth == 0.0f) 2851 pixelValue.setValue(0, false); 2852 else 2853 DE_FATAL("Unknown depth value"); 2854 } 2855 2856 if (isStencilAttachment) 2857 { 2858 if (value.depthStencil.stencil == 0xFFu) 2859 pixelValue.setValue(1, true); 2860 else if (value.depthStencil.stencil == 0x0u) 2861 pixelValue.setValue(1, false); 2862 else 2863 DE_FATAL("Unknown stencil value"); 2864 } 2865 } 2866 else 2867 { 2868 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 2869 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format); 2870 2871 switch (channelClass) 2872 { 2873 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 2874 for (int i = 0; i < 4; i++) 2875 { 2876 if (channelMask[i]) 2877 { 2878 if (value.color.int32[i] == 1) 2879 pixelValue.setValue(i, true); 2880 else if (value.color.int32[i] == 0) 2881 pixelValue.setValue(i, false); 2882 else 2883 DE_FATAL("Unknown clear color value"); 2884 } 2885 } 2886 break; 2887 2888 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 2889 for (int i = 0; i < 4; i++) 2890 { 2891 if (channelMask[i]) 2892 { 2893 if (value.color.uint32[i] == 1u) 2894 pixelValue.setValue(i, true); 2895 else if (value.color.uint32[i] == 0u) 2896 pixelValue.setValue(i, false); 2897 else 2898 DE_FATAL("Unknown clear color value"); 2899 } 2900 } 2901 break; 2902 2903 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 2904 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 2905 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 2906 for (int i = 0; i < 4; i++) 2907 { 2908 if (channelMask[i]) 2909 { 2910 if (value.color.float32[i] == 1.0f) 2911 pixelValue.setValue(i, true); 2912 else if (value.color.float32[i] == 0.0f) 2913 pixelValue.setValue(i, false); 2914 else 2915 DE_FATAL("Unknown clear color value"); 2916 } 2917 } 2918 break; 2919 2920 default: 2921 DE_FATAL("Unknown channel class"); 2922 } 2923 } 2924 2925 return pixelValue; 2926 } 2927 2928 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments, 2929 const RenderPass& renderPassInfo, 2930 const UVec2& targetSize, 2931 const vector<Maybe<VkClearValue> >& imageClearValues, 2932 const vector<Maybe<VkClearValue> >& renderPassClearValues, 2933 const vector<SubpassRenderInfo>& subpassRenderInfo, 2934 const UVec2& renderPos, 2935 const UVec2& renderSize) 2936 { 2937 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses(); 2938 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false); 2939 2940 referenceAttachments.resize(renderPassInfo.getAttachments().size()); 2941 2942 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 2943 { 2944 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx]; 2945 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 2946 vector<PixelValue>& reference = referenceAttachments[attachmentNdx]; 2947 2948 reference.resize(targetSize.x() * targetSize.y()); 2949 2950 if (imageClearValues[attachmentNdx]) 2951 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format)); 2952 } 2953 2954 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++) 2955 { 2956 const Subpass& subpass = subpasses[subpassNdx]; 2957 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx]; 2958 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments(); 2959 2960 // Apply load op if attachment was used for the first time 2961 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++) 2962 { 2963 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment(); 2964 2965 if (!attachmentUsed[attachmentIndex]) 2966 { 2967 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 2968 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 2969 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 2970 2971 DE_ASSERT(!tcu::hasDepthComponent(format.order)); 2972 DE_ASSERT(!tcu::hasStencilComponent(format.order)); 2973 2974 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR) 2975 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format)); 2976 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE) 2977 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize); 2978 2979 attachmentUsed[attachmentIndex] = true; 2980 } 2981 } 2982 2983 // Apply load op to depth/stencil attachment if it was used for the first time 2984 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED) 2985 { 2986 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 2987 2988 // Apply load op if attachment was used for the first time 2989 if (!attachmentUsed[attachmentIndex]) 2990 { 2991 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 2992 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 2993 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 2994 2995 if (tcu::hasDepthComponent(format.order)) 2996 { 2997 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR) 2998 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format)); 2999 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE) 3000 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize); 3001 } 3002 3003 if (tcu::hasStencilComponent(format.order)) 3004 { 3005 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR) 3006 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format)); 3007 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE) 3008 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize); 3009 } 3010 3011 attachmentUsed[attachmentIndex] = true; 3012 } 3013 } 3014 3015 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++) 3016 { 3017 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx]; 3018 const UVec2 offset = colorClear.getOffset(); 3019 const UVec2 size = colorClear.getSize(); 3020 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment(); 3021 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3022 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3023 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3024 VkClearValue value; 3025 3026 value.color = colorClear.getColor(); 3027 3028 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format)); 3029 } 3030 3031 if (renderInfo.getDepthStencilClear()) 3032 { 3033 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear(); 3034 const UVec2 offset = dsClear.getOffset(); 3035 const UVec2 size = dsClear.getSize(); 3036 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 3037 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout(); 3038 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3039 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3040 const bool hasStencil = tcu::hasStencilComponent(format.order) 3041 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR; 3042 const bool hasDepth = tcu::hasDepthComponent(format.order) 3043 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR; 3044 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3045 VkClearValue value; 3046 3047 value.depthStencil.depth = dsClear.getDepth(); 3048 value.depthStencil.stencil = dsClear.getStencil(); 3049 3050 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format)); 3051 } 3052 3053 if (renderInfo.getRenderQuad()) 3054 { 3055 const RenderQuad& renderQuad = *renderInfo.getRenderQuad(); 3056 const Vec2 posA = renderQuad.getCornerA(); 3057 const Vec2 posB = renderQuad.getCornerB(); 3058 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f); 3059 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f); 3060 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())), 3061 deRoundFloatToInt32(origin.y() + (p.y() * posA.y()))); 3062 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())), 3063 deRoundFloatToInt32(origin.y() + (p.y() * posB.y()))); 3064 3065 DE_ASSERT(posAI.x() < posBI.x()); 3066 DE_ASSERT(posAI.y() < posBI.y()); 3067 3068 if (subpass.getInputAttachments().empty()) 3069 { 3070 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++) 3071 { 3072 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment(); 3073 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3074 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3075 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format); 3076 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3077 3078 for (int y = posAI.y(); y < (int)posBI.y(); y++) 3079 for (int x = posAI.x(); x < (int)posBI.x(); x++) 3080 { 3081 for (int compNdx = 0; compNdx < 4; compNdx++) 3082 { 3083 const size_t index = subpassNdx + attachmentIndex + compNdx; 3084 const BoolOp op = boolOpFromIndex(index); 3085 const bool boolX = x % 2 == (int)(index % 2); 3086 const bool boolY = y % 2 == (int)((index / 2) % 2); 3087 3088 if (channelMask[compNdx]) 3089 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY)); 3090 } 3091 } 3092 } 3093 3094 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED) 3095 { 3096 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 3097 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout(); 3098 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3099 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3100 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3101 3102 for (int y = posAI.y(); y < (int)posBI.y(); y++) 3103 for (int x = posAI.x(); x < (int)posBI.x(); x++) 3104 { 3105 if (tcu::hasDepthComponent(format.order) 3106 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3107 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3108 { 3109 const size_t index = subpassNdx + 1; 3110 const BoolOp op = boolOpFromIndex(index); 3111 const bool boolX = x % 2 == (int)(index % 2); 3112 const bool boolY = y % 2 == (int)((index / 2) % 2); 3113 3114 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY)); 3115 } 3116 3117 if (tcu::hasStencilComponent(format.order) 3118 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3119 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3120 { 3121 const size_t index = subpassNdx; 3122 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0); 3123 } 3124 } 3125 } 3126 } 3127 else 3128 { 3129 size_t outputComponentCount = 0; 3130 vector<Maybe<bool> > inputs; 3131 3132 DE_ASSERT(posAI.x() < posBI.x()); 3133 DE_ASSERT(posAI.y() < posBI.y()); 3134 3135 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++) 3136 { 3137 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment(); 3138 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3139 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3140 const int componentCount = tcu::getNumUsedChannels(format.order); 3141 3142 outputComponentCount += (size_t)componentCount; 3143 } 3144 3145 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3146 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3147 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3148 { 3149 const Attachment& attachment (renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]); 3150 const tcu::TextureFormat format (mapVkFormat(attachment.getFormat())); 3151 3152 if (tcu::hasDepthComponent(format.order)) 3153 outputComponentCount++; 3154 } 3155 3156 if (outputComponentCount > 0) 3157 { 3158 for (int y = posAI.y(); y < (int)posBI.y(); y++) 3159 for (int x = posAI.x(); x < (int)posBI.x(); x++) 3160 { 3161 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++) 3162 { 3163 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment(); 3164 const VkImageLayout layout = subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout(); 3165 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3166 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3167 const int componentCount = tcu::getNumUsedChannels(format.order); 3168 3169 for (int compNdx = 0; compNdx < componentCount; compNdx++) 3170 { 3171 if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3172 && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)) 3173 { 3174 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx)); 3175 } 3176 } 3177 } 3178 3179 const size_t inputsPerOutput = inputs.size() >= outputComponentCount 3180 ? ((inputs.size() / outputComponentCount) 3181 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0)) 3182 : 1; 3183 3184 size_t outputValueNdx = 0; 3185 3186 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++) 3187 { 3188 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment(); 3189 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3190 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3191 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3192 const int componentCount = tcu::getNumUsedChannels(format.order); 3193 3194 for (int compNdx = 0; compNdx < componentCount; compNdx++) 3195 { 3196 const size_t index = subpassNdx + attachmentIndex + outputValueNdx; 3197 const BoolOp op = boolOpFromIndex(index); 3198 const bool boolX = x % 2 == (int)(index % 2); 3199 const bool boolY = y % 2 == (int)((index / 2) % 2); 3200 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY)); 3201 3202 for (size_t i = 0; i < inputsPerOutput; i++) 3203 { 3204 if (!output) 3205 break; 3206 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]) 3207 output = tcu::nothing<bool>(); 3208 else 3209 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]); 3210 } 3211 3212 if (output) 3213 reference[x + y * targetSize.x()].setValue(compNdx, *output); 3214 else 3215 reference[x + y * targetSize.x()].setUndefined(compNdx); 3216 } 3217 3218 outputValueNdx += componentCount; 3219 } 3220 3221 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3222 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3223 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3224 { 3225 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 3226 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3227 const size_t index = subpassNdx + attachmentIndex; 3228 const BoolOp op = boolOpFromIndex(index); 3229 const bool boolX = x % 2 == (int)(index % 2); 3230 const bool boolY = y % 2 == (int)((index / 2) % 2); 3231 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY)); 3232 3233 for (size_t i = 0; i < inputsPerOutput; i++) 3234 { 3235 if (!output) 3236 break; 3237 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]) 3238 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]); 3239 else 3240 output = tcu::nothing<bool>(); 3241 } 3242 3243 if (output) 3244 reference[x + y * targetSize.x()].setValue(0, *output); 3245 else 3246 reference[x + y * targetSize.x()].setUndefined(0); 3247 } 3248 3249 inputs.clear(); 3250 } 3251 } 3252 3253 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3254 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3255 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3256 { 3257 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 3258 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3259 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3260 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3261 3262 if (tcu::hasStencilComponent(format.order)) 3263 { 3264 for (int y = posAI.y(); y < (int)posBI.y(); y++) 3265 for (int x = posAI.x(); x < (int)posBI.x(); x++) 3266 { 3267 const size_t index = subpassNdx; 3268 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0); 3269 } 3270 } 3271 } 3272 } 3273 } 3274 } 3275 3276 // Mark all attachments that were used but not stored as undefined 3277 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++) 3278 { 3279 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex]; 3280 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3281 vector<PixelValue>& reference = referenceAttachments[attachmentIndex]; 3282 const bool isStencilAttachment = hasStencilComponent(format.order); 3283 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment; 3284 3285 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE) 3286 { 3287 if (isDepthOrStencilAttachment) 3288 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize); 3289 else 3290 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize); 3291 } 3292 3293 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE) 3294 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize); 3295 } 3296 } 3297 3298 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages, 3299 const vector<vector<PixelValue> >& referenceValues, 3300 const UVec2& targetSize, 3301 const RenderPass& renderPassInfo) 3302 { 3303 referenceImages.resize(referenceValues.size()); 3304 3305 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 3306 { 3307 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx]; 3308 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3309 const vector<PixelValue>& reference = referenceValues[attachmentNdx]; 3310 const bool hasDepth = tcu::hasDepthComponent(format.order); 3311 const bool hasStencil = tcu::hasStencilComponent(format.order); 3312 const bool hasDepthOrStencil = hasDepth || hasStencil; 3313 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx]; 3314 3315 referenceImage.setStorage(format, targetSize.x(), targetSize.y()); 3316 3317 if (hasDepthOrStencil) 3318 { 3319 if (hasDepth) 3320 { 3321 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH)); 3322 3323 for (deUint32 y = 0; y < targetSize.y(); y++) 3324 for (deUint32 x = 0; x < targetSize.x(); x++) 3325 { 3326 if (reference[x + y * targetSize.x()].getValue(0)) 3327 { 3328 if (*reference[x + y * targetSize.x()].getValue(0)) 3329 depthAccess.setPixDepth(1.0f, x, y); 3330 else 3331 depthAccess.setPixDepth(0.0f, x, y); 3332 } 3333 else // Fill with 3x3 grid 3334 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y); 3335 } 3336 } 3337 3338 if (hasStencil) 3339 { 3340 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL)); 3341 3342 for (deUint32 y = 0; y < targetSize.y(); y++) 3343 for (deUint32 x = 0; x < targetSize.x(); x++) 3344 { 3345 if (reference[x + y * targetSize.x()].getValue(1)) 3346 { 3347 if (*reference[x + y * targetSize.x()].getValue(1)) 3348 stencilAccess.setPixStencil(0xFFu, x, y); 3349 else 3350 stencilAccess.setPixStencil(0x0u, x, y); 3351 } 3352 else // Fill with 3x3 grid 3353 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y); 3354 } 3355 } 3356 } 3357 else 3358 { 3359 for (deUint32 y = 0; y < targetSize.y(); y++) 3360 for (deUint32 x = 0; x < targetSize.x(); x++) 3361 { 3362 tcu::Vec4 color; 3363 3364 for (int compNdx = 0; compNdx < 4; compNdx++) 3365 { 3366 if (reference[x + y * targetSize.x()].getValue(compNdx)) 3367 { 3368 if (*reference[x + y * targetSize.x()].getValue(compNdx)) 3369 color[compNdx] = 1.0f; 3370 else 3371 color[compNdx] = 0.0f; 3372 } 3373 else // Fill with 3x3 grid 3374 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f; 3375 } 3376 3377 referenceImage.getAccess().setPixel(color, x, y); 3378 } 3379 } 3380 } 3381 } 3382 3383 bool verifyColorAttachment (const vector<PixelValue>& reference, 3384 const ConstPixelBufferAccess& result, 3385 const PixelBufferAccess& errorImage) 3386 { 3387 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 3388 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 3389 bool ok = true; 3390 3391 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size()); 3392 DE_ASSERT(result.getWidth() == errorImage.getWidth()); 3393 DE_ASSERT(result.getHeight() == errorImage.getHeight()); 3394 3395 for (int y = 0; y < result.getHeight(); y++) 3396 for (int x = 0; x < result.getWidth(); x++) 3397 { 3398 const Vec4 resultColor = result.getPixel(x, y); 3399 const PixelValue& referenceValue = reference[x + y * result.getWidth()]; 3400 bool pixelOk = true; 3401 3402 for (int compNdx = 0; compNdx < 4; compNdx++) 3403 { 3404 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx); 3405 3406 if (maybeValue) 3407 { 3408 const bool value = *maybeValue; 3409 3410 if ((value && (resultColor[compNdx] != 1.0f)) 3411 || (!value && resultColor[compNdx] != 0.0f)) 3412 pixelOk = false; 3413 } 3414 } 3415 3416 if (!pixelOk) 3417 { 3418 errorImage.setPixel(red, x, y); 3419 ok = false; 3420 } 3421 else 3422 errorImage.setPixel(green, x, y); 3423 } 3424 3425 return ok; 3426 } 3427 3428 bool verifyDepthAttachment (const vector<PixelValue>& reference, 3429 const ConstPixelBufferAccess& result, 3430 const PixelBufferAccess& errorImage) 3431 { 3432 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 3433 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 3434 bool ok = true; 3435 3436 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size()); 3437 DE_ASSERT(result.getWidth() == errorImage.getWidth()); 3438 DE_ASSERT(result.getHeight() == errorImage.getHeight()); 3439 3440 for (int y = 0; y < result.getHeight(); y++) 3441 for (int x = 0; x < result.getWidth(); x++) 3442 { 3443 bool pixelOk = true; 3444 3445 const float resultDepth = result.getPixDepth(x, y); 3446 const PixelValue& referenceValue = reference[x + y * result.getWidth()]; 3447 const Maybe<bool> maybeValue = referenceValue.getValue(0); 3448 3449 if (maybeValue) 3450 { 3451 const bool value = *maybeValue; 3452 3453 if ((value && (resultDepth != 1.0f)) 3454 || (!value && resultDepth != 0.0f)) 3455 pixelOk = false; 3456 } 3457 3458 if (!pixelOk) 3459 { 3460 errorImage.setPixel(red, x, y); 3461 ok = false; 3462 } 3463 else 3464 errorImage.setPixel(green, x, y); 3465 } 3466 3467 return ok; 3468 } 3469 3470 bool verifyStencilAttachment (const vector<PixelValue>& reference, 3471 const ConstPixelBufferAccess& result, 3472 const PixelBufferAccess& errorImage) 3473 { 3474 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f); 3475 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f); 3476 bool ok = true; 3477 3478 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size()); 3479 DE_ASSERT(result.getWidth() == errorImage.getWidth()); 3480 DE_ASSERT(result.getHeight() == errorImage.getHeight()); 3481 3482 for (int y = 0; y < result.getHeight(); y++) 3483 for (int x = 0; x < result.getWidth(); x++) 3484 { 3485 bool pixelOk = true; 3486 3487 const deUint32 resultStencil = result.getPixStencil(x, y); 3488 const PixelValue& referenceValue = reference[x + y * result.getWidth()]; 3489 const Maybe<bool> maybeValue = referenceValue.getValue(1); 3490 3491 if (maybeValue) 3492 { 3493 const bool value = *maybeValue; 3494 3495 if ((value && (resultStencil != 0xFFu)) 3496 || (!value && resultStencil != 0x0u)) 3497 pixelOk = false; 3498 } 3499 3500 if (!pixelOk) 3501 { 3502 errorImage.setPixel(red, x, y); 3503 ok = false; 3504 } 3505 else 3506 errorImage.setPixel(green, x, y); 3507 } 3508 3509 return ok; 3510 } 3511 3512 bool logAndVerifyImages (TestLog& log, 3513 const DeviceInterface& vk, 3514 VkDevice device, 3515 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources, 3516 const vector<bool>& attachmentIsLazy, 3517 const RenderPass& renderPassInfo, 3518 const vector<Maybe<VkClearValue> >& renderPassClearValues, 3519 const vector<Maybe<VkClearValue> >& imageClearValues, 3520 const vector<SubpassRenderInfo>& subpassRenderInfo, 3521 const UVec2& targetSize, 3522 const TestConfig& config) 3523 { 3524 vector<vector<PixelValue> > referenceValues; 3525 vector<tcu::TextureLevel> referenceAttachments; 3526 bool isOk = true; 3527 3528 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage; 3529 3530 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize); 3531 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo); 3532 3533 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 3534 { 3535 if (!attachmentIsLazy[attachmentNdx]) 3536 { 3537 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx]; 3538 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3539 3540 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) 3541 { 3542 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat()); 3543 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize(); 3544 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr(); 3545 3546 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat()); 3547 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize(); 3548 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr(); 3549 3550 const VkMappedMemoryRange ranges[] = 3551 { 3552 { 3553 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType; 3554 DE_NULL, // pNext; 3555 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem; 3556 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset; 3557 depthBufferSize // size; 3558 }, 3559 { 3560 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType; 3561 DE_NULL, // pNext; 3562 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem; 3563 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset; 3564 stencilBufferSize // size; 3565 } 3566 }; 3567 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges)); 3568 3569 { 3570 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr); 3571 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr); 3572 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y()); 3573 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y()); 3574 3575 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess); 3576 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess); 3577 3578 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess()); 3579 3580 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE 3581 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess())) 3582 { 3583 log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess()); 3584 isOk = false; 3585 } 3586 3587 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE 3588 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess())) 3589 { 3590 log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess()); 3591 isOk = false; 3592 } 3593 } 3594 } 3595 else 3596 { 3597 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize(); 3598 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr(); 3599 3600 const VkMappedMemoryRange range = 3601 { 3602 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType; 3603 DE_NULL, // pNext; 3604 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem; 3605 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset; 3606 bufferSize // size; 3607 }; 3608 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range)); 3609 3610 if (tcu::hasDepthComponent(format.order)) 3611 { 3612 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr); 3613 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y()); 3614 3615 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access); 3616 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess()); 3617 3618 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE) 3619 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess())) 3620 { 3621 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess()); 3622 isOk = false; 3623 } 3624 } 3625 else if (tcu::hasStencilComponent(format.order)) 3626 { 3627 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr); 3628 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y()); 3629 3630 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access); 3631 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess()); 3632 3633 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE) 3634 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess())) 3635 { 3636 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess()); 3637 isOk = false; 3638 } 3639 } 3640 else 3641 { 3642 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr); 3643 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y()); 3644 3645 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access); 3646 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess()); 3647 3648 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE) 3649 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess())) 3650 { 3651 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess()); 3652 isOk = false; 3653 } 3654 } 3655 } 3656 } 3657 } 3658 3659 return isOk; 3660 } 3661 3662 std::string getInputAttachmentType (VkFormat vkFormat) 3663 { 3664 const tcu::TextureFormat format = mapVkFormat(vkFormat); 3665 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 3666 3667 switch (channelClass) 3668 { 3669 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 3670 return "isubpassInput"; 3671 3672 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 3673 return "usubpassInput"; 3674 3675 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 3676 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 3677 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 3678 return "subpassInput"; 3679 3680 default: 3681 DE_FATAL("Unknown channel class"); 3682 return ""; 3683 } 3684 } 3685 3686 std::string getAttachmentType (VkFormat vkFormat) 3687 { 3688 const tcu::TextureFormat format = mapVkFormat(vkFormat); 3689 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 3690 3691 switch (channelClass) 3692 { 3693 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 3694 return "ivec4"; 3695 3696 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 3697 return "uvec4"; 3698 3699 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 3700 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 3701 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 3702 return "vec4"; 3703 3704 default: 3705 DE_FATAL("Unknown channel class"); 3706 return ""; 3707 } 3708 } 3709 3710 void createTestShaders (SourceCollections& dst, TestConfig config) 3711 { 3712 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW) 3713 { 3714 const vector<Subpass>& subpasses = config.renderPass.getSubpasses(); 3715 3716 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++) 3717 { 3718 const Subpass& subpass = subpasses[subpassNdx]; 3719 deUint32 inputAttachmentBinding = 0; 3720 std::ostringstream vertexShader; 3721 std::ostringstream fragmentShader; 3722 3723 vertexShader << "#version 310 es\n" 3724 << "layout(location = 0) in highp vec2 a_position;\n" 3725 << "void main (void) {\n" 3726 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n" 3727 << "}\n"; 3728 3729 fragmentShader << "#version 310 es\n" 3730 << "precision highp float;\n"; 3731 3732 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 3733 { 3734 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment(); 3735 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout(); 3736 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex]; 3737 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3738 const bool isDepthFormat = tcu::hasDepthComponent(format.order); 3739 const bool isStencilFormat = tcu::hasStencilComponent(format.order); 3740 3741 if (isDepthFormat || isStencilFormat) 3742 { 3743 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3744 { 3745 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n"; 3746 inputAttachmentBinding++; 3747 } 3748 3749 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3750 { 3751 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n"; 3752 inputAttachmentBinding++; 3753 } 3754 } 3755 else 3756 { 3757 const std::string attachmentType = getInputAttachmentType(attachment.getFormat()); 3758 3759 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n"; 3760 inputAttachmentBinding++; 3761 } 3762 } 3763 3764 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 3765 { 3766 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat()); 3767 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n"; 3768 } 3769 3770 fragmentShader << "void main (void) {\n"; 3771 3772 if (subpass.getInputAttachments().empty()) 3773 { 3774 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 3775 { 3776 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment(); 3777 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat()); 3778 3779 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4("; 3780 3781 for (size_t compNdx = 0; compNdx < 4; compNdx++) 3782 { 3783 const size_t index = subpassNdx + attachmentIndex + compNdx; 3784 const BoolOp op = boolOpFromIndex(index); 3785 3786 if (compNdx > 0) 3787 fragmentShader << ",\n\t\t"; 3788 3789 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2) 3790 << ") " << boolOpToString(op) << " (" 3791 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) 3792 << ") ? 1.0 : 0.0)"; 3793 } 3794 3795 fragmentShader << "));\n"; 3796 } 3797 3798 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3799 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3800 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3801 { 3802 const size_t index = subpassNdx + 1; 3803 const BoolOp op = boolOpFromIndex(index); 3804 3805 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2) 3806 << ") " << boolOpToString(op) << " (" 3807 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) 3808 << ") ? 1.0 : 0.0);\n"; 3809 } 3810 } 3811 else 3812 { 3813 size_t inputComponentCount = 0; 3814 size_t outputComponentCount = 0; 3815 3816 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 3817 { 3818 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment(); 3819 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout(); 3820 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex]; 3821 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3822 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order); 3823 3824 if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3825 inputComponentCount += 1; 3826 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3827 inputComponentCount += 1; 3828 else 3829 inputComponentCount += componentCount; 3830 } 3831 3832 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 3833 { 3834 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment(); 3835 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex]; 3836 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3837 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order); 3838 3839 outputComponentCount += componentCount; 3840 } 3841 3842 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3843 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3844 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3845 { 3846 outputComponentCount++; 3847 } 3848 3849 if (outputComponentCount > 0) 3850 { 3851 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount 3852 ? ((inputComponentCount / outputComponentCount) 3853 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0)) 3854 : 1; 3855 3856 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"; 3857 3858 if (outputComponentCount > 0) 3859 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n"; 3860 3861 size_t inputValueNdx = 0; 3862 3863 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 3864 { 3865 const char* const components[] = 3866 { 3867 "x", "y", "z", "w" 3868 }; 3869 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment(); 3870 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout(); 3871 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex]; 3872 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3873 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order); 3874 const bool isDepthFormat = tcu::hasDepthComponent(format.order); 3875 const bool isStencilFormat = tcu::hasStencilComponent(format.order); 3876 3877 if (isDepthFormat || isStencilFormat) 3878 { 3879 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR) 3880 { 3881 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n"; 3882 inputValueNdx++; 3883 } 3884 3885 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3886 { 3887 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n"; 3888 inputValueNdx++; 3889 } 3890 } 3891 else 3892 { 3893 for (size_t compNdx = 0; compNdx < componentCount; compNdx++) 3894 { 3895 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n"; 3896 inputValueNdx++; 3897 } 3898 } 3899 } 3900 3901 size_t outputValueNdx = 0; 3902 3903 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 3904 { 3905 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment(); 3906 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex]; 3907 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat()); 3908 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 3909 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order); 3910 3911 for (size_t compNdx = 0; compNdx < componentCount; compNdx++) 3912 { 3913 const size_t index = subpassNdx + attachmentIndex + outputValueNdx; 3914 const BoolOp op = boolOpFromIndex(index); 3915 3916 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = " 3917 << "(int(gl_FragCoord.x) % 2 == " << (index % 2) 3918 << ") " << boolOpToString(op) << " (" 3919 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) 3920 << ");\n"; 3921 3922 for (size_t i = 0; i < inputsPerOutput; i++) 3923 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n"; 3924 } 3925 3926 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "("; 3927 3928 for (size_t compNdx = 0; compNdx < 4; compNdx++) 3929 { 3930 if (compNdx > 0) 3931 fragmentShader << ", "; 3932 3933 if (compNdx < componentCount) 3934 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]"; 3935 else 3936 fragmentShader << "0"; 3937 } 3938 3939 outputValueNdx += componentCount; 3940 3941 fragmentShader << ");\n"; 3942 } 3943 3944 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED 3945 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL 3946 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 3947 { 3948 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment(); 3949 const size_t index = subpassNdx + attachmentIndex; 3950 const BoolOp op = boolOpFromIndex(index); 3951 3952 fragmentShader << "\toutputs[" << outputValueNdx << "] = " 3953 << "(int(gl_FragCoord.x) % 2 == " << (index % 2) 3954 << ") " << boolOpToString(op) << " (" 3955 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) 3956 << ");\n"; 3957 3958 for (size_t i = 0; i < inputsPerOutput; i++) 3959 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n"; 3960 3961 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;"; 3962 } 3963 } 3964 } 3965 3966 fragmentShader << "}\n"; 3967 3968 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str()); 3969 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str()); 3970 } 3971 } 3972 } 3973 3974 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory) 3975 { 3976 bool lastAttachmentWasLazy = false; 3977 3978 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++) 3979 { 3980 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD 3981 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE 3982 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD 3983 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE) 3984 { 3985 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy)) 3986 { 3987 attachmentIsLazy.push_back(true); 3988 3989 lastAttachmentWasLazy = true; 3990 } 3991 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT) 3992 { 3993 attachmentIsLazy.push_back(false); 3994 lastAttachmentWasLazy = false; 3995 } 3996 else 3997 DE_FATAL("Unknown imageMemory"); 3998 } 3999 else 4000 attachmentIsLazy.push_back(false); 4001 } 4002 } 4003 4004 enum AttachmentRefType 4005 { 4006 ATTACHMENTREFTYPE_COLOR, 4007 ATTACHMENTREFTYPE_DEPTH_STENCIL, 4008 ATTACHMENTREFTYPE_INPUT, 4009 ATTACHMENTREFTYPE_RESOLVE, 4010 }; 4011 4012 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout) 4013 { 4014 switch (layout) 4015 { 4016 case VK_IMAGE_LAYOUT_GENERAL: 4017 case VK_IMAGE_LAYOUT_PREINITIALIZED: 4018 return 0; 4019 4020 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 4021 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 4022 4023 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 4024 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 4025 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 4026 4027 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 4028 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 4029 4030 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 4031 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 4032 4033 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 4034 return VK_IMAGE_USAGE_TRANSFER_DST_BIT; 4035 4036 default: 4037 DE_FATAL("Unexpected image layout"); 4038 return 0; 4039 } 4040 } 4041 4042 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references) 4043 { 4044 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx) 4045 { 4046 const deUint32 attachment = references[referenceNdx].getAttachment(); 4047 4048 if (attachment != VK_ATTACHMENT_UNUSED) 4049 { 4050 VkImageUsageFlags usage; 4051 4052 switch (refType) 4053 { 4054 case ATTACHMENTREFTYPE_COLOR: 4055 case ATTACHMENTREFTYPE_RESOLVE: 4056 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 4057 break; 4058 4059 case ATTACHMENTREFTYPE_DEPTH_STENCIL: 4060 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 4061 break; 4062 4063 case ATTACHMENTREFTYPE_INPUT: 4064 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 4065 break; 4066 4067 default: 4068 DE_FATAL("Unexpected attachment reference type"); 4069 usage = 0; 4070 break; 4071 } 4072 4073 attachmentImageUsage[attachment] |= usage; 4074 } 4075 } 4076 } 4077 4078 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references) 4079 { 4080 if (!references.empty()) 4081 { 4082 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]); 4083 } 4084 } 4085 4086 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues) 4087 { 4088 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0)); 4089 4090 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx) 4091 { 4092 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx]; 4093 4094 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments()); 4095 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment()); 4096 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments()); 4097 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments()); 4098 } 4099 4100 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 4101 { 4102 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx]; 4103 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat()); 4104 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures; 4105 4106 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0) 4107 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT; 4108 4109 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0) 4110 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT; 4111 4112 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout()); 4113 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout()); 4114 4115 if (!attachmentIsLazy[attachmentNdx]) 4116 { 4117 if (clearValues[attachmentNdx]) 4118 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 4119 4120 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 4121 } 4122 else 4123 { 4124 const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); 4125 4126 attachmentImageUsage[attachmentNdx] &= allowedTransientBits; 4127 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; 4128 } 4129 } 4130 } 4131 4132 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer) 4133 { 4134 bool lastSubpassWasSecondary = false; 4135 4136 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++) 4137 { 4138 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary)) 4139 { 4140 subpassIsSecondary.push_back(true); 4141 lastSubpassWasSecondary = true; 4142 } 4143 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE) 4144 { 4145 subpassIsSecondary.push_back(false); 4146 lastSubpassWasSecondary = false; 4147 } 4148 else 4149 DE_FATAL("Unknown commandBuffer"); 4150 } 4151 } 4152 4153 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy) 4154 { 4155 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++) 4156 { 4157 if (!isLazy[attachmentNdx]) 4158 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng))); 4159 else 4160 clearValues.push_back(nothing<VkClearValue>()); 4161 } 4162 } 4163 4164 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments) 4165 { 4166 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++) 4167 { 4168 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR 4169 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR) 4170 { 4171 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng))); 4172 } 4173 else 4174 clearValues.push_back(nothing<VkClearValue>()); 4175 } 4176 } 4177 4178 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass) 4179 { 4180 clearValues.resize(renderPass.getSubpasses().size()); 4181 4182 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++) 4183 { 4184 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx]; 4185 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments(); 4186 4187 clearValues[subpassNdx].resize(colorAttachments.size()); 4188 4189 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++) 4190 { 4191 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx]; 4192 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()]; 4193 4194 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng); 4195 } 4196 } 4197 } 4198 4199 void logSubpassRenderInfo (TestLog& log, 4200 const SubpassRenderInfo& info) 4201 { 4202 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage; 4203 4204 if (info.isSecondary()) 4205 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage; 4206 else 4207 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage; 4208 4209 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++) 4210 { 4211 const ColorClear& colorClear = info.getColorClears()[attachmentNdx]; 4212 4213 log << TestLog::Message << "Clearing color attachment " << attachmentNdx 4214 << ". Offset: " << colorClear.getOffset() 4215 << ", Size: " << colorClear.getSize() 4216 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage; 4217 } 4218 4219 if (info.getDepthStencilClear()) 4220 { 4221 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear(); 4222 4223 log << TestLog::Message << "Clearing depth stencil attachment" 4224 << ". Offset: " << depthStencilClear.getOffset() 4225 << ", Size: " << depthStencilClear.getSize() 4226 << ", Depth: " << depthStencilClear.getDepth() 4227 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage; 4228 } 4229 4230 if (info.getRenderQuad()) 4231 { 4232 const RenderQuad& renderQuad = *info.getRenderQuad(); 4233 4234 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage; 4235 } 4236 } 4237 4238 void logTestCaseInfo (TestLog& log, 4239 const TestConfig& config, 4240 const vector<bool>& attachmentIsLazy, 4241 const vector<Maybe<VkClearValue> >& imageClearValues, 4242 const vector<Maybe<VkClearValue> >& renderPassClearValues, 4243 const vector<SubpassRenderInfo>& subpassRenderInfo) 4244 { 4245 const RenderPass& renderPass = config.renderPass; 4246 4247 logRenderPassInfo(log, renderPass); 4248 4249 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size()); 4250 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size()); 4251 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size()); 4252 4253 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage; 4254 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage; 4255 4256 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++) 4257 { 4258 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx)); 4259 4260 if (attachmentIsLazy[attachmentNdx]) 4261 log << TestLog::Message << "Is lazy." << TestLog::EndMessage; 4262 4263 if (imageClearValues[attachmentNdx]) 4264 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage; 4265 4266 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx]) 4267 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage; 4268 } 4269 4270 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++) 4271 { 4272 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx)); 4273 4274 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]); 4275 } 4276 } 4277 4278 float roundToViewport (float x, deUint32 offset, deUint32 size) 4279 { 4280 const float origin = (float)(offset) + ((float(size) / 2.0f)); 4281 const float p = (float)(size) / 2.0f; 4282 const deInt32 xi = deRoundFloatToInt32(origin + (p * x)); 4283 4284 return (((float)xi) - origin) / p; 4285 } 4286 4287 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config) 4288 { 4289 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes; 4290 const vector<Subpass>& subpasses = renderPass.getSubpasses(); 4291 bool lastSubpassWasSecondary = false; 4292 4293 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++) 4294 { 4295 const Subpass& subpass = subpasses[subpassNdx]; 4296 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY 4297 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false; 4298 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3)); 4299 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3), 4300 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3)); 4301 4302 vector<ColorClear> colorClears; 4303 Maybe<DepthStencilClear> depthStencilClear; 4304 Maybe<RenderQuad> renderQuad; 4305 4306 lastSubpassWasSecondary = subpassIsSecondary; 4307 4308 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR) 4309 { 4310 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments(); 4311 4312 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++) 4313 { 4314 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx]; 4315 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()]; 4316 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3)); 4317 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u), 4318 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u)); 4319 const VkClearColorValue color = randomColorClearValue(attachment, rng); 4320 4321 colorClears.push_back(ColorClear(offset, size, color)); 4322 } 4323 4324 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED) 4325 { 4326 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]; 4327 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3)); 4328 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u), 4329 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u)); 4330 const VkClearValue value = randomClearValue(attachment, rng); 4331 4332 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil)); 4333 } 4334 } 4335 4336 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW) 4337 { 4338 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f; 4339 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f; 4340 4341 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x()); 4342 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x()); 4343 4344 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y()); 4345 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y()); 4346 4347 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1))); 4348 } 4349 4350 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear)); 4351 } 4352 } 4353 4354 void checkTextureFormatSupport (TestLog& log, 4355 const InstanceInterface& vk, 4356 VkPhysicalDevice device, 4357 const vector<Attachment>& attachments) 4358 { 4359 bool supported = true; 4360 4361 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++) 4362 { 4363 const Attachment& attachment = attachments[attachmentNdx]; 4364 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat()); 4365 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order); 4366 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 4367 VkFormatProperties properties; 4368 4369 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties); 4370 4371 if ((properties.optimalTilingFeatures & flags) != flags) 4372 { 4373 supported = false; 4374 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage; 4375 } 4376 } 4377 4378 if (!supported) 4379 TCU_THROW(NotSupportedError, "Format not supported"); 4380 } 4381 4382 tcu::TestStatus renderPassTest (Context& context, TestConfig config) 4383 { 4384 const UVec2 targetSize = config.targetSize; 4385 const UVec2 renderPos = config.renderPos; 4386 const UVec2 renderSize = config.renderSize; 4387 const RenderPass& renderPassInfo = config.renderPass; 4388 4389 TestLog& log = context.getTestContext().getLog(); 4390 de::Random rng (config.seed); 4391 4392 vector<bool> attachmentIsLazy; 4393 vector<VkImageUsageFlags> attachmentImageUsage; 4394 vector<Maybe<VkClearValue> > imageClearValues; 4395 vector<Maybe<VkClearValue> > renderPassClearValues; 4396 4397 vector<bool> subpassIsSecondary; 4398 vector<SubpassRenderInfo> subpassRenderInfo; 4399 vector<vector<VkClearColorValue> > subpassColorClearValues; 4400 4401 if (config.allocationKind == ALLOCATION_KIND_DEDICATED) 4402 { 4403 const std::string extensionName("VK_KHR_dedicated_allocation"); 4404 4405 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName)) 4406 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 4407 } 4408 4409 if (!renderPassInfo.getInputAspects().empty()) 4410 { 4411 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2"))) 4412 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported."); 4413 } 4414 4415 { 4416 bool requireDepthStencilLayout = false; 4417 4418 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 4419 { 4420 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4421 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR 4422 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4423 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 4424 { 4425 requireDepthStencilLayout = true; 4426 break; 4427 } 4428 } 4429 4430 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++) 4431 { 4432 const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]); 4433 4434 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 4435 { 4436 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4437 || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 4438 { 4439 requireDepthStencilLayout = true; 4440 break; 4441 } 4442 } 4443 4444 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 4445 { 4446 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4447 || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 4448 { 4449 requireDepthStencilLayout = true; 4450 break; 4451 } 4452 } 4453 4454 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++) 4455 { 4456 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4457 || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 4458 { 4459 requireDepthStencilLayout = true; 4460 break; 4461 } 4462 } 4463 4464 if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR 4465 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR) 4466 { 4467 requireDepthStencilLayout = true; 4468 break; 4469 } 4470 } 4471 4472 if (requireDepthStencilLayout && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2"))) 4473 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported"); 4474 } 4475 4476 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory); 4477 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy); 4478 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues); 4479 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments()); 4480 4481 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes); 4482 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo); 4483 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config); 4484 4485 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo); 4486 4487 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments()); 4488 4489 { 4490 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()); 4491 4492 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage; 4493 4494 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++) 4495 { 4496 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments) 4497 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments."); 4498 } 4499 } 4500 4501 { 4502 const InstanceInterface& vki = context.getInstanceInterface(); 4503 const VkPhysicalDevice& physDevice = context.getPhysicalDevice(); 4504 const VkDevice device = context.getDevice(); 4505 const DeviceInterface& vk = context.getDeviceInterface(); 4506 const VkQueue queue = context.getUniversalQueue(); 4507 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex(); 4508 Allocator& allocator = context.getDefaultAllocator(); 4509 4510 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo)); 4511 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0)); 4512 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4513 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4514 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4515 4516 vector<de::SharedPtr<AttachmentResources> > attachmentResources; 4517 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers; 4518 vector<VkImage> attachmentImages; 4519 vector<VkImageView> attachmentViews; 4520 vector<pair<VkImageView, VkImageView> > inputAttachmentViews; 4521 4522 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 4523 { 4524 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx]; 4525 4526 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind))); 4527 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView()); 4528 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage()); 4529 4530 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews()); 4531 } 4532 4533 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4534 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues); 4535 endCommandBuffer(vk, *initializeImagesCommandBuffer); 4536 4537 { 4538 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews)); 4539 4540 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++) 4541 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments(), config.allocationKind))); 4542 4543 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4544 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes); 4545 endCommandBuffer(vk, *renderCommandBuffer); 4546 4547 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4548 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize); 4549 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer); 4550 { 4551 const VkCommandBuffer commandBuffers[] = 4552 { 4553 *initializeImagesCommandBuffer, 4554 *renderCommandBuffer, 4555 *readImagesToBuffersCommandBuffer 4556 }; 4557 const Unique<VkFence> fence (createFence(vk, device, 0u)); 4558 4559 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence); 4560 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull); 4561 } 4562 } 4563 4564 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config)) 4565 return tcu::TestStatus::pass("Pass"); 4566 else 4567 return tcu::TestStatus::fail("Result verification failed"); 4568 } 4569 } 4570 4571 static const VkFormat s_coreColorFormats[] = 4572 { 4573 VK_FORMAT_R5G6B5_UNORM_PACK16, 4574 VK_FORMAT_R8_UNORM, 4575 VK_FORMAT_R8_SNORM, 4576 VK_FORMAT_R8_UINT, 4577 VK_FORMAT_R8_SINT, 4578 VK_FORMAT_R8G8_UNORM, 4579 VK_FORMAT_R8G8_SNORM, 4580 VK_FORMAT_R8G8_UINT, 4581 VK_FORMAT_R8G8_SINT, 4582 VK_FORMAT_R8G8B8A8_UNORM, 4583 VK_FORMAT_R8G8B8A8_SNORM, 4584 VK_FORMAT_R8G8B8A8_UINT, 4585 VK_FORMAT_R8G8B8A8_SINT, 4586 VK_FORMAT_R8G8B8A8_SRGB, 4587 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 4588 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 4589 VK_FORMAT_A8B8G8R8_UINT_PACK32, 4590 VK_FORMAT_A8B8G8R8_SINT_PACK32, 4591 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 4592 VK_FORMAT_B8G8R8A8_UNORM, 4593 VK_FORMAT_B8G8R8A8_SRGB, 4594 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 4595 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4596 VK_FORMAT_A2B10G10R10_UINT_PACK32, 4597 VK_FORMAT_R16_UNORM, 4598 VK_FORMAT_R16_SNORM, 4599 VK_FORMAT_R16_UINT, 4600 VK_FORMAT_R16_SINT, 4601 VK_FORMAT_R16_SFLOAT, 4602 VK_FORMAT_R16G16_UNORM, 4603 VK_FORMAT_R16G16_SNORM, 4604 VK_FORMAT_R16G16_UINT, 4605 VK_FORMAT_R16G16_SINT, 4606 VK_FORMAT_R16G16_SFLOAT, 4607 VK_FORMAT_R16G16B16A16_UNORM, 4608 VK_FORMAT_R16G16B16A16_SNORM, 4609 VK_FORMAT_R16G16B16A16_UINT, 4610 VK_FORMAT_R16G16B16A16_SINT, 4611 VK_FORMAT_R16G16B16A16_SFLOAT, 4612 VK_FORMAT_R32_UINT, 4613 VK_FORMAT_R32_SINT, 4614 VK_FORMAT_R32_SFLOAT, 4615 VK_FORMAT_R32G32_UINT, 4616 VK_FORMAT_R32G32_SINT, 4617 VK_FORMAT_R32G32_SFLOAT, 4618 VK_FORMAT_R32G32B32A32_UINT, 4619 VK_FORMAT_R32G32B32A32_SINT, 4620 VK_FORMAT_R32G32B32A32_SFLOAT 4621 }; 4622 4623 static const VkFormat s_coreDepthStencilFormats[] = 4624 { 4625 VK_FORMAT_D16_UNORM, 4626 4627 VK_FORMAT_X8_D24_UNORM_PACK32, 4628 VK_FORMAT_D32_SFLOAT, 4629 4630 VK_FORMAT_D24_UNORM_S8_UINT, 4631 VK_FORMAT_D32_SFLOAT_S8_UINT 4632 }; 4633 4634 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4635 { 4636 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 }; 4637 const VkAttachmentLoadOp loadOps[] = 4638 { 4639 VK_ATTACHMENT_LOAD_OP_LOAD, 4640 VK_ATTACHMENT_LOAD_OP_CLEAR, 4641 VK_ATTACHMENT_LOAD_OP_DONT_CARE 4642 }; 4643 4644 const VkAttachmentStoreOp storeOps[] = 4645 { 4646 VK_ATTACHMENT_STORE_OP_STORE, 4647 VK_ATTACHMENT_STORE_OP_DONT_CARE 4648 }; 4649 4650 const VkImageLayout initialAndFinalColorLayouts[] = 4651 { 4652 VK_IMAGE_LAYOUT_GENERAL, 4653 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4654 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4655 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4656 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4657 }; 4658 4659 const VkImageLayout initialAndFinalDepthStencilLayouts[] = 4660 { 4661 VK_IMAGE_LAYOUT_GENERAL, 4662 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 4663 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, 4664 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4665 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4666 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4667 }; 4668 4669 const VkImageLayout subpassLayouts[] = 4670 { 4671 VK_IMAGE_LAYOUT_GENERAL, 4672 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 4673 }; 4674 4675 const VkImageLayout depthStencilLayouts[] = 4676 { 4677 VK_IMAGE_LAYOUT_GENERAL, 4678 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL 4679 }; 4680 4681 const TestConfig::RenderTypes renderCommands[] = 4682 { 4683 TestConfig::RENDERTYPES_NONE, 4684 TestConfig::RENDERTYPES_CLEAR, 4685 TestConfig::RENDERTYPES_DRAW, 4686 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW, 4687 }; 4688 4689 const TestConfig::CommandBufferTypes commandBuffers[] = 4690 { 4691 TestConfig::COMMANDBUFFERTYPES_INLINE, 4692 TestConfig::COMMANDBUFFERTYPES_SECONDARY, 4693 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY 4694 }; 4695 4696 const TestConfig::ImageMemory imageMemories[] = 4697 { 4698 TestConfig::IMAGEMEMORY_STRICT, 4699 TestConfig::IMAGEMEMORY_LAZY, 4700 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY 4701 }; 4702 4703 const UVec2 targetSizes[] = 4704 { 4705 UVec2(64, 64), 4706 UVec2(63, 65) 4707 }; 4708 4709 const UVec2 renderPositions[] = 4710 { 4711 UVec2(0, 0), 4712 UVec2(3, 17) 4713 }; 4714 4715 const UVec2 renderSizes[] = 4716 { 4717 UVec2(32, 32), 4718 UVec2(60, 47) 4719 }; 4720 4721 tcu::TestContext& testCtx = group->getTestContext(); 4722 de::Random rng (1433774382u); 4723 4724 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++) 4725 { 4726 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx]; 4727 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200); 4728 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str())); 4729 4730 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++) 4731 { 4732 const bool useDepthStencil = rng.getBool(); 4733 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL; 4734 vector<Attachment> attachments; 4735 vector<AttachmentReference> colorAttachmentReferences; 4736 4737 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++) 4738 { 4739 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4740 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 4741 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4742 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4743 4744 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4745 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4746 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 4747 4748 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4749 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4750 4751 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4752 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 4753 } 4754 4755 if (useDepthStencil) 4756 { 4757 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4758 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats)); 4759 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4760 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4761 4762 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)); 4763 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)); 4764 4765 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4766 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4767 4768 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts)); 4769 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4770 } 4771 4772 { 4773 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 4774 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 4775 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 4776 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>())); 4777 const vector<SubpassDependency> deps; 4778 4779 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx); 4780 const RenderPass renderPass (attachments, subpasses, deps); 4781 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 4782 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 4783 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 4784 4785 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind)); 4786 } 4787 } 4788 4789 group->addChild(attachmentCountGroup.release()); 4790 } 4791 } 4792 4793 template<typename T> 4794 T chooseRandom (de::Random& rng, const set<T>& values) 4795 { 4796 size_t ndx = ((size_t)rng.getUint32()) % values.size(); 4797 typename set<T>::const_iterator iter = values.begin(); 4798 4799 for (; ndx > 0; ndx--) 4800 iter++; 4801 4802 return *iter; 4803 } 4804 4805 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4806 { 4807 const deUint32 attachmentCounts[] = { 4, 8 }; 4808 const VkAttachmentLoadOp loadOps[] = 4809 { 4810 VK_ATTACHMENT_LOAD_OP_LOAD, 4811 VK_ATTACHMENT_LOAD_OP_CLEAR, 4812 VK_ATTACHMENT_LOAD_OP_DONT_CARE 4813 }; 4814 4815 const VkAttachmentStoreOp storeOps[] = 4816 { 4817 VK_ATTACHMENT_STORE_OP_STORE, 4818 VK_ATTACHMENT_STORE_OP_DONT_CARE 4819 }; 4820 4821 const VkImageLayout initialAndFinalColorLayouts[] = 4822 { 4823 VK_IMAGE_LAYOUT_GENERAL, 4824 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4825 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4826 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4827 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4828 }; 4829 4830 const VkImageLayout initialAndFinalDepthStencilLayouts[] = 4831 { 4832 VK_IMAGE_LAYOUT_GENERAL, 4833 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 4834 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, 4835 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4836 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4837 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4838 }; 4839 4840 const VkImageLayout subpassLayouts[] = 4841 { 4842 VK_IMAGE_LAYOUT_GENERAL, 4843 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4844 }; 4845 4846 enum AllocationType 4847 { 4848 // Each pass uses one more attachmen than previous one 4849 ALLOCATIONTYPE_GROW, 4850 // Each pass uses one less attachment than previous one 4851 ALLOCATIONTYPE_SHRINK, 4852 // Each pass drops one attachment and picks up new one 4853 ALLOCATIONTYPE_ROLL, 4854 // Start by growing and end by shrinking 4855 ALLOCATIONTYPE_GROW_SHRINK, 4856 // Each subpass has single input and single output attachment 4857 ALLOCATIONTYPE_IO_CHAIN, 4858 // Each subpass has multiple inputs and multiple outputs attachment 4859 ALLOCATIONTYPE_IO_GENERIC 4860 }; 4861 4862 const AllocationType allocationTypes[] = 4863 { 4864 ALLOCATIONTYPE_GROW, 4865 ALLOCATIONTYPE_SHRINK, 4866 ALLOCATIONTYPE_ROLL, 4867 ALLOCATIONTYPE_GROW_SHRINK, 4868 ALLOCATIONTYPE_IO_CHAIN, 4869 ALLOCATIONTYPE_IO_GENERIC 4870 }; 4871 4872 const char* const allocationTypeStr[] = 4873 { 4874 "grow", 4875 "shrink", 4876 "roll", 4877 "grow_shrink", 4878 "input_output_chain", 4879 "input_output", 4880 }; 4881 4882 const TestConfig::RenderTypes renderCommands[] = 4883 { 4884 TestConfig::RENDERTYPES_NONE, 4885 TestConfig::RENDERTYPES_CLEAR, 4886 TestConfig::RENDERTYPES_DRAW, 4887 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW, 4888 }; 4889 4890 const TestConfig::CommandBufferTypes commandBuffers[] = 4891 { 4892 TestConfig::COMMANDBUFFERTYPES_INLINE, 4893 TestConfig::COMMANDBUFFERTYPES_SECONDARY, 4894 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY 4895 }; 4896 4897 const TestConfig::ImageMemory imageMemories[] = 4898 { 4899 TestConfig::IMAGEMEMORY_STRICT, 4900 TestConfig::IMAGEMEMORY_LAZY, 4901 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY 4902 }; 4903 4904 const UVec2 targetSizes[] = 4905 { 4906 UVec2(64, 64), 4907 UVec2(63, 65) 4908 }; 4909 4910 const UVec2 renderPositions[] = 4911 { 4912 UVec2(0, 0), 4913 UVec2(3, 17) 4914 }; 4915 4916 const UVec2 renderSizes[] = 4917 { 4918 UVec2(32, 32), 4919 UVec2(60, 47) 4920 }; 4921 4922 tcu::TestContext& testCtx = group->getTestContext(); 4923 de::Random rng (3700649827u); 4924 4925 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++) 4926 { 4927 const AllocationType allocationType = allocationTypes[allocationTypeNdx]; 4928 const size_t testCaseCount = 100; 4929 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx])); 4930 4931 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++) 4932 { 4933 if (allocationType == ALLOCATIONTYPE_IO_GENERIC) 4934 { 4935 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u; 4936 const deUint32 subpassCount = 4u + rng.getUint32() % 31u; 4937 vector<Attachment> attachments; 4938 4939 set<deUint32> definedAttachments; 4940 4941 vector<Subpass> subpasses; 4942 set<deUint32> colorAttachments; 4943 set<deUint32> depthStencilAttachments; 4944 4945 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++) 4946 { 4947 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f; 4948 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4949 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4950 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4951 4952 const VkImageLayout initialLayout = isDepthStencilAttachment 4953 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) 4954 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4955 const VkImageLayout finalizeLayout = isDepthStencilAttachment 4956 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) 4957 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4958 4959 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4960 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4961 4962 if (isDepthStencilAttachment) 4963 { 4964 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats)); 4965 4966 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR 4967 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) 4968 definedAttachments.insert(attachmentIndex); 4969 4970 depthStencilAttachments.insert(attachmentIndex); 4971 4972 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4973 } 4974 else 4975 { 4976 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 4977 4978 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) 4979 definedAttachments.insert(attachmentIndex); 4980 4981 colorAttachments.insert(attachmentIndex); 4982 4983 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4984 } 4985 } 4986 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>()); 4987 vector<SubpassDependency> deps; 4988 4989 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++) 4990 { 4991 const deUint32 colorAttachmentCount = depthStencilAttachments.empty() 4992 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size()) 4993 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u); 4994 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1); 4995 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool()); 4996 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount); 4997 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount); 4998 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment 4999 ? just(chooseRandom(rng, depthStencilAttachments)) 5000 : nothing<deUint32>()); 5001 std::vector<deUint32> subpassPreserveAttachments; 5002 5003 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount); 5004 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount); 5005 5006 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++) 5007 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]); 5008 5009 if (depthStencilAttachment) 5010 definedAttachments.insert(*depthStencilAttachment); 5011 5012 { 5013 std::vector<AttachmentReference> inputAttachmentReferences; 5014 std::vector<AttachmentReference> colorAttachmentReferences; 5015 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL); 5016 5017 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++) 5018 { 5019 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx]; 5020 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts 5021 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL; 5022 5023 if (lastUseOfAttachment[colorAttachmentIndex]) 5024 { 5025 const bool byRegion = rng.getBool(); 5026 5027 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex, 5028 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5029 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5030 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5031 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5032 5033 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5034 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5035 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5036 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5037 5038 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5039 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 5040 5041 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5042 } 5043 5044 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex); 5045 5046 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout)); 5047 } 5048 5049 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++) 5050 { 5051 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx]; 5052 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts 5053 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL; 5054 5055 if(lastUseOfAttachment[inputAttachmentIndex]) 5056 { 5057 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex) 5058 { 5059 deps.push_back(SubpassDependency(subpassIndex, subpassIndex, 5060 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5061 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5062 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5063 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5064 5065 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5066 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5067 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5068 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5069 5070 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5071 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5072 5073 VK_DEPENDENCY_BY_REGION_BIT)); 5074 } 5075 else 5076 { 5077 const bool byRegion = rng.getBool(); 5078 5079 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex, 5080 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5081 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5082 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5083 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5084 5085 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5086 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5087 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5088 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5089 5090 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5091 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5092 5093 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5094 } 5095 5096 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex); 5097 5098 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout)); 5099 } 5100 } 5101 5102 if (depthStencilAttachment) 5103 { 5104 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts 5105 if (lastUseOfAttachment[*depthStencilAttachment]) 5106 { 5107 if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex) 5108 { 5109 deps.push_back(SubpassDependency(subpassIndex, subpassIndex, 5110 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5111 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5112 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5113 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5114 5115 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5116 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5117 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5118 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5119 5120 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5121 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5122 5123 VK_DEPENDENCY_BY_REGION_BIT)); 5124 } 5125 else 5126 { 5127 const bool byRegion = rng.getBool(); 5128 5129 deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex, 5130 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5131 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5132 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5133 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5134 5135 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5136 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5137 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5138 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5139 5140 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5141 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5142 5143 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5144 } 5145 } 5146 5147 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex); 5148 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL); 5149 } 5150 else 5151 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL); 5152 5153 vector<deUint32> preserveAttachments; 5154 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++) 5155 { 5156 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex) 5157 preserveAttachments.push_back(attachmentIndex); 5158 } 5159 5160 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5161 inputAttachmentReferences, 5162 colorAttachmentReferences, 5163 vector<AttachmentReference>(), 5164 depthStencilAttachmentReference, 5165 preserveAttachments)); 5166 } 5167 } 5168 { 5169 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 5170 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 5171 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 5172 5173 const string testCaseName = de::toString(testCaseNdx); 5174 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 5175 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 5176 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 5177 5178 const RenderPass renderPass (attachments, subpasses, deps); 5179 5180 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind)); 5181 } 5182 } 5183 else 5184 { 5185 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts)); 5186 vector<Attachment> attachments; 5187 vector<Subpass> subpasses; 5188 5189 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++) 5190 { 5191 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 5192 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 5193 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 5194 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 5195 5196 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 5197 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 5198 5199 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 5200 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 5201 5202 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 5203 } 5204 5205 if (allocationType == ALLOCATIONTYPE_GROW) 5206 { 5207 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5208 { 5209 vector<AttachmentReference> colorAttachmentReferences; 5210 5211 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++) 5212 { 5213 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5214 5215 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5216 } 5217 5218 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5219 vector<AttachmentReference>(), 5220 colorAttachmentReferences, 5221 vector<AttachmentReference>(), 5222 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5223 vector<deUint32>())); 5224 } 5225 } 5226 else if (allocationType == ALLOCATIONTYPE_SHRINK) 5227 { 5228 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5229 { 5230 vector<AttachmentReference> colorAttachmentReferences; 5231 5232 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++) 5233 { 5234 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5235 5236 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5237 } 5238 5239 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5240 vector<AttachmentReference>(), 5241 colorAttachmentReferences, 5242 vector<AttachmentReference>(), 5243 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5244 vector<deUint32>())); 5245 } 5246 } 5247 else if (allocationType == ALLOCATIONTYPE_ROLL) 5248 { 5249 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++) 5250 { 5251 vector<AttachmentReference> colorAttachmentReferences; 5252 5253 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++) 5254 { 5255 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5256 5257 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout)); 5258 } 5259 5260 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5261 vector<AttachmentReference>(), 5262 colorAttachmentReferences, 5263 vector<AttachmentReference>(), 5264 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5265 vector<deUint32>())); 5266 } 5267 } 5268 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK) 5269 { 5270 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5271 { 5272 vector<AttachmentReference> colorAttachmentReferences; 5273 5274 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++) 5275 { 5276 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5277 5278 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5279 } 5280 5281 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5282 vector<AttachmentReference>(), 5283 colorAttachmentReferences, 5284 vector<AttachmentReference>(), 5285 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5286 vector<deUint32>())); 5287 } 5288 5289 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5290 { 5291 vector<AttachmentReference> colorAttachmentReferences; 5292 5293 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++) 5294 { 5295 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5296 5297 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5298 } 5299 5300 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5301 vector<AttachmentReference>(), 5302 colorAttachmentReferences, 5303 vector<AttachmentReference>(), 5304 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5305 vector<deUint32>())); 5306 } 5307 } 5308 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN) 5309 { 5310 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5311 vector<AttachmentReference>(), 5312 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))), 5313 vector<AttachmentReference>(), 5314 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5315 vector<deUint32>())); 5316 5317 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++) 5318 { 5319 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5320 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5321 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))), 5322 vector<AttachmentReference>(), 5323 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5324 vector<deUint32>())); 5325 } 5326 } 5327 else 5328 DE_FATAL("Unknown allocation type"); 5329 5330 { 5331 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 5332 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 5333 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 5334 5335 const string testCaseName = de::toString(testCaseNdx); 5336 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 5337 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 5338 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 5339 5340 vector<SubpassDependency> deps; 5341 5342 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++) 5343 { 5344 const bool byRegion = rng.getBool(); 5345 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1, 5346 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5347 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5348 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5349 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5350 5351 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5352 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5353 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5354 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5355 5356 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5357 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 5358 5359 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5360 } 5361 5362 const RenderPass renderPass (attachments, subpasses, deps); 5363 5364 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind)); 5365 } 5366 } 5367 } 5368 group->addChild(allocationTypeGroup.release()); 5369 } 5370 } 5371 5372 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5373 { 5374 const UVec2 targetSize (64, 64); 5375 const UVec2 renderPos (0, 0); 5376 const UVec2 renderSize (64, 64); 5377 5378 // color 5379 { 5380 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5381 VK_SAMPLE_COUNT_1_BIT, 5382 VK_ATTACHMENT_LOAD_OP_CLEAR, 5383 VK_ATTACHMENT_STORE_OP_STORE, 5384 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5385 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5386 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5387 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5388 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5389 0u, 5390 vector<AttachmentReference>(), 5391 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5392 vector<AttachmentReference>(), 5393 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5394 vector<deUint32>())), 5395 vector<SubpassDependency>()); 5396 5397 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5398 } 5399 5400 // depth 5401 { 5402 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, 5403 VK_SAMPLE_COUNT_1_BIT, 5404 VK_ATTACHMENT_LOAD_OP_CLEAR, 5405 VK_ATTACHMENT_STORE_OP_STORE, 5406 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5407 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5408 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5409 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5410 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5411 0u, 5412 vector<AttachmentReference>(), 5413 vector<AttachmentReference>(), 5414 vector<AttachmentReference>(), 5415 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5416 vector<deUint32>())), 5417 vector<SubpassDependency>()); 5418 5419 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5420 } 5421 5422 // stencil 5423 { 5424 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT, 5425 VK_SAMPLE_COUNT_1_BIT, 5426 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5427 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5428 VK_ATTACHMENT_LOAD_OP_CLEAR, 5429 VK_ATTACHMENT_STORE_OP_STORE, 5430 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5431 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5432 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5433 0u, 5434 vector<AttachmentReference>(), 5435 vector<AttachmentReference>(), 5436 vector<AttachmentReference>(), 5437 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5438 vector<deUint32>())), 5439 vector<SubpassDependency>()); 5440 5441 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5442 } 5443 5444 // depth_stencil 5445 { 5446 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT, 5447 VK_SAMPLE_COUNT_1_BIT, 5448 VK_ATTACHMENT_LOAD_OP_CLEAR, 5449 VK_ATTACHMENT_STORE_OP_STORE, 5450 VK_ATTACHMENT_LOAD_OP_CLEAR, 5451 VK_ATTACHMENT_STORE_OP_STORE, 5452 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5453 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5454 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5455 0u, 5456 vector<AttachmentReference>(), 5457 vector<AttachmentReference>(), 5458 vector<AttachmentReference>(), 5459 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5460 vector<deUint32>())), 5461 vector<SubpassDependency>()); 5462 5463 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5464 } 5465 5466 // color_depth 5467 { 5468 const Attachment attachments[] = 5469 { 5470 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5471 VK_SAMPLE_COUNT_1_BIT, 5472 VK_ATTACHMENT_LOAD_OP_CLEAR, 5473 VK_ATTACHMENT_STORE_OP_STORE, 5474 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5475 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5476 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5477 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5478 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, 5479 VK_SAMPLE_COUNT_1_BIT, 5480 VK_ATTACHMENT_LOAD_OP_CLEAR, 5481 VK_ATTACHMENT_STORE_OP_STORE, 5482 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5483 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5484 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5485 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5486 }; 5487 5488 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5489 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5490 0u, 5491 vector<AttachmentReference>(), 5492 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5493 vector<AttachmentReference>(), 5494 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5495 vector<deUint32>())), 5496 vector<SubpassDependency>()); 5497 5498 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5499 } 5500 5501 // color_stencil 5502 { 5503 const Attachment attachments[] = 5504 { 5505 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5506 VK_SAMPLE_COUNT_1_BIT, 5507 VK_ATTACHMENT_LOAD_OP_CLEAR, 5508 VK_ATTACHMENT_STORE_OP_STORE, 5509 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5510 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5511 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5512 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5513 Attachment(VK_FORMAT_S8_UINT, 5514 VK_SAMPLE_COUNT_1_BIT, 5515 VK_ATTACHMENT_LOAD_OP_CLEAR, 5516 VK_ATTACHMENT_STORE_OP_STORE, 5517 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5518 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5519 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5520 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5521 }; 5522 5523 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5524 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5525 0u, 5526 vector<AttachmentReference>(), 5527 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5528 vector<AttachmentReference>(), 5529 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5530 vector<deUint32>())), 5531 vector<SubpassDependency>()); 5532 5533 5534 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5535 } 5536 5537 // color_depth_stencil 5538 { 5539 const Attachment attachments[] = 5540 { 5541 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5542 VK_SAMPLE_COUNT_1_BIT, 5543 VK_ATTACHMENT_LOAD_OP_CLEAR, 5544 VK_ATTACHMENT_STORE_OP_STORE, 5545 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5546 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5547 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5548 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5549 Attachment(VK_FORMAT_D24_UNORM_S8_UINT, 5550 VK_SAMPLE_COUNT_1_BIT, 5551 VK_ATTACHMENT_LOAD_OP_CLEAR, 5552 VK_ATTACHMENT_STORE_OP_STORE, 5553 VK_ATTACHMENT_LOAD_OP_CLEAR, 5554 VK_ATTACHMENT_STORE_OP_STORE, 5555 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5556 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5557 }; 5558 5559 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5560 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5561 0u, 5562 vector<AttachmentReference>(), 5563 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5564 vector<AttachmentReference>(), 5565 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5566 vector<deUint32>())), 5567 vector<SubpassDependency>()); 5568 5569 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5570 } 5571 } 5572 5573 std::string formatToName (VkFormat format) 5574 { 5575 const std::string formatStr = de::toString(format); 5576 const std::string prefix = "VK_FORMAT_"; 5577 5578 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix); 5579 5580 return de::toLower(formatStr.substr(prefix.length())); 5581 } 5582 5583 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5584 { 5585 tcu::TestContext& testCtx = group->getTestContext(); 5586 5587 const UVec2 targetSize (64, 64); 5588 const UVec2 renderPos (0, 0); 5589 const UVec2 renderSize (64, 64); 5590 5591 const struct 5592 { 5593 const char* const str; 5594 const VkAttachmentStoreOp op; 5595 } storeOps[] = 5596 { 5597 { "store", VK_ATTACHMENT_STORE_OP_STORE }, 5598 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE } 5599 }; 5600 5601 const struct 5602 { 5603 const char* const str; 5604 const VkAttachmentLoadOp op; 5605 } loadOps[] = 5606 { 5607 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR }, 5608 { "load", VK_ATTACHMENT_LOAD_OP_LOAD }, 5609 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE } 5610 }; 5611 5612 const struct 5613 { 5614 const char* const str; 5615 const TestConfig::RenderTypes types; 5616 } renderTypes[] = 5617 { 5618 { "clear", TestConfig::RENDERTYPES_CLEAR }, 5619 { "draw", TestConfig::RENDERTYPES_DRAW }, 5620 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW } 5621 }; 5622 5623 // Color formats 5624 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++) 5625 { 5626 const VkFormat format = s_coreColorFormats[formatNdx]; 5627 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str())); 5628 5629 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5630 { 5631 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5632 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5633 5634 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5635 { 5636 const RenderPass renderPass (vector<Attachment>(1, Attachment(format, 5637 VK_SAMPLE_COUNT_1_BIT, 5638 loadOp, 5639 VK_ATTACHMENT_STORE_OP_STORE, 5640 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5641 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5642 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5643 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5644 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5645 0u, 5646 vector<AttachmentReference>(), 5647 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5648 vector<AttachmentReference>(), 5649 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5650 vector<deUint32>())), 5651 vector<SubpassDependency>()); 5652 5653 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5654 } 5655 5656 formatGroup->addChild(loadOpGroup.release()); 5657 } 5658 5659 { 5660 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input")); 5661 5662 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5663 { 5664 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5665 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5666 5667 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++) 5668 { 5669 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op; 5670 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str)); 5671 5672 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++) 5673 { 5674 const bool useInputAspect = useInputAspectNdx != 0; 5675 5676 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5677 { 5678 { 5679 vector<Attachment> attachments; 5680 vector<Subpass> subpasses; 5681 vector<SubpassDependency> deps; 5682 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 5683 5684 attachments.push_back(Attachment(format, 5685 VK_SAMPLE_COUNT_1_BIT, 5686 loadOp, 5687 storeOp, 5688 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5689 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5690 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5691 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5692 5693 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 5694 VK_SAMPLE_COUNT_1_BIT, 5695 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5696 VK_ATTACHMENT_STORE_OP_STORE, 5697 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5698 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5699 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5700 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5701 5702 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5703 0u, 5704 vector<AttachmentReference>(), 5705 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5706 vector<AttachmentReference>(), 5707 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5708 vector<deUint32>())); 5709 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5710 0u, 5711 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5712 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5713 vector<AttachmentReference>(), 5714 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5715 vector<deUint32>())); 5716 5717 deps.push_back(SubpassDependency(0, 1, 5718 5719 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5720 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5721 5722 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5723 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5724 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5725 5726 if (useInputAspect) 5727 { 5728 const VkInputAttachmentAspectReferenceKHR inputAspect = 5729 { 5730 0u, 5731 0u, 5732 VK_IMAGE_ASPECT_COLOR_BIT 5733 }; 5734 5735 inputAspects.push_back(inputAspect); 5736 } 5737 5738 { 5739 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5740 5741 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 5742 } 5743 } 5744 { 5745 vector<Attachment> attachments; 5746 vector<Subpass> subpasses; 5747 vector<SubpassDependency> deps; 5748 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 5749 5750 attachments.push_back(Attachment(format, 5751 VK_SAMPLE_COUNT_1_BIT, 5752 loadOp, 5753 storeOp, 5754 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5755 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5756 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5757 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5758 5759 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5760 0u, 5761 vector<AttachmentReference>(), 5762 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5763 vector<AttachmentReference>(), 5764 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5765 vector<deUint32>())); 5766 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5767 0u, 5768 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 5769 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 5770 vector<AttachmentReference>(), 5771 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5772 vector<deUint32>())); 5773 5774 deps.push_back(SubpassDependency(0, 1, 5775 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5776 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5777 5778 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5779 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5780 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5781 5782 if (useInputAspect) 5783 { 5784 const VkInputAttachmentAspectReferenceKHR inputAspect = 5785 { 5786 0u, 5787 0u, 5788 VK_IMAGE_ASPECT_COLOR_BIT 5789 }; 5790 5791 inputAspects.push_back(inputAspect); 5792 } 5793 5794 { 5795 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5796 5797 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 5798 } 5799 } 5800 } 5801 } 5802 5803 loadOpGroup->addChild(storeOpGroup.release()); 5804 } 5805 5806 inputGroup->addChild(loadOpGroup.release()); 5807 } 5808 5809 formatGroup->addChild(inputGroup.release()); 5810 } 5811 5812 group->addChild(formatGroup.release()); 5813 } 5814 5815 // Depth stencil formats 5816 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++) 5817 { 5818 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx]; 5819 const tcu::TextureFormat format = mapVkFormat(vkFormat); 5820 const bool isStencilAttachment = hasStencilComponent(format.order); 5821 const bool isDepthAttachment = hasDepthComponent(format.order); 5822 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str())); 5823 5824 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5825 { 5826 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5827 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5828 5829 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5830 { 5831 { 5832 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5833 VK_SAMPLE_COUNT_1_BIT, 5834 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5835 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5836 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5837 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5838 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5839 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5840 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5841 0u, 5842 vector<AttachmentReference>(), 5843 vector<AttachmentReference>(), 5844 vector<AttachmentReference>(), 5845 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5846 vector<deUint32>())), 5847 vector<SubpassDependency>()); 5848 5849 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5850 } 5851 5852 if (isStencilAttachment && isDepthAttachment) 5853 { 5854 { 5855 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5856 VK_SAMPLE_COUNT_1_BIT, 5857 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5858 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5859 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5860 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5861 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5862 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5863 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5864 0u, 5865 vector<AttachmentReference>(), 5866 vector<AttachmentReference>(), 5867 vector<AttachmentReference>(), 5868 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR), 5869 vector<deUint32>())), 5870 vector<SubpassDependency>()); 5871 5872 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), string(renderTypes[renderTypeNdx].str) + "_depth_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5873 } 5874 5875 { 5876 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5877 VK_SAMPLE_COUNT_1_BIT, 5878 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5879 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5880 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5881 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5882 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5883 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5884 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5885 0u, 5886 vector<AttachmentReference>(), 5887 vector<AttachmentReference>(), 5888 vector<AttachmentReference>(), 5889 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR), 5890 vector<deUint32>())), 5891 vector<SubpassDependency>()); 5892 5893 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), string(renderTypes[renderTypeNdx].str) + "_stencil_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind)); 5894 } 5895 } 5896 } 5897 5898 formatGroup->addChild(loadOpGroup.release()); 5899 } 5900 5901 { 5902 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input")); 5903 5904 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5905 { 5906 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5907 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5908 5909 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++) 5910 { 5911 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op; 5912 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str)); 5913 5914 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++) 5915 { 5916 const bool useInputAspect = useInputAspectNdx != 0; 5917 5918 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5919 { 5920 { 5921 vector<Attachment> attachments; 5922 vector<Subpass> subpasses; 5923 vector<SubpassDependency> deps; 5924 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 5925 5926 attachments.push_back(Attachment(vkFormat, 5927 VK_SAMPLE_COUNT_1_BIT, 5928 loadOp, 5929 storeOp, 5930 loadOp, 5931 storeOp, 5932 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5933 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 5934 5935 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 5936 VK_SAMPLE_COUNT_1_BIT, 5937 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5938 VK_ATTACHMENT_STORE_OP_STORE, 5939 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5940 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5941 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5942 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5943 5944 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5945 0u, 5946 vector<AttachmentReference>(), 5947 vector<AttachmentReference>(), 5948 vector<AttachmentReference>(), 5949 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5950 vector<deUint32>())); 5951 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5952 0u, 5953 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5954 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5955 vector<AttachmentReference>(), 5956 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5957 vector<deUint32>())); 5958 5959 deps.push_back(SubpassDependency(0, 1, 5960 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5961 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5962 5963 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5964 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5965 0u)); 5966 5967 deps.push_back(SubpassDependency(1, 1, 5968 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5969 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5970 5971 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5972 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5973 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5974 5975 if (useInputAspect) 5976 { 5977 const VkInputAttachmentAspectReferenceKHR inputAspect = 5978 { 5979 0u, 5980 0u, 5981 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 5982 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 5983 }; 5984 5985 inputAspects.push_back(inputAspect); 5986 } 5987 5988 { 5989 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5990 5991 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 5992 } 5993 } 5994 { 5995 vector<Attachment> attachments; 5996 vector<Subpass> subpasses; 5997 vector<SubpassDependency> deps; 5998 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 5999 6000 attachments.push_back(Attachment(vkFormat, 6001 VK_SAMPLE_COUNT_1_BIT, 6002 loadOp, 6003 storeOp, 6004 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6005 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6006 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6007 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6008 6009 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6010 0u, 6011 vector<AttachmentReference>(), 6012 vector<AttachmentReference>(), 6013 vector<AttachmentReference>(), 6014 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6015 vector<deUint32>())); 6016 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6017 0u, 6018 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 6019 vector<AttachmentReference>(), 6020 vector<AttachmentReference>(), 6021 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL), 6022 vector<deUint32>())); 6023 6024 deps.push_back(SubpassDependency(0, 1, 6025 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6026 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6027 6028 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6029 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6030 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6031 6032 6033 if (useInputAspect) 6034 { 6035 const VkInputAttachmentAspectReferenceKHR inputAspect = 6036 { 6037 0u, 6038 0u, 6039 6040 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6041 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6042 }; 6043 6044 inputAspects.push_back(inputAspect); 6045 } 6046 6047 { 6048 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6049 6050 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 6051 } 6052 } 6053 6054 if (isStencilAttachment && isDepthAttachment) 6055 { 6056 // Depth read only 6057 { 6058 vector<Attachment> attachments; 6059 vector<Subpass> subpasses; 6060 vector<SubpassDependency> deps; 6061 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 6062 6063 attachments.push_back(Attachment(vkFormat, 6064 VK_SAMPLE_COUNT_1_BIT, 6065 loadOp, 6066 storeOp, 6067 loadOp, 6068 storeOp, 6069 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6070 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6071 6072 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 6073 VK_SAMPLE_COUNT_1_BIT, 6074 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6075 VK_ATTACHMENT_STORE_OP_STORE, 6076 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6077 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6078 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 6079 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 6080 6081 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6082 0u, 6083 vector<AttachmentReference>(), 6084 vector<AttachmentReference>(), 6085 vector<AttachmentReference>(), 6086 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6087 vector<deUint32>())); 6088 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6089 0u, 6090 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)), 6091 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 6092 vector<AttachmentReference>(), 6093 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 6094 vector<deUint32>())); 6095 6096 deps.push_back(SubpassDependency(0, 1, 6097 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6098 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6099 6100 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6101 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6102 0u)); 6103 6104 if (useInputAspect) 6105 { 6106 const VkInputAttachmentAspectReferenceKHR inputAspect = 6107 { 6108 0u, 6109 0u, 6110 6111 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6112 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6113 }; 6114 6115 inputAspects.push_back(inputAspect); 6116 } 6117 6118 { 6119 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6120 6121 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 6122 } 6123 } 6124 { 6125 vector<Attachment> attachments; 6126 vector<Subpass> subpasses; 6127 vector<SubpassDependency> deps; 6128 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 6129 6130 attachments.push_back(Attachment(vkFormat, 6131 VK_SAMPLE_COUNT_1_BIT, 6132 loadOp, 6133 storeOp, 6134 loadOp, 6135 storeOp, 6136 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6137 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6138 6139 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6140 0u, 6141 vector<AttachmentReference>(), 6142 vector<AttachmentReference>(), 6143 vector<AttachmentReference>(), 6144 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6145 vector<deUint32>())); 6146 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6147 0u, 6148 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)), 6149 vector<AttachmentReference>(), 6150 vector<AttachmentReference>(), 6151 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR), 6152 vector<deUint32>())); 6153 6154 deps.push_back(SubpassDependency(0, 1, 6155 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6156 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6157 6158 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6159 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6160 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6161 6162 deps.push_back(SubpassDependency(1, 1, 6163 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6164 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6165 6166 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6167 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6168 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6169 6170 6171 if (useInputAspect) 6172 { 6173 const VkInputAttachmentAspectReferenceKHR inputAspect = 6174 { 6175 0u, 6176 0u, 6177 6178 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6179 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6180 }; 6181 6182 inputAspects.push_back(inputAspect); 6183 } 6184 6185 { 6186 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6187 6188 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only", string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 6189 } 6190 } 6191 // Stencil read only 6192 { 6193 vector<Attachment> attachments; 6194 vector<Subpass> subpasses; 6195 vector<SubpassDependency> deps; 6196 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 6197 6198 attachments.push_back(Attachment(vkFormat, 6199 VK_SAMPLE_COUNT_1_BIT, 6200 loadOp, 6201 storeOp, 6202 loadOp, 6203 storeOp, 6204 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6205 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6206 6207 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 6208 VK_SAMPLE_COUNT_1_BIT, 6209 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6210 VK_ATTACHMENT_STORE_OP_STORE, 6211 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6212 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6213 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 6214 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 6215 6216 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6217 0u, 6218 vector<AttachmentReference>(), 6219 vector<AttachmentReference>(), 6220 vector<AttachmentReference>(), 6221 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6222 vector<deUint32>())); 6223 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6224 0u, 6225 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)), 6226 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 6227 vector<AttachmentReference>(), 6228 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 6229 vector<deUint32>())); 6230 6231 deps.push_back(SubpassDependency(0, 1, 6232 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6233 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6234 6235 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6236 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6237 0u)); 6238 6239 if (useInputAspect) 6240 { 6241 const VkInputAttachmentAspectReferenceKHR inputAspect = 6242 { 6243 0u, 6244 0u, 6245 6246 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6247 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6248 }; 6249 6250 inputAspects.push_back(inputAspect); 6251 } 6252 6253 { 6254 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6255 6256 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 6257 } 6258 } 6259 { 6260 vector<Attachment> attachments; 6261 vector<Subpass> subpasses; 6262 vector<SubpassDependency> deps; 6263 vector<VkInputAttachmentAspectReferenceKHR> inputAspects; 6264 6265 attachments.push_back(Attachment(vkFormat, 6266 VK_SAMPLE_COUNT_1_BIT, 6267 loadOp, 6268 storeOp, 6269 loadOp, 6270 storeOp, 6271 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6272 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6273 6274 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6275 0u, 6276 vector<AttachmentReference>(), 6277 vector<AttachmentReference>(), 6278 vector<AttachmentReference>(), 6279 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6280 vector<deUint32>())); 6281 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6282 0u, 6283 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)), 6284 vector<AttachmentReference>(), 6285 vector<AttachmentReference>(), 6286 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR), 6287 vector<deUint32>())); 6288 6289 deps.push_back(SubpassDependency(0, 1, 6290 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6291 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6292 6293 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6294 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6295 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6296 6297 deps.push_back(SubpassDependency(1, 1, 6298 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6299 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6300 6301 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6302 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6303 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6304 6305 6306 if (useInputAspect) 6307 { 6308 const VkInputAttachmentAspectReferenceKHR inputAspect = 6309 { 6310 0u, 6311 0u, 6312 6313 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6314 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6315 }; 6316 6317 inputAspects.push_back(inputAspect); 6318 } 6319 6320 { 6321 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6322 6323 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only", string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind)); 6324 } 6325 } 6326 } 6327 } 6328 } 6329 6330 loadOpGroup->addChild(storeOpGroup.release()); 6331 } 6332 6333 inputGroup->addChild(loadOpGroup.release()); 6334 } 6335 6336 formatGroup->addChild(inputGroup.release()); 6337 } 6338 6339 group->addChild(formatGroup.release()); 6340 } 6341 } 6342 6343 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6344 { 6345 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind); 6346 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind); 6347 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind); 6348 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind); 6349 } 6350 6351 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx) 6352 { 6353 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests")); 6354 6355 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED); 6356 6357 return suballocationTestsGroup; 6358 } 6359 6360 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx) 6361 { 6362 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation")); 6363 6364 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED); 6365 6366 return dedicatedAllocationTestsGroup; 6367 } 6368 6369 } // anonymous 6370 6371 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx) 6372 { 6373 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests")); 6374 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx); 6375 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx); 6376 6377 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx)); 6378 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx)); 6379 6380 renderpassTests->addChild(suballocationTestGroup.release()); 6381 renderpassTests->addChild(dedicatedAllocationTestGroup.release()); 6382 6383 return renderpassTests.release(); 6384 } 6385 6386 } // vkt 6387