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