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