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: 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: 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<VkInputAttachmentAspectReference> inputAspects = vector<VkInputAttachmentAspectReference>()) 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<VkInputAttachmentAspectReference>& 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<VkInputAttachmentAspectReference> 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 VkInputAttachmentAspectReference& 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 VkRenderPassInputAttachmentAspectCreateInfo inputAspectCreateInfo = 1185 { 1186 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, 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 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 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) 1952 && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) 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) 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) 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 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) 2219 | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ? 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) 2234 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)) 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; 3042 const bool hasDepth = tcu::hasDepthComponent(format.order) 3043 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; 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) 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) 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) 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) 3172 && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)) 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) 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) 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) 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) 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) 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) 3825 inputComponentCount += 1; 3826 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) 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) 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) 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) 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) 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 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation")) 4404 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported"); 4405 } 4406 4407 if (!renderPassInfo.getInputAspects().empty()) 4408 { 4409 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2")) 4410 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported."); 4411 } 4412 4413 { 4414 bool requireDepthStencilLayout = false; 4415 4416 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 4417 { 4418 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4419 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL 4420 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4421 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) 4422 { 4423 requireDepthStencilLayout = true; 4424 break; 4425 } 4426 } 4427 4428 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++) 4429 { 4430 const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]); 4431 4432 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++) 4433 { 4434 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4435 || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) 4436 { 4437 requireDepthStencilLayout = true; 4438 break; 4439 } 4440 } 4441 4442 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++) 4443 { 4444 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4445 || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) 4446 { 4447 requireDepthStencilLayout = true; 4448 break; 4449 } 4450 } 4451 4452 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++) 4453 { 4454 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4455 || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) 4456 { 4457 requireDepthStencilLayout = true; 4458 break; 4459 } 4460 } 4461 4462 if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL 4463 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) 4464 { 4465 requireDepthStencilLayout = true; 4466 break; 4467 } 4468 } 4469 4470 if (requireDepthStencilLayout && !isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2")) 4471 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported"); 4472 } 4473 4474 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory); 4475 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy); 4476 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues); 4477 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments()); 4478 4479 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes); 4480 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo); 4481 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config); 4482 4483 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo); 4484 4485 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments()); 4486 4487 { 4488 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()); 4489 4490 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage; 4491 4492 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++) 4493 { 4494 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments) 4495 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments."); 4496 } 4497 } 4498 4499 { 4500 const InstanceInterface& vki = context.getInstanceInterface(); 4501 const VkPhysicalDevice& physDevice = context.getPhysicalDevice(); 4502 const VkDevice device = context.getDevice(); 4503 const DeviceInterface& vk = context.getDeviceInterface(); 4504 const VkQueue queue = context.getUniversalQueue(); 4505 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex(); 4506 Allocator& allocator = context.getDefaultAllocator(); 4507 4508 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo)); 4509 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0)); 4510 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4511 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4512 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 4513 4514 vector<de::SharedPtr<AttachmentResources> > attachmentResources; 4515 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers; 4516 vector<VkImage> attachmentImages; 4517 vector<VkImageView> attachmentViews; 4518 vector<pair<VkImageView, VkImageView> > inputAttachmentViews; 4519 4520 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++) 4521 { 4522 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx]; 4523 4524 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind))); 4525 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView()); 4526 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage()); 4527 4528 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews()); 4529 } 4530 4531 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4532 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues); 4533 endCommandBuffer(vk, *initializeImagesCommandBuffer); 4534 4535 { 4536 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews)); 4537 4538 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++) 4539 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))); 4540 4541 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4542 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes); 4543 endCommandBuffer(vk, *renderCommandBuffer); 4544 4545 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0); 4546 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize); 4547 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer); 4548 { 4549 const VkCommandBuffer commandBuffers[] = 4550 { 4551 *initializeImagesCommandBuffer, 4552 *renderCommandBuffer, 4553 *readImagesToBuffersCommandBuffer 4554 }; 4555 const Unique<VkFence> fence (createFence(vk, device, 0u)); 4556 4557 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence); 4558 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull); 4559 } 4560 } 4561 4562 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config)) 4563 return tcu::TestStatus::pass("Pass"); 4564 else 4565 return tcu::TestStatus::fail("Result verification failed"); 4566 } 4567 } 4568 4569 static const VkFormat s_coreColorFormats[] = 4570 { 4571 VK_FORMAT_R5G6B5_UNORM_PACK16, 4572 VK_FORMAT_R8_UNORM, 4573 VK_FORMAT_R8_SNORM, 4574 VK_FORMAT_R8_UINT, 4575 VK_FORMAT_R8_SINT, 4576 VK_FORMAT_R8G8_UNORM, 4577 VK_FORMAT_R8G8_SNORM, 4578 VK_FORMAT_R8G8_UINT, 4579 VK_FORMAT_R8G8_SINT, 4580 VK_FORMAT_R8G8B8A8_UNORM, 4581 VK_FORMAT_R8G8B8A8_SNORM, 4582 VK_FORMAT_R8G8B8A8_UINT, 4583 VK_FORMAT_R8G8B8A8_SINT, 4584 VK_FORMAT_R8G8B8A8_SRGB, 4585 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 4586 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 4587 VK_FORMAT_A8B8G8R8_UINT_PACK32, 4588 VK_FORMAT_A8B8G8R8_SINT_PACK32, 4589 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 4590 VK_FORMAT_B8G8R8A8_UNORM, 4591 VK_FORMAT_B8G8R8A8_SRGB, 4592 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 4593 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4594 VK_FORMAT_A2B10G10R10_UINT_PACK32, 4595 VK_FORMAT_R16_UNORM, 4596 VK_FORMAT_R16_SNORM, 4597 VK_FORMAT_R16_UINT, 4598 VK_FORMAT_R16_SINT, 4599 VK_FORMAT_R16_SFLOAT, 4600 VK_FORMAT_R16G16_UNORM, 4601 VK_FORMAT_R16G16_SNORM, 4602 VK_FORMAT_R16G16_UINT, 4603 VK_FORMAT_R16G16_SINT, 4604 VK_FORMAT_R16G16_SFLOAT, 4605 VK_FORMAT_R16G16B16A16_UNORM, 4606 VK_FORMAT_R16G16B16A16_SNORM, 4607 VK_FORMAT_R16G16B16A16_UINT, 4608 VK_FORMAT_R16G16B16A16_SINT, 4609 VK_FORMAT_R16G16B16A16_SFLOAT, 4610 VK_FORMAT_R32_UINT, 4611 VK_FORMAT_R32_SINT, 4612 VK_FORMAT_R32_SFLOAT, 4613 VK_FORMAT_R32G32_UINT, 4614 VK_FORMAT_R32G32_SINT, 4615 VK_FORMAT_R32G32_SFLOAT, 4616 VK_FORMAT_R32G32B32A32_UINT, 4617 VK_FORMAT_R32G32B32A32_SINT, 4618 VK_FORMAT_R32G32B32A32_SFLOAT 4619 }; 4620 4621 static const VkFormat s_coreDepthStencilFormats[] = 4622 { 4623 VK_FORMAT_D16_UNORM, 4624 4625 VK_FORMAT_X8_D24_UNORM_PACK32, 4626 VK_FORMAT_D32_SFLOAT, 4627 4628 VK_FORMAT_D24_UNORM_S8_UINT, 4629 VK_FORMAT_D32_SFLOAT_S8_UINT 4630 }; 4631 4632 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4633 { 4634 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 }; 4635 const VkAttachmentLoadOp loadOps[] = 4636 { 4637 VK_ATTACHMENT_LOAD_OP_LOAD, 4638 VK_ATTACHMENT_LOAD_OP_CLEAR, 4639 VK_ATTACHMENT_LOAD_OP_DONT_CARE 4640 }; 4641 4642 const VkAttachmentStoreOp storeOps[] = 4643 { 4644 VK_ATTACHMENT_STORE_OP_STORE, 4645 VK_ATTACHMENT_STORE_OP_DONT_CARE 4646 }; 4647 4648 const VkImageLayout initialAndFinalColorLayouts[] = 4649 { 4650 VK_IMAGE_LAYOUT_GENERAL, 4651 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4652 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4653 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4654 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4655 }; 4656 4657 const VkImageLayout initialAndFinalDepthStencilLayouts[] = 4658 { 4659 VK_IMAGE_LAYOUT_GENERAL, 4660 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 4661 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, 4662 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4663 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4664 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4665 }; 4666 4667 const VkImageLayout subpassLayouts[] = 4668 { 4669 VK_IMAGE_LAYOUT_GENERAL, 4670 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 4671 }; 4672 4673 const VkImageLayout depthStencilLayouts[] = 4674 { 4675 VK_IMAGE_LAYOUT_GENERAL, 4676 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL 4677 }; 4678 4679 const TestConfig::RenderTypes renderCommands[] = 4680 { 4681 TestConfig::RENDERTYPES_NONE, 4682 TestConfig::RENDERTYPES_CLEAR, 4683 TestConfig::RENDERTYPES_DRAW, 4684 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW, 4685 }; 4686 4687 const TestConfig::CommandBufferTypes commandBuffers[] = 4688 { 4689 TestConfig::COMMANDBUFFERTYPES_INLINE, 4690 TestConfig::COMMANDBUFFERTYPES_SECONDARY, 4691 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY 4692 }; 4693 4694 const TestConfig::ImageMemory imageMemories[] = 4695 { 4696 TestConfig::IMAGEMEMORY_STRICT, 4697 TestConfig::IMAGEMEMORY_LAZY, 4698 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY 4699 }; 4700 4701 const UVec2 targetSizes[] = 4702 { 4703 UVec2(64, 64), 4704 UVec2(63, 65) 4705 }; 4706 4707 const UVec2 renderPositions[] = 4708 { 4709 UVec2(0, 0), 4710 UVec2(3, 17) 4711 }; 4712 4713 const UVec2 renderSizes[] = 4714 { 4715 UVec2(32, 32), 4716 UVec2(60, 47) 4717 }; 4718 4719 tcu::TestContext& testCtx = group->getTestContext(); 4720 de::Random rng (1433774382u); 4721 4722 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++) 4723 { 4724 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx]; 4725 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200); 4726 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str())); 4727 4728 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++) 4729 { 4730 const bool useDepthStencil = rng.getBool(); 4731 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL; 4732 vector<Attachment> attachments; 4733 vector<AttachmentReference> colorAttachmentReferences; 4734 4735 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++) 4736 { 4737 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4738 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 4739 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4740 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4741 4742 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4743 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4744 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 4745 4746 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4747 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4748 4749 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4750 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 4751 } 4752 4753 if (useDepthStencil) 4754 { 4755 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4756 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats)); 4757 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4758 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4759 4760 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)); 4761 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)); 4762 4763 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4764 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4765 4766 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts)); 4767 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4768 } 4769 4770 { 4771 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 4772 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 4773 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 4774 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>())); 4775 const vector<SubpassDependency> deps; 4776 4777 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx); 4778 const RenderPass renderPass (attachments, subpasses, deps); 4779 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 4780 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 4781 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 4782 4783 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind)); 4784 } 4785 } 4786 4787 group->addChild(attachmentCountGroup.release()); 4788 } 4789 } 4790 4791 template<typename T> 4792 T chooseRandom (de::Random& rng, const set<T>& values) 4793 { 4794 size_t ndx = ((size_t)rng.getUint32()) % values.size(); 4795 typename set<T>::const_iterator iter = values.begin(); 4796 4797 for (; ndx > 0; ndx--) 4798 iter++; 4799 4800 return *iter; 4801 } 4802 4803 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4804 { 4805 const deUint32 attachmentCounts[] = { 4, 8 }; 4806 const VkAttachmentLoadOp loadOps[] = 4807 { 4808 VK_ATTACHMENT_LOAD_OP_LOAD, 4809 VK_ATTACHMENT_LOAD_OP_CLEAR, 4810 VK_ATTACHMENT_LOAD_OP_DONT_CARE 4811 }; 4812 4813 const VkAttachmentStoreOp storeOps[] = 4814 { 4815 VK_ATTACHMENT_STORE_OP_STORE, 4816 VK_ATTACHMENT_STORE_OP_DONT_CARE 4817 }; 4818 4819 const VkImageLayout initialAndFinalColorLayouts[] = 4820 { 4821 VK_IMAGE_LAYOUT_GENERAL, 4822 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4823 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4824 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4825 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4826 }; 4827 4828 const VkImageLayout initialAndFinalDepthStencilLayouts[] = 4829 { 4830 VK_IMAGE_LAYOUT_GENERAL, 4831 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 4832 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, 4833 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 4834 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4835 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 4836 }; 4837 4838 const VkImageLayout subpassLayouts[] = 4839 { 4840 VK_IMAGE_LAYOUT_GENERAL, 4841 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 4842 }; 4843 4844 enum AllocationType 4845 { 4846 // Each pass uses one more attachmen than previous one 4847 ALLOCATIONTYPE_GROW, 4848 // Each pass uses one less attachment than previous one 4849 ALLOCATIONTYPE_SHRINK, 4850 // Each pass drops one attachment and picks up new one 4851 ALLOCATIONTYPE_ROLL, 4852 // Start by growing and end by shrinking 4853 ALLOCATIONTYPE_GROW_SHRINK, 4854 // Each subpass has single input and single output attachment 4855 ALLOCATIONTYPE_IO_CHAIN, 4856 // Each subpass has multiple inputs and multiple outputs attachment 4857 ALLOCATIONTYPE_IO_GENERIC 4858 }; 4859 4860 const AllocationType allocationTypes[] = 4861 { 4862 ALLOCATIONTYPE_GROW, 4863 ALLOCATIONTYPE_SHRINK, 4864 ALLOCATIONTYPE_ROLL, 4865 ALLOCATIONTYPE_GROW_SHRINK, 4866 ALLOCATIONTYPE_IO_CHAIN, 4867 ALLOCATIONTYPE_IO_GENERIC 4868 }; 4869 4870 const char* const allocationTypeStr[] = 4871 { 4872 "grow", 4873 "shrink", 4874 "roll", 4875 "grow_shrink", 4876 "input_output_chain", 4877 "input_output", 4878 }; 4879 4880 const TestConfig::RenderTypes renderCommands[] = 4881 { 4882 TestConfig::RENDERTYPES_NONE, 4883 TestConfig::RENDERTYPES_CLEAR, 4884 TestConfig::RENDERTYPES_DRAW, 4885 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW, 4886 }; 4887 4888 const TestConfig::CommandBufferTypes commandBuffers[] = 4889 { 4890 TestConfig::COMMANDBUFFERTYPES_INLINE, 4891 TestConfig::COMMANDBUFFERTYPES_SECONDARY, 4892 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY 4893 }; 4894 4895 const TestConfig::ImageMemory imageMemories[] = 4896 { 4897 TestConfig::IMAGEMEMORY_STRICT, 4898 TestConfig::IMAGEMEMORY_LAZY, 4899 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY 4900 }; 4901 4902 const UVec2 targetSizes[] = 4903 { 4904 UVec2(64, 64), 4905 UVec2(63, 65) 4906 }; 4907 4908 const UVec2 renderPositions[] = 4909 { 4910 UVec2(0, 0), 4911 UVec2(3, 17) 4912 }; 4913 4914 const UVec2 renderSizes[] = 4915 { 4916 UVec2(32, 32), 4917 UVec2(60, 47) 4918 }; 4919 4920 tcu::TestContext& testCtx = group->getTestContext(); 4921 de::Random rng (3700649827u); 4922 4923 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++) 4924 { 4925 const AllocationType allocationType = allocationTypes[allocationTypeNdx]; 4926 const size_t testCaseCount = 100; 4927 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx])); 4928 4929 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++) 4930 { 4931 if (allocationType == ALLOCATIONTYPE_IO_GENERIC) 4932 { 4933 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u; 4934 const deUint32 subpassCount = 4u + rng.getUint32() % 31u; 4935 vector<Attachment> attachments; 4936 4937 set<deUint32> definedAttachments; 4938 4939 vector<Subpass> subpasses; 4940 set<deUint32> colorAttachments; 4941 set<deUint32> depthStencilAttachments; 4942 4943 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++) 4944 { 4945 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f; 4946 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 4947 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4948 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4949 4950 const VkImageLayout initialLayout = isDepthStencilAttachment 4951 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) 4952 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4953 const VkImageLayout finalizeLayout = isDepthStencilAttachment 4954 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) 4955 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 4956 4957 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 4958 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 4959 4960 if (isDepthStencilAttachment) 4961 { 4962 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats)); 4963 4964 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR 4965 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) 4966 definedAttachments.insert(attachmentIndex); 4967 4968 depthStencilAttachments.insert(attachmentIndex); 4969 4970 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4971 } 4972 else 4973 { 4974 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 4975 4976 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) 4977 definedAttachments.insert(attachmentIndex); 4978 4979 colorAttachments.insert(attachmentIndex); 4980 4981 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 4982 } 4983 } 4984 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>()); 4985 vector<SubpassDependency> deps; 4986 4987 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++) 4988 { 4989 const deUint32 colorAttachmentCount = depthStencilAttachments.empty() 4990 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size()) 4991 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u); 4992 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1); 4993 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool()); 4994 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount); 4995 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount); 4996 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment 4997 ? just(chooseRandom(rng, depthStencilAttachments)) 4998 : nothing<deUint32>()); 4999 std::vector<deUint32> subpassPreserveAttachments; 5000 5001 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount); 5002 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount); 5003 5004 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++) 5005 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]); 5006 5007 if (depthStencilAttachment) 5008 definedAttachments.insert(*depthStencilAttachment); 5009 5010 { 5011 std::vector<AttachmentReference> inputAttachmentReferences; 5012 std::vector<AttachmentReference> colorAttachmentReferences; 5013 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL); 5014 5015 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++) 5016 { 5017 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx]; 5018 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts 5019 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL; 5020 5021 if (lastUseOfAttachment[colorAttachmentIndex]) 5022 { 5023 const bool byRegion = rng.getBool(); 5024 5025 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex, 5026 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5027 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5028 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5029 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5030 5031 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5032 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5033 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5034 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5035 5036 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5037 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 5038 5039 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5040 } 5041 5042 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex); 5043 5044 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout)); 5045 } 5046 5047 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++) 5048 { 5049 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx]; 5050 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts 5051 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL; 5052 5053 if(lastUseOfAttachment[inputAttachmentIndex]) 5054 { 5055 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex) 5056 { 5057 deps.push_back(SubpassDependency(subpassIndex, subpassIndex, 5058 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5059 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5060 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5061 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5062 5063 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5064 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5065 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5066 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5067 5068 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5069 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5070 5071 VK_DEPENDENCY_BY_REGION_BIT)); 5072 } 5073 else 5074 { 5075 const bool byRegion = rng.getBool(); 5076 5077 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex, 5078 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5079 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5080 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5081 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5082 5083 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5084 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5085 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5086 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5087 5088 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5089 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5090 5091 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5092 } 5093 5094 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex); 5095 5096 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout)); 5097 } 5098 } 5099 5100 if (depthStencilAttachment) 5101 { 5102 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts 5103 if (lastUseOfAttachment[*depthStencilAttachment]) 5104 { 5105 if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex) 5106 { 5107 deps.push_back(SubpassDependency(subpassIndex, subpassIndex, 5108 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5109 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5110 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5111 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5112 5113 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5114 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5115 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5116 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5117 5118 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5119 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5120 5121 VK_DEPENDENCY_BY_REGION_BIT)); 5122 } 5123 else 5124 { 5125 const bool byRegion = rng.getBool(); 5126 5127 deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex, 5128 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5129 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5130 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5131 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5132 5133 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5134 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5135 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5136 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5137 5138 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 5139 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5140 5141 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5142 } 5143 } 5144 5145 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex); 5146 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL); 5147 } 5148 else 5149 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL); 5150 5151 vector<deUint32> preserveAttachments; 5152 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++) 5153 { 5154 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex) 5155 preserveAttachments.push_back(attachmentIndex); 5156 } 5157 5158 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5159 inputAttachmentReferences, 5160 colorAttachmentReferences, 5161 vector<AttachmentReference>(), 5162 depthStencilAttachmentReference, 5163 preserveAttachments)); 5164 } 5165 } 5166 { 5167 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 5168 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 5169 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 5170 5171 const string testCaseName = de::toString(testCaseNdx); 5172 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 5173 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 5174 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 5175 5176 const RenderPass renderPass (attachments, subpasses, deps); 5177 5178 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind)); 5179 } 5180 } 5181 else 5182 { 5183 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts)); 5184 vector<Attachment> attachments; 5185 vector<Subpass> subpasses; 5186 5187 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++) 5188 { 5189 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; 5190 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats)); 5191 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 5192 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 5193 5194 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 5195 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts)); 5196 5197 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps)); 5198 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps)); 5199 5200 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout)); 5201 } 5202 5203 if (allocationType == ALLOCATIONTYPE_GROW) 5204 { 5205 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5206 { 5207 vector<AttachmentReference> colorAttachmentReferences; 5208 5209 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++) 5210 { 5211 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5212 5213 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5214 } 5215 5216 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5217 vector<AttachmentReference>(), 5218 colorAttachmentReferences, 5219 vector<AttachmentReference>(), 5220 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5221 vector<deUint32>())); 5222 } 5223 } 5224 else if (allocationType == ALLOCATIONTYPE_SHRINK) 5225 { 5226 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5227 { 5228 vector<AttachmentReference> colorAttachmentReferences; 5229 5230 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++) 5231 { 5232 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5233 5234 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5235 } 5236 5237 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5238 vector<AttachmentReference>(), 5239 colorAttachmentReferences, 5240 vector<AttachmentReference>(), 5241 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5242 vector<deUint32>())); 5243 } 5244 } 5245 else if (allocationType == ALLOCATIONTYPE_ROLL) 5246 { 5247 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++) 5248 { 5249 vector<AttachmentReference> colorAttachmentReferences; 5250 5251 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++) 5252 { 5253 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5254 5255 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout)); 5256 } 5257 5258 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5259 vector<AttachmentReference>(), 5260 colorAttachmentReferences, 5261 vector<AttachmentReference>(), 5262 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5263 vector<deUint32>())); 5264 } 5265 } 5266 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK) 5267 { 5268 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5269 { 5270 vector<AttachmentReference> colorAttachmentReferences; 5271 5272 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++) 5273 { 5274 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5275 5276 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5277 } 5278 5279 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5280 vector<AttachmentReference>(), 5281 colorAttachmentReferences, 5282 vector<AttachmentReference>(), 5283 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5284 vector<deUint32>())); 5285 } 5286 5287 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++) 5288 { 5289 vector<AttachmentReference> colorAttachmentReferences; 5290 5291 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++) 5292 { 5293 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)); 5294 5295 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout)); 5296 } 5297 5298 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5299 vector<AttachmentReference>(), 5300 colorAttachmentReferences, 5301 vector<AttachmentReference>(), 5302 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5303 vector<deUint32>())); 5304 } 5305 } 5306 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN) 5307 { 5308 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5309 vector<AttachmentReference>(), 5310 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))), 5311 vector<AttachmentReference>(), 5312 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5313 vector<deUint32>())); 5314 5315 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++) 5316 { 5317 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, 5318 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5319 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))), 5320 vector<AttachmentReference>(), 5321 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5322 vector<deUint32>())); 5323 } 5324 } 5325 else 5326 DE_FATAL("Unknown allocation type"); 5327 5328 { 5329 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands)); 5330 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers)); 5331 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories)); 5332 5333 const string testCaseName = de::toString(testCaseNdx); 5334 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes)); 5335 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions)); 5336 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes)); 5337 5338 vector<SubpassDependency> deps; 5339 5340 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++) 5341 { 5342 const bool byRegion = rng.getBool(); 5343 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1, 5344 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5345 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5346 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5347 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5348 5349 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT 5350 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT 5351 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT 5352 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 5353 5354 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5355 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 5356 5357 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u)); 5358 } 5359 5360 const RenderPass renderPass (attachments, subpasses, deps); 5361 5362 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind)); 5363 } 5364 } 5365 } 5366 group->addChild(allocationTypeGroup.release()); 5367 } 5368 } 5369 5370 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5371 { 5372 const UVec2 targetSize (64, 64); 5373 const UVec2 renderPos (0, 0); 5374 const UVec2 renderSize (64, 64); 5375 5376 // color 5377 { 5378 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5379 VK_SAMPLE_COUNT_1_BIT, 5380 VK_ATTACHMENT_LOAD_OP_CLEAR, 5381 VK_ATTACHMENT_STORE_OP_STORE, 5382 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5383 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5384 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5385 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5386 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5387 0u, 5388 vector<AttachmentReference>(), 5389 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5390 vector<AttachmentReference>(), 5391 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5392 vector<deUint32>())), 5393 vector<SubpassDependency>()); 5394 5395 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)); 5396 } 5397 5398 // depth 5399 { 5400 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, 5401 VK_SAMPLE_COUNT_1_BIT, 5402 VK_ATTACHMENT_LOAD_OP_CLEAR, 5403 VK_ATTACHMENT_STORE_OP_STORE, 5404 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5405 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5406 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5407 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5408 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5409 0u, 5410 vector<AttachmentReference>(), 5411 vector<AttachmentReference>(), 5412 vector<AttachmentReference>(), 5413 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5414 vector<deUint32>())), 5415 vector<SubpassDependency>()); 5416 5417 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)); 5418 } 5419 5420 // stencil 5421 { 5422 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT, 5423 VK_SAMPLE_COUNT_1_BIT, 5424 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5425 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5426 VK_ATTACHMENT_LOAD_OP_CLEAR, 5427 VK_ATTACHMENT_STORE_OP_STORE, 5428 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5429 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5430 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5431 0u, 5432 vector<AttachmentReference>(), 5433 vector<AttachmentReference>(), 5434 vector<AttachmentReference>(), 5435 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5436 vector<deUint32>())), 5437 vector<SubpassDependency>()); 5438 5439 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)); 5440 } 5441 5442 // depth_stencil 5443 { 5444 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT, 5445 VK_SAMPLE_COUNT_1_BIT, 5446 VK_ATTACHMENT_LOAD_OP_CLEAR, 5447 VK_ATTACHMENT_STORE_OP_STORE, 5448 VK_ATTACHMENT_LOAD_OP_CLEAR, 5449 VK_ATTACHMENT_STORE_OP_STORE, 5450 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5451 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5452 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5453 0u, 5454 vector<AttachmentReference>(), 5455 vector<AttachmentReference>(), 5456 vector<AttachmentReference>(), 5457 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5458 vector<deUint32>())), 5459 vector<SubpassDependency>()); 5460 5461 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)); 5462 } 5463 5464 // color_depth 5465 { 5466 const Attachment attachments[] = 5467 { 5468 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5469 VK_SAMPLE_COUNT_1_BIT, 5470 VK_ATTACHMENT_LOAD_OP_CLEAR, 5471 VK_ATTACHMENT_STORE_OP_STORE, 5472 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5473 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5474 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5475 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5476 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, 5477 VK_SAMPLE_COUNT_1_BIT, 5478 VK_ATTACHMENT_LOAD_OP_CLEAR, 5479 VK_ATTACHMENT_STORE_OP_STORE, 5480 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5481 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5482 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5483 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5484 }; 5485 5486 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5487 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5488 0u, 5489 vector<AttachmentReference>(), 5490 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5491 vector<AttachmentReference>(), 5492 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5493 vector<deUint32>())), 5494 vector<SubpassDependency>()); 5495 5496 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)); 5497 } 5498 5499 // color_stencil 5500 { 5501 const Attachment attachments[] = 5502 { 5503 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5504 VK_SAMPLE_COUNT_1_BIT, 5505 VK_ATTACHMENT_LOAD_OP_CLEAR, 5506 VK_ATTACHMENT_STORE_OP_STORE, 5507 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5508 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5509 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5510 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5511 Attachment(VK_FORMAT_S8_UINT, 5512 VK_SAMPLE_COUNT_1_BIT, 5513 VK_ATTACHMENT_LOAD_OP_CLEAR, 5514 VK_ATTACHMENT_STORE_OP_STORE, 5515 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5516 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5517 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5518 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5519 }; 5520 5521 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5522 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5523 0u, 5524 vector<AttachmentReference>(), 5525 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5526 vector<AttachmentReference>(), 5527 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5528 vector<deUint32>())), 5529 vector<SubpassDependency>()); 5530 5531 5532 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)); 5533 } 5534 5535 // color_depth_stencil 5536 { 5537 const Attachment attachments[] = 5538 { 5539 Attachment(VK_FORMAT_R8G8B8A8_UNORM, 5540 VK_SAMPLE_COUNT_1_BIT, 5541 VK_ATTACHMENT_LOAD_OP_CLEAR, 5542 VK_ATTACHMENT_STORE_OP_STORE, 5543 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5544 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5545 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5546 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL), 5547 Attachment(VK_FORMAT_D24_UNORM_S8_UINT, 5548 VK_SAMPLE_COUNT_1_BIT, 5549 VK_ATTACHMENT_LOAD_OP_CLEAR, 5550 VK_ATTACHMENT_STORE_OP_STORE, 5551 VK_ATTACHMENT_LOAD_OP_CLEAR, 5552 VK_ATTACHMENT_STORE_OP_STORE, 5553 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5554 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5555 }; 5556 5557 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)), 5558 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5559 0u, 5560 vector<AttachmentReference>(), 5561 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5562 vector<AttachmentReference>(), 5563 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5564 vector<deUint32>())), 5565 vector<SubpassDependency>()); 5566 5567 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)); 5568 } 5569 } 5570 5571 std::string formatToName (VkFormat format) 5572 { 5573 const std::string formatStr = de::toString(format); 5574 const std::string prefix = "VK_FORMAT_"; 5575 5576 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix); 5577 5578 return de::toLower(formatStr.substr(prefix.length())); 5579 } 5580 5581 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5582 { 5583 tcu::TestContext& testCtx = group->getTestContext(); 5584 5585 const UVec2 targetSize (64, 64); 5586 const UVec2 renderPos (0, 0); 5587 const UVec2 renderSize (64, 64); 5588 5589 const struct 5590 { 5591 const char* const str; 5592 const VkAttachmentStoreOp op; 5593 } storeOps[] = 5594 { 5595 { "store", VK_ATTACHMENT_STORE_OP_STORE }, 5596 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE } 5597 }; 5598 5599 const struct 5600 { 5601 const char* const str; 5602 const VkAttachmentLoadOp op; 5603 } loadOps[] = 5604 { 5605 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR }, 5606 { "load", VK_ATTACHMENT_LOAD_OP_LOAD }, 5607 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE } 5608 }; 5609 5610 const struct 5611 { 5612 const char* const str; 5613 const TestConfig::RenderTypes types; 5614 } renderTypes[] = 5615 { 5616 { "clear", TestConfig::RENDERTYPES_CLEAR }, 5617 { "draw", TestConfig::RENDERTYPES_DRAW }, 5618 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW } 5619 }; 5620 5621 // Color formats 5622 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++) 5623 { 5624 const VkFormat format = s_coreColorFormats[formatNdx]; 5625 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str())); 5626 5627 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5628 { 5629 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5630 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5631 5632 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5633 { 5634 const RenderPass renderPass (vector<Attachment>(1, Attachment(format, 5635 VK_SAMPLE_COUNT_1_BIT, 5636 loadOp, 5637 VK_ATTACHMENT_STORE_OP_STORE, 5638 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5639 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5640 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5641 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5642 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5643 0u, 5644 vector<AttachmentReference>(), 5645 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5646 vector<AttachmentReference>(), 5647 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5648 vector<deUint32>())), 5649 vector<SubpassDependency>()); 5650 5651 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)); 5652 } 5653 5654 formatGroup->addChild(loadOpGroup.release()); 5655 } 5656 5657 { 5658 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input")); 5659 5660 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5661 { 5662 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5663 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5664 5665 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++) 5666 { 5667 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op; 5668 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str)); 5669 5670 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++) 5671 { 5672 const bool useInputAspect = useInputAspectNdx != 0; 5673 5674 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5675 { 5676 { 5677 vector<Attachment> attachments; 5678 vector<Subpass> subpasses; 5679 vector<SubpassDependency> deps; 5680 vector<VkInputAttachmentAspectReference> inputAspects; 5681 5682 attachments.push_back(Attachment(format, 5683 VK_SAMPLE_COUNT_1_BIT, 5684 loadOp, 5685 storeOp, 5686 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5687 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5688 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5689 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5690 5691 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 5692 VK_SAMPLE_COUNT_1_BIT, 5693 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5694 VK_ATTACHMENT_STORE_OP_STORE, 5695 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5696 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5697 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5698 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5699 5700 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5701 0u, 5702 vector<AttachmentReference>(), 5703 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5704 vector<AttachmentReference>(), 5705 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5706 vector<deUint32>())); 5707 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5708 0u, 5709 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5710 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5711 vector<AttachmentReference>(), 5712 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5713 vector<deUint32>())); 5714 5715 deps.push_back(SubpassDependency(0, 1, 5716 5717 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5718 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5719 5720 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5721 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5722 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5723 5724 if (useInputAspect) 5725 { 5726 const VkInputAttachmentAspectReference inputAspect = 5727 { 5728 0u, 5729 0u, 5730 VK_IMAGE_ASPECT_COLOR_BIT 5731 }; 5732 5733 inputAspects.push_back(inputAspect); 5734 } 5735 5736 { 5737 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5738 5739 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)); 5740 } 5741 } 5742 { 5743 vector<Attachment> attachments; 5744 vector<Subpass> subpasses; 5745 vector<SubpassDependency> deps; 5746 vector<VkInputAttachmentAspectReference> inputAspects; 5747 5748 attachments.push_back(Attachment(format, 5749 VK_SAMPLE_COUNT_1_BIT, 5750 loadOp, 5751 storeOp, 5752 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5753 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5754 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5755 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5756 5757 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5758 0u, 5759 vector<AttachmentReference>(), 5760 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5761 vector<AttachmentReference>(), 5762 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5763 vector<deUint32>())); 5764 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5765 0u, 5766 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 5767 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 5768 vector<AttachmentReference>(), 5769 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5770 vector<deUint32>())); 5771 5772 deps.push_back(SubpassDependency(0, 1, 5773 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5774 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5775 5776 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5777 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5778 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5779 5780 if (useInputAspect) 5781 { 5782 const VkInputAttachmentAspectReference inputAspect = 5783 { 5784 0u, 5785 0u, 5786 VK_IMAGE_ASPECT_COLOR_BIT 5787 }; 5788 5789 inputAspects.push_back(inputAspect); 5790 } 5791 5792 { 5793 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5794 5795 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)); 5796 } 5797 } 5798 } 5799 } 5800 5801 loadOpGroup->addChild(storeOpGroup.release()); 5802 } 5803 5804 inputGroup->addChild(loadOpGroup.release()); 5805 } 5806 5807 formatGroup->addChild(inputGroup.release()); 5808 } 5809 5810 group->addChild(formatGroup.release()); 5811 } 5812 5813 // Depth stencil formats 5814 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++) 5815 { 5816 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx]; 5817 const tcu::TextureFormat format = mapVkFormat(vkFormat); 5818 const bool isStencilAttachment = hasStencilComponent(format.order); 5819 const bool isDepthAttachment = hasDepthComponent(format.order); 5820 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str())); 5821 5822 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5823 { 5824 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5825 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5826 5827 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5828 { 5829 { 5830 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5831 VK_SAMPLE_COUNT_1_BIT, 5832 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5833 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5834 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5835 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5836 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5837 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5838 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5839 0u, 5840 vector<AttachmentReference>(), 5841 vector<AttachmentReference>(), 5842 vector<AttachmentReference>(), 5843 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5844 vector<deUint32>())), 5845 vector<SubpassDependency>()); 5846 5847 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)); 5848 } 5849 5850 if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR) 5851 { 5852 { 5853 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5854 VK_SAMPLE_COUNT_1_BIT, 5855 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5856 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5857 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5858 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5859 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5860 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5861 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5862 0u, 5863 vector<AttachmentReference>(), 5864 vector<AttachmentReference>(), 5865 vector<AttachmentReference>(), 5866 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL), 5867 vector<deUint32>())), 5868 vector<SubpassDependency>()); 5869 5870 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)); 5871 } 5872 5873 { 5874 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat, 5875 VK_SAMPLE_COUNT_1_BIT, 5876 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5877 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5878 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5879 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE, 5880 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5881 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)), 5882 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5883 0u, 5884 vector<AttachmentReference>(), 5885 vector<AttachmentReference>(), 5886 vector<AttachmentReference>(), 5887 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL), 5888 vector<deUint32>())), 5889 vector<SubpassDependency>()); 5890 5891 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)); 5892 } 5893 } 5894 } 5895 5896 formatGroup->addChild(loadOpGroup.release()); 5897 } 5898 5899 { 5900 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input")); 5901 5902 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++) 5903 { 5904 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op; 5905 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str)); 5906 5907 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++) 5908 { 5909 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op; 5910 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str)); 5911 5912 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++) 5913 { 5914 const bool useInputAspect = useInputAspectNdx != 0; 5915 5916 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++) 5917 { 5918 { 5919 vector<Attachment> attachments; 5920 vector<Subpass> subpasses; 5921 vector<SubpassDependency> deps; 5922 vector<VkInputAttachmentAspectReference> inputAspects; 5923 5924 attachments.push_back(Attachment(vkFormat, 5925 VK_SAMPLE_COUNT_1_BIT, 5926 loadOp, 5927 storeOp, 5928 loadOp, 5929 storeOp, 5930 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5931 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 5932 5933 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 5934 VK_SAMPLE_COUNT_1_BIT, 5935 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5936 VK_ATTACHMENT_STORE_OP_STORE, 5937 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 5938 VK_ATTACHMENT_STORE_OP_DONT_CARE, 5939 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5940 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 5941 5942 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5943 0u, 5944 vector<AttachmentReference>(), 5945 vector<AttachmentReference>(), 5946 vector<AttachmentReference>(), 5947 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 5948 vector<deUint32>())); 5949 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 5950 0u, 5951 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)), 5952 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 5953 vector<AttachmentReference>(), 5954 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 5955 vector<deUint32>())); 5956 5957 deps.push_back(SubpassDependency(0, 1, 5958 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5959 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5960 5961 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5962 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5963 0u)); 5964 5965 deps.push_back(SubpassDependency(1, 1, 5966 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 5967 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 5968 5969 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 5970 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 5971 vk::VK_DEPENDENCY_BY_REGION_BIT)); 5972 5973 if (useInputAspect) 5974 { 5975 const VkInputAttachmentAspectReference inputAspect = 5976 { 5977 0u, 5978 0u, 5979 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 5980 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 5981 }; 5982 5983 inputAspects.push_back(inputAspect); 5984 } 5985 5986 { 5987 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 5988 5989 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)); 5990 } 5991 } 5992 { 5993 vector<Attachment> attachments; 5994 vector<Subpass> subpasses; 5995 vector<SubpassDependency> deps; 5996 vector<VkInputAttachmentAspectReference> inputAspects; 5997 5998 attachments.push_back(Attachment(vkFormat, 5999 VK_SAMPLE_COUNT_1_BIT, 6000 loadOp, 6001 storeOp, 6002 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6003 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6004 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6005 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6006 6007 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6008 0u, 6009 vector<AttachmentReference>(), 6010 vector<AttachmentReference>(), 6011 vector<AttachmentReference>(), 6012 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6013 vector<deUint32>())); 6014 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6015 0u, 6016 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)), 6017 vector<AttachmentReference>(), 6018 vector<AttachmentReference>(), 6019 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL), 6020 vector<deUint32>())); 6021 6022 deps.push_back(SubpassDependency(0, 1, 6023 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6024 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6025 6026 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6027 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6028 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6029 6030 6031 if (useInputAspect) 6032 { 6033 const VkInputAttachmentAspectReference inputAspect = 6034 { 6035 0u, 6036 0u, 6037 6038 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6039 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6040 }; 6041 6042 inputAspects.push_back(inputAspect); 6043 } 6044 6045 { 6046 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6047 6048 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)); 6049 } 6050 } 6051 6052 if (isStencilAttachment && isDepthAttachment) 6053 { 6054 // Depth read only 6055 { 6056 vector<Attachment> attachments; 6057 vector<Subpass> subpasses; 6058 vector<SubpassDependency> deps; 6059 vector<VkInputAttachmentAspectReference> inputAspects; 6060 6061 attachments.push_back(Attachment(vkFormat, 6062 VK_SAMPLE_COUNT_1_BIT, 6063 loadOp, 6064 storeOp, 6065 loadOp, 6066 storeOp, 6067 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6068 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6069 6070 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 6071 VK_SAMPLE_COUNT_1_BIT, 6072 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6073 VK_ATTACHMENT_STORE_OP_STORE, 6074 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6075 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6076 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 6077 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 6078 6079 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6080 0u, 6081 vector<AttachmentReference>(), 6082 vector<AttachmentReference>(), 6083 vector<AttachmentReference>(), 6084 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6085 vector<deUint32>())); 6086 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6087 0u, 6088 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)), 6089 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 6090 vector<AttachmentReference>(), 6091 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 6092 vector<deUint32>())); 6093 6094 deps.push_back(SubpassDependency(0, 1, 6095 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6096 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6097 6098 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6099 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6100 0u)); 6101 6102 if (useInputAspect) 6103 { 6104 const VkInputAttachmentAspectReference inputAspect = 6105 { 6106 0u, 6107 0u, 6108 6109 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6110 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6111 }; 6112 6113 inputAspects.push_back(inputAspect); 6114 } 6115 6116 { 6117 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6118 6119 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)); 6120 } 6121 } 6122 { 6123 vector<Attachment> attachments; 6124 vector<Subpass> subpasses; 6125 vector<SubpassDependency> deps; 6126 vector<VkInputAttachmentAspectReference> inputAspects; 6127 6128 attachments.push_back(Attachment(vkFormat, 6129 VK_SAMPLE_COUNT_1_BIT, 6130 loadOp, 6131 storeOp, 6132 loadOp, 6133 storeOp, 6134 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6135 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6136 6137 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6138 0u, 6139 vector<AttachmentReference>(), 6140 vector<AttachmentReference>(), 6141 vector<AttachmentReference>(), 6142 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6143 vector<deUint32>())); 6144 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6145 0u, 6146 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)), 6147 vector<AttachmentReference>(), 6148 vector<AttachmentReference>(), 6149 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL), 6150 vector<deUint32>())); 6151 6152 deps.push_back(SubpassDependency(0, 1, 6153 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6154 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6155 6156 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6157 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6158 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6159 6160 deps.push_back(SubpassDependency(1, 1, 6161 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6162 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6163 6164 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6165 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6166 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6167 6168 6169 if (useInputAspect) 6170 { 6171 const VkInputAttachmentAspectReference inputAspect = 6172 { 6173 0u, 6174 0u, 6175 6176 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6177 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6178 }; 6179 6180 inputAspects.push_back(inputAspect); 6181 } 6182 6183 { 6184 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6185 6186 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)); 6187 } 6188 } 6189 // Stencil read only 6190 { 6191 vector<Attachment> attachments; 6192 vector<Subpass> subpasses; 6193 vector<SubpassDependency> deps; 6194 vector<VkInputAttachmentAspectReference> inputAspects; 6195 6196 attachments.push_back(Attachment(vkFormat, 6197 VK_SAMPLE_COUNT_1_BIT, 6198 loadOp, 6199 storeOp, 6200 loadOp, 6201 storeOp, 6202 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6203 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6204 6205 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, 6206 VK_SAMPLE_COUNT_1_BIT, 6207 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6208 VK_ATTACHMENT_STORE_OP_STORE, 6209 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 6210 VK_ATTACHMENT_STORE_OP_DONT_CARE, 6211 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 6212 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 6213 6214 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6215 0u, 6216 vector<AttachmentReference>(), 6217 vector<AttachmentReference>(), 6218 vector<AttachmentReference>(), 6219 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6220 vector<deUint32>())); 6221 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6222 0u, 6223 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)), 6224 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)), 6225 vector<AttachmentReference>(), 6226 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), 6227 vector<deUint32>())); 6228 6229 deps.push_back(SubpassDependency(0, 1, 6230 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6231 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6232 6233 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6234 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6235 0u)); 6236 6237 if (useInputAspect) 6238 { 6239 const VkInputAttachmentAspectReference inputAspect = 6240 { 6241 0u, 6242 0u, 6243 6244 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6245 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6246 }; 6247 6248 inputAspects.push_back(inputAspect); 6249 } 6250 6251 { 6252 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6253 6254 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)); 6255 } 6256 } 6257 { 6258 vector<Attachment> attachments; 6259 vector<Subpass> subpasses; 6260 vector<SubpassDependency> deps; 6261 vector<VkInputAttachmentAspectReference> inputAspects; 6262 6263 attachments.push_back(Attachment(vkFormat, 6264 VK_SAMPLE_COUNT_1_BIT, 6265 loadOp, 6266 storeOp, 6267 loadOp, 6268 storeOp, 6269 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 6270 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 6271 6272 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6273 0u, 6274 vector<AttachmentReference>(), 6275 vector<AttachmentReference>(), 6276 vector<AttachmentReference>(), 6277 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), 6278 vector<deUint32>())); 6279 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 6280 0u, 6281 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)), 6282 vector<AttachmentReference>(), 6283 vector<AttachmentReference>(), 6284 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL), 6285 vector<deUint32>())); 6286 6287 deps.push_back(SubpassDependency(0, 1, 6288 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6289 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6290 6291 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 6292 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6293 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6294 6295 deps.push_back(SubpassDependency(1, 1, 6296 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6297 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6298 6299 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 6300 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 6301 vk::VK_DEPENDENCY_BY_REGION_BIT)); 6302 6303 6304 if (useInputAspect) 6305 { 6306 const VkInputAttachmentAspectReference inputAspect = 6307 { 6308 0u, 6309 0u, 6310 6311 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) 6312 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u) 6313 }; 6314 6315 inputAspects.push_back(inputAspect); 6316 } 6317 6318 { 6319 const RenderPass renderPass (attachments, subpasses, deps, inputAspects); 6320 6321 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)); 6322 } 6323 } 6324 } 6325 } 6326 } 6327 6328 loadOpGroup->addChild(storeOpGroup.release()); 6329 } 6330 6331 inputGroup->addChild(loadOpGroup.release()); 6332 } 6333 6334 formatGroup->addChild(inputGroup.release()); 6335 } 6336 6337 group->addChild(formatGroup.release()); 6338 } 6339 } 6340 6341 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6342 { 6343 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind); 6344 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind); 6345 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind); 6346 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind); 6347 } 6348 6349 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx) 6350 { 6351 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests")); 6352 6353 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED); 6354 6355 return suballocationTestsGroup; 6356 } 6357 6358 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx) 6359 { 6360 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation")); 6361 6362 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED); 6363 6364 return dedicatedAllocationTestsGroup; 6365 } 6366 6367 } // anonymous 6368 6369 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx) 6370 { 6371 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests")); 6372 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx); 6373 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx); 6374 6375 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx)); 6376 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx)); 6377 6378 renderpassTests->addChild(suballocationTestGroup.release()); 6379 renderpassTests->addChild(dedicatedAllocationTestGroup.release()); 6380 6381 return renderpassTests.release(); 6382 } 6383 6384 } // vkt 6385