1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief RenderPass tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassTests.hpp"
26 #include "vktRenderPassMultisampleTests.hpp"
27 #include "vktRenderPassMultisampleResolveTests.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "vktTestGroupUtil.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkStrUtil.hpp"
42 #include "vkTypeUtil.hpp"
44 #include "tcuFloat.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
52 #include "deRandom.hpp"
53 #include "deSTLUtil.hpp"
54 #include "deSharedPtr.hpp"
55 #include "deStringUtil.hpp"
56 #include "deUniquePtr.hpp"
77 using tcu::ConstPixelBufferAccess;
78 using tcu::PixelBufferAccess;
95 ALLOCATION_KIND_SUBALLOCATED,
96 ALLOCATION_KIND_DEDICATED,
99 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
100 const DeviceInterface& vkd,
101 const VkPhysicalDevice& physDevice,
102 const VkDevice device,
103 const VkBuffer& buffer,
104 const MemoryRequirement requirement,
105 Allocator& allocator,
106 AllocationKind allocationKind)
108 switch (allocationKind)
110 case ALLOCATION_KIND_SUBALLOCATED:
112 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
114 return allocator.allocate(memoryRequirements, requirement);
117 case ALLOCATION_KIND_DEDICATED:
119 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
124 TCU_THROW(InternalError, "Invalid allocation kind");
129 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
130 const DeviceInterface& vkd,
131 const VkPhysicalDevice& physDevice,
132 const VkDevice device,
133 const VkImage& image,
134 const MemoryRequirement requirement,
135 Allocator& allocator,
136 AllocationKind allocationKind)
138 switch (allocationKind)
140 case ALLOCATION_KIND_SUBALLOCATED:
142 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
144 return allocator.allocate(memoryRequirements, requirement);
147 case ALLOCATION_KIND_DEDICATED:
149 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
154 TCU_THROW(InternalError, "Invalid allocation kind");
167 const char* boolOpToString (BoolOp op)
184 DE_FATAL("Unknown boolean operation.");
189 bool performBoolOp (BoolOp op, bool a, bool b)
206 DE_FATAL("Unknown boolean operation.");
211 BoolOp boolOpFromIndex (size_t index)
221 return ops[index % DE_LENGTH_OF_ARRAY(ops)];
224 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
226 VkFramebufferCreateFlags pCreateInfo_flags,
227 VkRenderPass pCreateInfo_renderPass,
228 deUint32 pCreateInfo_attachmentCount,
229 const VkImageView* pCreateInfo_pAttachments,
230 deUint32 pCreateInfo_width,
231 deUint32 pCreateInfo_height,
232 deUint32 pCreateInfo_layers)
234 const VkFramebufferCreateInfo pCreateInfo =
236 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
239 pCreateInfo_renderPass,
240 pCreateInfo_attachmentCount,
241 pCreateInfo_pAttachments,
246 return createFramebuffer(vk, device, &pCreateInfo);
249 Move<VkImage> createImage (const DeviceInterface& vk,
251 VkImageCreateFlags pCreateInfo_flags,
252 VkImageType pCreateInfo_imageType,
253 VkFormat pCreateInfo_format,
254 VkExtent3D pCreateInfo_extent,
255 deUint32 pCreateInfo_mipLevels,
256 deUint32 pCreateInfo_arrayLayers,
257 VkSampleCountFlagBits pCreateInfo_samples,
258 VkImageTiling pCreateInfo_tiling,
259 VkImageUsageFlags pCreateInfo_usage,
260 VkSharingMode pCreateInfo_sharingMode,
261 deUint32 pCreateInfo_queueFamilyCount,
262 const deUint32* pCreateInfo_pQueueFamilyIndices,
263 VkImageLayout pCreateInfo_initialLayout)
265 const VkImageCreateInfo pCreateInfo =
267 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
270 pCreateInfo_imageType,
273 pCreateInfo_mipLevels,
274 pCreateInfo_arrayLayers,
278 pCreateInfo_sharingMode,
279 pCreateInfo_queueFamilyCount,
280 pCreateInfo_pQueueFamilyIndices,
281 pCreateInfo_initialLayout
283 return createImage(vk, device, &pCreateInfo);
286 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
288 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
291 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
293 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
296 Move<VkImageView> createImageView (const DeviceInterface& vk,
298 VkImageViewCreateFlags pCreateInfo_flags,
299 VkImage pCreateInfo_image,
300 VkImageViewType pCreateInfo_viewType,
301 VkFormat pCreateInfo_format,
302 VkComponentMapping pCreateInfo_components,
303 VkImageSubresourceRange pCreateInfo_subresourceRange)
305 const VkImageViewCreateInfo pCreateInfo =
307 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
311 pCreateInfo_viewType,
313 pCreateInfo_components,
314 pCreateInfo_subresourceRange,
316 return createImageView(vk, device, &pCreateInfo);
319 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
321 VkBufferCreateFlags pCreateInfo_flags,
322 VkDeviceSize pCreateInfo_size,
323 VkBufferUsageFlags pCreateInfo_usage,
324 VkSharingMode pCreateInfo_sharingMode,
325 deUint32 pCreateInfo_queueFamilyCount,
326 const deUint32* pCreateInfo_pQueueFamilyIndices)
328 const VkBufferCreateInfo pCreateInfo =
330 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
335 pCreateInfo_sharingMode,
336 pCreateInfo_queueFamilyCount,
337 pCreateInfo_pQueueFamilyIndices,
339 return createBuffer(vk, device, &pCreateInfo);
342 void cmdBeginRenderPass (const DeviceInterface& vk,
343 VkCommandBuffer cmdBuffer,
344 VkRenderPass pRenderPassBegin_renderPass,
345 VkFramebuffer pRenderPassBegin_framebuffer,
346 VkRect2D pRenderPassBegin_renderArea,
347 deUint32 pRenderPassBegin_clearValueCount,
348 const VkClearValue* pRenderPassBegin_pAttachmentClearValues,
349 VkSubpassContents contents)
351 const VkRenderPassBeginInfo pRenderPassBegin =
353 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
355 pRenderPassBegin_renderPass,
356 pRenderPassBegin_framebuffer,
357 pRenderPassBegin_renderArea,
358 pRenderPassBegin_clearValueCount,
359 pRenderPassBegin_pAttachmentClearValues,
361 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
364 void beginCommandBuffer (const DeviceInterface& vk,
365 VkCommandBuffer cmdBuffer,
366 VkCommandBufferUsageFlags pBeginInfo_flags,
367 VkRenderPass pInheritanceInfo_renderPass,
368 deUint32 pInheritanceInfo_subpass,
369 VkFramebuffer pInheritanceInfo_framebuffer,
370 VkBool32 pInheritanceInfo_occlusionQueryEnable,
371 VkQueryControlFlags pInheritanceInfo_queryFlags,
372 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
374 const VkCommandBufferInheritanceInfo pInheritanceInfo =
376 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
378 pInheritanceInfo_renderPass,
379 pInheritanceInfo_subpass,
380 pInheritanceInfo_framebuffer,
381 pInheritanceInfo_occlusionQueryEnable,
382 pInheritanceInfo_queryFlags,
383 pInheritanceInfo_pipelineStatistics,
385 const VkCommandBufferBeginInfo pBeginInfo =
387 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
392 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
395 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
397 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
400 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
402 const VkSubmitInfo submitInfo =
404 VK_STRUCTURE_TYPE_SUBMIT_INFO,
406 0u, // waitSemaphoreCount
407 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
408 (const VkPipelineStageFlags*)DE_NULL,
409 cmdBufferCount, // commandBufferCount
411 0u, // signalSemaphoreCount
412 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
414 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
417 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
419 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
422 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
424 const tcu::TextureFormat format = mapVkFormat(vkFormat);
426 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
428 switch (format.order)
430 case tcu::TextureFormat::DS:
431 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
433 case tcu::TextureFormat::D:
434 return VK_IMAGE_ASPECT_DEPTH_BIT;
436 case tcu::TextureFormat::S:
437 return VK_IMAGE_ASPECT_STENCIL_BIT;
440 return VK_IMAGE_ASPECT_COLOR_BIT;
444 VkAccessFlags getAllMemoryReadFlags (void)
446 return VK_ACCESS_TRANSFER_READ_BIT
447 | VK_ACCESS_UNIFORM_READ_BIT
448 | VK_ACCESS_HOST_READ_BIT
449 | VK_ACCESS_INDEX_READ_BIT
450 | VK_ACCESS_SHADER_READ_BIT
451 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
452 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
453 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
454 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
455 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
458 VkAccessFlags getAllMemoryWriteFlags (void)
460 return VK_ACCESS_TRANSFER_WRITE_BIT
461 | VK_ACCESS_HOST_WRITE_BIT
462 | VK_ACCESS_SHADER_WRITE_BIT
463 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
464 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
467 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
471 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
472 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
473 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
474 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
475 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT;
476 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT;
477 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT;
480 return (VkAccessFlags)0;
484 VkPipelineStageFlags getAllPipelineStageFlags (void)
486 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
487 | VK_PIPELINE_STAGE_TRANSFER_BIT
488 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
489 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
490 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
491 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
492 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
493 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
494 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
495 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
496 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
497 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
498 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
501 class AttachmentReference
504 AttachmentReference (deUint32 attachment,
505 VkImageLayout layout)
506 : m_attachment (attachment)
511 deUint32 getAttachment (void) const { return m_attachment; }
512 VkImageLayout getImageLayout (void) const { return m_layout; }
515 deUint32 m_attachment;
516 VkImageLayout m_layout;
522 Subpass (VkPipelineBindPoint pipelineBindPoint,
523 VkSubpassDescriptionFlags flags,
524 const vector<AttachmentReference>& inputAttachments,
525 const vector<AttachmentReference>& colorAttachments,
526 const vector<AttachmentReference>& resolveAttachments,
527 AttachmentReference depthStencilAttachment,
528 const vector<deUint32>& preserveAttachments)
529 : m_pipelineBindPoint (pipelineBindPoint)
531 , m_inputAttachments (inputAttachments)
532 , m_colorAttachments (colorAttachments)
533 , m_resolveAttachments (resolveAttachments)
534 , m_depthStencilAttachment (depthStencilAttachment)
535 , m_preserveAttachments (preserveAttachments)
539 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
540 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
541 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
542 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
543 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
544 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
545 const vector<deUint32>& getPreserveAttachments (void) const { return m_preserveAttachments; }
548 VkPipelineBindPoint m_pipelineBindPoint;
549 VkSubpassDescriptionFlags m_flags;
551 vector<AttachmentReference> m_inputAttachments;
552 vector<AttachmentReference> m_colorAttachments;
553 vector<AttachmentReference> m_resolveAttachments;
554 AttachmentReference m_depthStencilAttachment;
556 vector<deUint32> m_preserveAttachments;
559 class SubpassDependency
562 SubpassDependency (deUint32 srcPass,
565 VkPipelineStageFlags srcStageMask,
566 VkPipelineStageFlags dstStageMask,
568 VkAccessFlags outputMask,
569 VkAccessFlags inputMask,
571 VkDependencyFlags flags)
572 : m_srcPass (srcPass)
573 , m_dstPass (dstPass)
575 , m_srcStageMask (srcStageMask)
576 , m_dstStageMask (dstStageMask)
578 , m_outputMask (outputMask)
579 , m_inputMask (inputMask)
584 deUint32 getSrcPass (void) const { return m_srcPass; }
585 deUint32 getDstPass (void) const { return m_dstPass; }
587 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
588 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
590 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
591 VkAccessFlags getInputMask (void) const { return m_inputMask; }
593 VkDependencyFlags getFlags (void) const { return m_flags; }
599 VkPipelineStageFlags m_srcStageMask;
600 VkPipelineStageFlags m_dstStageMask;
602 VkAccessFlags m_outputMask;
603 VkAccessFlags m_inputMask;
604 VkDependencyFlags m_flags;
610 Attachment (VkFormat format,
611 VkSampleCountFlagBits samples,
613 VkAttachmentLoadOp loadOp,
614 VkAttachmentStoreOp storeOp,
616 VkAttachmentLoadOp stencilLoadOp,
617 VkAttachmentStoreOp stencilStoreOp,
619 VkImageLayout initialLayout,
620 VkImageLayout finalLayout)
622 , m_samples (samples)
625 , m_storeOp (storeOp)
627 , m_stencilLoadOp (stencilLoadOp)
628 , m_stencilStoreOp (stencilStoreOp)
630 , m_initialLayout (initialLayout)
631 , m_finalLayout (finalLayout)
635 VkFormat getFormat (void) const { return m_format; }
636 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
638 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
639 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
642 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
643 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
645 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
646 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
650 VkSampleCountFlagBits m_samples;
652 VkAttachmentLoadOp m_loadOp;
653 VkAttachmentStoreOp m_storeOp;
655 VkAttachmentLoadOp m_stencilLoadOp;
656 VkAttachmentStoreOp m_stencilStoreOp;
658 VkImageLayout m_initialLayout;
659 VkImageLayout m_finalLayout;
665 RenderPass (const vector<Attachment>& attachments,
666 const vector<Subpass>& subpasses,
667 const vector<SubpassDependency>& dependencies,
668 const vector<VkInputAttachmentAspectReferenceKHR> inputAspects = vector<VkInputAttachmentAspectReferenceKHR>())
669 : m_attachments (attachments)
670 , m_subpasses (subpasses)
671 , m_dependencies (dependencies)
672 , m_inputAspects (inputAspects)
676 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
677 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
678 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
679 const vector<VkInputAttachmentAspectReferenceKHR> getInputAspects (void) const { return m_inputAspects; }
682 const vector<Attachment> m_attachments;
683 const vector<Subpass> m_subpasses;
684 const vector<SubpassDependency> m_dependencies;
685 const vector<VkInputAttachmentAspectReferenceKHR> m_inputAspects;
692 RENDERTYPES_NONE = 0,
693 RENDERTYPES_CLEAR = (1<<1),
694 RENDERTYPES_DRAW = (1<<2)
697 enum CommandBufferTypes
699 COMMANDBUFFERTYPES_INLINE = (1<<0),
700 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
705 IMAGEMEMORY_STRICT = (1<<0),
706 IMAGEMEMORY_LAZY = (1<<1)
709 TestConfig (const RenderPass& renderPass_,
710 RenderTypes renderTypes_,
711 CommandBufferTypes commandBufferTypes_,
712 ImageMemory imageMemory_,
713 const UVec2& targetSize_,
714 const UVec2& renderPos_,
715 const UVec2& renderSize_,
717 AllocationKind allocationKind_)
718 : renderPass (renderPass_)
719 , renderTypes (renderTypes_)
720 , commandBufferTypes (commandBufferTypes_)
721 , imageMemory (imageMemory_)
722 , targetSize (targetSize_)
723 , renderPos (renderPos_)
724 , renderSize (renderSize_)
726 , allocationKind (allocationKind_)
730 RenderPass renderPass;
731 RenderTypes renderTypes;
732 CommandBufferTypes commandBufferTypes;
733 ImageMemory imageMemory;
738 AllocationKind allocationKind;
741 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
743 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
746 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
748 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
751 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
753 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
756 void logRenderPassInfo (TestLog& log,
757 const RenderPass& renderPass)
759 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
762 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
763 const vector<Attachment>& attachments = renderPass.getAttachments();
765 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
767 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
768 const Attachment& attachment = attachments[attachmentNdx];
770 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
771 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
773 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
774 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
776 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
777 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
779 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
780 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
784 if (!renderPass.getInputAspects().empty())
786 const tcu::ScopedLogSection inputAspectSection (log, "InputAspects", "InputAspects");
788 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
790 const VkInputAttachmentAspectReferenceKHR& inputAspect (renderPass.getInputAspects()[aspectNdx]);
792 log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
793 log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex << TestLog::EndMessage;
794 log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask) << TestLog::EndMessage;
799 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
800 const vector<Subpass>& subpasses = renderPass.getSubpasses();
802 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
804 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
805 const Subpass& subpass = subpasses[subpassNdx];
807 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
808 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
809 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
810 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments();
812 if (!inputAttachments.empty())
814 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
816 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
818 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
819 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
821 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
822 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
826 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
828 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
829 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
831 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
832 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
835 if (!colorAttachments.empty())
837 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
839 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
841 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
842 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
844 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
845 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
849 if (!resolveAttachments.empty())
851 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
853 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
855 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
856 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
858 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
859 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
863 if (!preserveAttachments.empty())
865 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
867 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
869 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
870 const deUint32 preserveAttachment = preserveAttachments[preserveNdx];
872 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
879 if (!renderPass.getDependencies().empty())
881 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
883 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
885 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
886 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
888 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
889 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
891 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
892 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
894 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
895 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
896 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
901 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
903 const tcu::TextureFormat format = mapVkFormat(vkFormat);
904 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
905 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
907 std::ostringstream stream;
911 switch (channelClass)
913 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
914 for (int i = 0; i < 4; i++)
920 stream << value.int32[i];
926 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
927 for (int i = 0; i < 4; i++)
933 stream << value.uint32[i];
939 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
940 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
941 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
942 for (int i = 0; i < 4; i++)
948 stream << value.float32[i];
955 DE_FATAL("Unknown channel class");
963 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
965 const tcu::TextureFormat format = mapVkFormat(vkFormat);
967 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
969 std::ostringstream stream;
973 if (tcu::hasStencilComponent(format.order))
974 stream << "stencil: " << value.depthStencil.stencil;
976 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
979 if (tcu::hasDepthComponent(format.order))
980 stream << "depth: " << value.depthStencil.depth;
987 return clearColorToString(vkFormat, value.color);
990 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
992 const float clearNan = tcu::Float32::nan().asFloat();
993 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
994 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
995 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
996 VkClearColorValue clearColor;
998 switch (channelClass)
1000 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1002 for (int ndx = 0; ndx < 4; ndx++)
1004 if (!channelMask[ndx])
1005 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
1007 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1012 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1014 for (int ndx = 0; ndx < 4; ndx++)
1016 if (!channelMask[ndx])
1017 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
1019 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1024 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1025 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1026 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1028 for (int ndx = 0; ndx < 4; ndx++)
1030 if (!channelMask[ndx])
1031 clearColor.float32[ndx] = clearNan;
1033 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1039 DE_FATAL("Unknown channel class");
1045 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
1047 const VkAttachmentDescription attachmentDescription =
1051 attachment.getFormat(), // format
1052 attachment.getSamples(), // samples
1054 attachment.getLoadOp(), // loadOp
1055 attachment.getStoreOp(), // storeOp
1057 attachment.getStencilLoadOp(), // stencilLoadOp
1058 attachment.getStencilStoreOp(), // stencilStoreOp
1060 attachment.getInitialLayout(), // initialLayout
1061 attachment.getFinalLayout(), // finalLayout
1064 return attachmentDescription;
1067 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
1069 const VkAttachmentReference reference =
1071 referenceInfo.getAttachment(), // attachment;
1072 referenceInfo.getImageLayout() // layout;
1078 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
1079 vector<VkAttachmentReference>* attachmentReferenceLists,
1080 vector<deUint32>* preserveAttachmentReferences)
1082 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
1083 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
1084 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
1085 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
1087 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1088 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
1090 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1091 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
1093 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1094 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
1096 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
1098 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1099 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1101 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1104 const VkSubpassDescription subpassDescription =
1106 subpass.getFlags(), // flags;
1107 subpass.getPipelineBindPoint(), // pipelineBindPoint;
1109 (deUint32)inputAttachmentReferences.size(), // inputCount;
1110 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1112 (deUint32)colorAttachmentReferences.size(), // colorCount;
1113 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1114 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1116 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1117 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1118 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1121 return subpassDescription;
1125 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1127 const VkSubpassDependency dependency =
1129 dependencyInfo.getSrcPass(), // srcSubpass;
1130 dependencyInfo.getDstPass(), // destSubpass;
1132 dependencyInfo.getSrcStageMask(), // srcStageMask;
1133 dependencyInfo.getDstStageMask(), // destStageMask;
1135 dependencyInfo.getOutputMask(), // outputMask;
1136 dependencyInfo.getInputMask(), // inputMask;
1138 dependencyInfo.getFlags() // dependencyFlags;
1144 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1146 const RenderPass& renderPassInfo)
1148 const size_t perSubpassAttachmentReferenceLists = 4;
1149 vector<VkAttachmentDescription> attachments;
1150 vector<VkSubpassDescription> subpasses;
1151 vector<VkSubpassDependency> dependencies;
1152 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1153 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1155 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1156 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1158 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1159 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1161 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1162 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1164 if (renderPassInfo.getInputAspects().empty())
1166 const VkRenderPassCreateInfo createInfo =
1168 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1170 (VkRenderPassCreateFlags)0u,
1171 (deUint32)attachments.size(),
1172 (attachments.empty() ? DE_NULL : &attachments[0]),
1173 (deUint32)subpasses.size(),
1174 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1175 (deUint32)dependencies.size(),
1176 (dependencies.empty() ? DE_NULL : &dependencies[0])
1179 return createRenderPass(vk, device, &createInfo);
1183 const VkRenderPassInputAttachmentAspectCreateInfoKHR inputAspectCreateInfo =
1185 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR,
1188 (deUint32)renderPassInfo.getInputAspects().size(),
1189 renderPassInfo.getInputAspects().data(),
1191 const VkRenderPassCreateInfo createInfo =
1193 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1194 &inputAspectCreateInfo,
1195 (VkRenderPassCreateFlags)0u,
1196 (deUint32)attachments.size(),
1197 (attachments.empty() ? DE_NULL : &attachments[0]),
1198 (deUint32)subpasses.size(),
1199 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1200 (deUint32)dependencies.size(),
1201 (dependencies.empty() ? DE_NULL : &dependencies[0])
1204 return createRenderPass(vk, device, &createInfo);
1208 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1210 VkRenderPass renderPass,
1212 const vector<VkImageView>& attachments)
1214 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1217 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1219 deUint32 queueIndex,
1222 VkSampleCountFlagBits samples,
1223 VkImageUsageFlags usageFlags,
1224 VkImageLayout layout)
1226 VkImageUsageFlags targetUsageFlags = 0;
1227 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1229 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1230 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1232 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1233 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1235 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1236 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1238 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1240 return createImage(vk, device,
1241 (VkImageCreateFlags)0,
1244 vk::makeExtent3D(size.x(), size.y(), 1u),
1248 VK_IMAGE_TILING_OPTIMAL,
1249 usageFlags | targetUsageFlags,
1250 VK_SHARING_MODE_EXCLUSIVE,
1256 de::MovePtr<Allocation> createImageMemory (const InstanceInterface& vki,
1257 const VkPhysicalDevice& vkd,
1258 const DeviceInterface& vk,
1260 Allocator& allocator,
1263 AllocationKind allocationKind)
1265 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1266 de::MovePtr<Allocation> allocation = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1268 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1273 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1277 VkImageAspectFlags aspect)
1279 const VkImageSubresourceRange range =
1288 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1291 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1293 const float clearNan = tcu::Float32::nan().asFloat();
1294 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1296 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1298 VkClearValue clearValue;
1300 clearValue.depthStencil.depth = clearNan;
1301 clearValue.depthStencil.stencil = 0xCDu;
1303 if (tcu::hasStencilComponent(format.order))
1304 clearValue.depthStencil.stencil = rng.getBool()
1308 if (tcu::hasDepthComponent(format.order))
1309 clearValue.depthStencil.depth = rng.getBool()
1317 VkClearValue clearValue;
1319 clearValue.color = randomColorClearValue(attachment, rng);
1325 class AttachmentResources
1328 AttachmentResources (const InstanceInterface& vki,
1329 const VkPhysicalDevice& physDevice,
1330 const DeviceInterface& vk,
1332 Allocator& allocator,
1333 deUint32 queueIndex,
1335 const Attachment& attachmentInfo,
1336 VkImageUsageFlags usageFlags,
1337 const AllocationKind allocationKind)
1338 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1339 , m_imageMemory (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
1340 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1342 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1343 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1344 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1346 if (isDepthFormat && isStencilFormat)
1348 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1349 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1351 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1354 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1356 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1358 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1360 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1361 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1363 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1364 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1366 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1367 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1369 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1371 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1372 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1374 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1378 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1380 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1381 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1383 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1388 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1390 return m_inputAttachmentViews;
1393 ~AttachmentResources (void)
1397 VkImageView getAttachmentView (void) const
1399 return *m_attachmentView;
1402 VkImage getImage (void) const
1407 VkBuffer getBuffer (void) const
1409 DE_ASSERT(*m_buffer != DE_NULL);
1413 VkDeviceSize getBufferSize (void) const
1415 DE_ASSERT(*m_buffer != DE_NULL);
1416 return m_bufferSize;
1419 const Allocation& getResultMemory (void) const
1421 DE_ASSERT(m_bufferMemory);
1422 return *m_bufferMemory;
1425 VkBuffer getSecondaryBuffer (void) const
1427 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1428 return *m_secondaryBuffer;
1431 VkDeviceSize getSecondaryBufferSize (void) const
1433 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1434 return m_secondaryBufferSize;
1437 const Allocation& getSecondaryResultMemory (void) const
1439 DE_ASSERT(m_secondaryBufferMemory);
1440 return *m_secondaryBufferMemory;
1444 const Unique<VkImage> m_image;
1445 const UniquePtr<Allocation> m_imageMemory;
1446 const Unique<VkImageView> m_attachmentView;
1448 Move<VkImageView> m_depthInputAttachmentView;
1449 Move<VkImageView> m_stencilInputAttachmentView;
1450 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1452 Move<VkBuffer> m_buffer;
1453 VkDeviceSize m_bufferSize;
1454 de::MovePtr<Allocation> m_bufferMemory;
1456 Move<VkBuffer> m_secondaryBuffer;
1457 VkDeviceSize m_secondaryBufferSize;
1458 de::MovePtr<Allocation> m_secondaryBufferMemory;
1461 void uploadBufferData (const DeviceInterface& vk,
1463 const Allocation& memory,
1467 const VkMappedMemoryRange range =
1469 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1471 memory.getMemory(), // mem;
1472 memory.getOffset(), // offset;
1473 (VkDeviceSize)size // size;
1475 void* const ptr = memory.getHostPtr();
1477 deMemcpy(ptr, data, size);
1478 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1481 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1483 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1487 case tcu::TextureFormat::D:
1488 case tcu::TextureFormat::DS:
1489 return VK_IMAGE_ASPECT_DEPTH_BIT;
1491 case tcu::TextureFormat::S:
1492 return VK_IMAGE_ASPECT_STENCIL_BIT;
1495 return VK_IMAGE_ASPECT_COLOR_BIT;
1502 RenderQuad (const Vec2& posA, const Vec2& posB)
1505 m_vertices[0] = posA;
1506 m_vertices[1] = Vec2(posA[0], posB[1]);
1507 m_vertices[2] = posB;
1509 m_vertices[3] = posB;
1510 m_vertices[4] = Vec2(posB[0], posA[1]);
1511 m_vertices[5] = posA;
1514 const Vec2& getCornerA (void) const
1516 return m_vertices[0];
1519 const Vec2& getCornerB (void) const
1521 return m_vertices[2];
1524 const void* getVertexPointer (void) const
1526 return &m_vertices[0];
1529 size_t getVertexDataSize (void) const
1531 return sizeof(Vec2) * m_vertices.size();
1535 vector<Vec2> m_vertices;
1541 ColorClear (const UVec2& offset,
1543 const VkClearColorValue& color)
1550 const UVec2& getOffset (void) const { return m_offset; }
1551 const UVec2& getSize (void) const { return m_size; }
1552 const VkClearColorValue& getColor (void) const { return m_color; }
1557 VkClearColorValue m_color;
1560 class DepthStencilClear
1563 DepthStencilClear (const UVec2& offset,
1570 , m_stencil (stencil)
1574 const UVec2& getOffset (void) const { return m_offset; }
1575 const UVec2& getSize (void) const { return m_size; }
1576 float getDepth (void) const { return m_depth; }
1577 deUint32 getStencil (void) const { return m_stencil; }
1580 const UVec2 m_offset;
1583 const float m_depth;
1584 const deUint32 m_stencil;
1587 class SubpassRenderInfo
1590 SubpassRenderInfo (const RenderPass& renderPass,
1591 deUint32 subpassIndex,
1595 const UVec2& viewportOffset,
1596 const UVec2& viewportSize,
1598 const Maybe<RenderQuad>& renderQuad,
1599 const vector<ColorClear>& colorClears,
1600 const Maybe<DepthStencilClear>& depthStencilClear)
1601 : m_viewportOffset (viewportOffset)
1602 , m_viewportSize (viewportSize)
1603 , m_subpassIndex (subpassIndex)
1604 , m_isSecondary (isSecondary_)
1605 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1606 , m_renderQuad (renderQuad)
1607 , m_colorClears (colorClears)
1608 , m_depthStencilClear (depthStencilClear)
1609 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1610 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1612 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1613 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1615 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1617 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1618 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1622 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1623 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1625 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1626 bool isSecondary (void) const { return m_isSecondary; }
1628 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1629 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1630 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1632 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); }
1633 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
1634 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1636 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1637 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1638 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1639 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1640 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1641 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1642 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1643 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1646 UVec2 m_viewportOffset;
1647 UVec2 m_viewportSize;
1649 deUint32 m_subpassIndex;
1651 VkSubpassDescriptionFlags m_flags;
1653 Maybe<RenderQuad> m_renderQuad;
1654 vector<ColorClear> m_colorClears;
1655 Maybe<DepthStencilClear> m_depthStencilClear;
1657 vector<AttachmentReference> m_colorAttachments;
1658 vector<Attachment> m_colorAttachmentInfo;
1660 Maybe<AttachmentReference> m_depthStencilAttachment;
1661 Maybe<Attachment> m_depthStencilAttachmentInfo;
1663 vector<AttachmentReference> m_inputAttachments;
1666 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1668 VkRenderPass renderPass,
1669 VkShaderModule vertexShaderModule,
1670 VkShaderModule fragmentShaderModule,
1671 VkPipelineLayout pipelineLayout,
1672 const SubpassRenderInfo& renderInfo)
1674 const VkSpecializationInfo emptyShaderSpecializations =
1676 0u, // mapEntryCount
1682 Maybe<VkSampleCountFlagBits> rasterSamples;
1683 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1685 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1687 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1689 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1691 rasterSamples = attachment.getSamples();
1694 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1696 VK_FALSE, // blendEnable
1697 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1698 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1699 VK_BLEND_OP_ADD, // blendOpColor
1700 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1701 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1702 VK_BLEND_OP_ADD, // blendOpAlpha
1703 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1706 attachmentBlendStates.push_back(attachmentBlendState);
1710 if (renderInfo.getDepthStencilAttachment())
1712 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1714 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1715 rasterSamples = attachment.getSamples();
1718 // If there are no attachment use single sample
1720 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1722 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1725 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1727 (VkPipelineShaderStageCreateFlags)0u,
1728 VK_SHADER_STAGE_VERTEX_BIT, // stage
1729 vertexShaderModule, // shader
1731 &emptyShaderSpecializations
1734 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1736 (VkPipelineShaderStageCreateFlags)0u,
1737 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1738 fragmentShaderModule, // shader
1740 &emptyShaderSpecializations
1743 const VkVertexInputBindingDescription vertexBinding =
1746 (deUint32)sizeof(tcu::Vec2), // strideInBytes
1747 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1749 const VkVertexInputAttributeDescription vertexAttrib =
1753 VK_FORMAT_R32G32_SFLOAT, // format
1754 0u, // offsetInBytes
1756 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1758 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1760 (VkPipelineVertexInputStateCreateFlags)0u,
1762 &vertexBinding, // pVertexBindingDescriptions
1763 1u, // attributeCount
1764 &vertexAttrib, // pVertexAttributeDescriptions
1766 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1768 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1770 (VkPipelineInputAssemblyStateCreateFlags)0u,
1771 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1772 VK_FALSE, // primitiveRestartEnable
1774 const VkViewport viewport =
1776 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1777 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1780 const VkRect2D scissor =
1782 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1783 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1785 const VkPipelineViewportStateCreateInfo viewportState =
1787 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1789 (VkPipelineViewportStateCreateFlags)0u,
1795 const VkPipelineRasterizationStateCreateInfo rasterState =
1797 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1799 (VkPipelineRasterizationStateCreateFlags)0u,
1800 VK_TRUE, // depthClipEnable
1801 VK_FALSE, // rasterizerDiscardEnable
1802 VK_POLYGON_MODE_FILL, // fillMode
1803 VK_CULL_MODE_NONE, // cullMode
1804 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1805 VK_FALSE, // depthBiasEnable
1807 0.0f, // depthBiasClamp
1808 0.0f, // slopeScaledDepthBias
1811 const VkPipelineMultisampleStateCreateInfo multisampleState =
1813 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1815 (VkPipelineMultisampleStateCreateFlags)0u,
1816 *rasterSamples, // rasterSamples
1817 VK_FALSE, // sampleShadingEnable
1818 0.0f, // minSampleShading
1819 DE_NULL, // pSampleMask
1820 VK_FALSE, // alphaToCoverageEnable
1821 VK_FALSE, // alphaToOneEnable
1823 const size_t stencilIndex = renderInfo.getSubpassIndex();
1824 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1826 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1828 (VkPipelineDepthStencilStateCreateFlags)0u,
1829 VK_TRUE, // depthTestEnable
1830 VK_TRUE, // depthWriteEnable
1831 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1832 VK_FALSE, // depthBoundsEnable
1833 VK_TRUE, // stencilTestEnable
1835 VK_STENCIL_OP_REPLACE, // stencilFailOp
1836 VK_STENCIL_OP_REPLACE, // stencilPassOp
1837 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1838 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1839 ~0u, // stencilCompareMask
1840 ~0u, // stencilWriteMask
1841 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1844 VK_STENCIL_OP_REPLACE, // stencilFailOp
1845 VK_STENCIL_OP_REPLACE, // stencilPassOp
1846 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1847 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1848 ~0u, // stencilCompareMask
1849 ~0u, // stencilWriteMask
1850 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1853 0.0f, // minDepthBounds;
1854 1.0f // maxDepthBounds;
1856 const VkPipelineColorBlendStateCreateInfo blendState =
1858 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1860 (VkPipelineColorBlendStateCreateFlags)0u,
1861 VK_FALSE, // logicOpEnable
1862 VK_LOGIC_OP_COPY, // logicOp
1863 (deUint32)attachmentBlendStates.size(), // attachmentCount
1864 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1865 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1867 const VkGraphicsPipelineCreateInfo createInfo =
1869 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1871 (VkPipelineCreateFlags)0u,
1874 shaderStages, // pStages
1876 &vertexInputState, // pVertexInputState
1877 &inputAssemblyState, // pInputAssemblyState
1878 DE_NULL, // pTessellationState
1879 &viewportState, // pViewportState
1880 &rasterState, // pRasterState
1881 &multisampleState, // pMultisampleState
1882 &depthStencilState, // pDepthStencilState
1883 &blendState, // pColorBlendState
1884 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1885 pipelineLayout, // layout
1887 renderPass, // renderPass
1888 renderInfo.getSubpassIndex(), // subpass
1889 DE_NULL, // basePipelineHandle
1890 0u // basePipelineIndex
1893 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1896 class SubpassRenderer
1899 SubpassRenderer (Context& context,
1900 const DeviceInterface& vk,
1902 Allocator& allocator,
1903 VkRenderPass renderPass,
1904 VkFramebuffer framebuffer,
1905 VkCommandPool commandBufferPool,
1906 deUint32 queueFamilyIndex,
1907 const vector<VkImage>& attachmentImages,
1908 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
1909 const SubpassRenderInfo& renderInfo,
1910 const vector<Attachment>& attachmentInfos,
1911 const AllocationKind allocationKind)
1912 : m_renderInfo (renderInfo)
1914 const InstanceInterface& vki = context.getInstanceInterface();
1915 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
1916 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1917 vector<VkDescriptorSetLayoutBinding> bindings;
1919 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
1920 m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);
1922 if (renderInfo.getDepthStencilAttachmentIndex())
1923 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
1925 if (renderInfo.getRenderQuad())
1927 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1929 if (renderInfo.getInputAttachmentCount() > 0)
1931 deUint32 bindingIndex = 0;
1933 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1935 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1936 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1937 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1938 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1939 const deUint32 bindingCount = isDepthFormat && isStencilFormat ? 2u : 1u;
1941 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
1943 const VkDescriptorSetLayoutBinding binding =
1946 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1948 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1952 bindings.push_back(binding);
1957 const VkDescriptorSetLayoutCreateInfo createInfo =
1959 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1963 (deUint32)bindings.size(),
1967 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
1970 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
1971 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1973 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1975 (vk::VkPipelineLayoutCreateFlags)0,
1976 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
1977 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
1978 0u, // pushConstantRangeCount;
1979 DE_NULL, // pPushConstantRanges;
1982 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1983 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1984 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1985 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1987 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1988 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1990 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1991 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1993 if (renderInfo.getInputAttachmentCount() > 0)
1996 const VkDescriptorPoolSize poolSize =
1998 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1999 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2000 renderInfo.getInputAttachmentCount() * 2u
2002 const VkDescriptorPoolCreateInfo createInfo =
2004 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2006 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2008 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2009 renderInfo.getInputAttachmentCount() * 2u,
2014 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2017 const VkDescriptorSetAllocateInfo allocateInfo =
2019 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2024 &descriptorSetLayout
2027 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2030 vector<VkWriteDescriptorSet> writes (bindings.size());
2031 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
2032 deUint32 bindingIndex = 0;
2034 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2036 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2037 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2038 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2039 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2040 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2042 if (isDepthFormat && isStencilFormat)
2045 const VkDescriptorImageInfo imageInfo =
2048 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2049 inputAttachmentLayout
2051 imageInfos[bindingIndex] = imageInfo;
2054 const VkWriteDescriptorSet write =
2056 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2063 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2064 &imageInfos[bindingIndex],
2068 writes[bindingIndex] = write;
2074 const VkDescriptorImageInfo imageInfo =
2077 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2078 inputAttachmentLayout
2080 imageInfos[bindingIndex] = imageInfo;
2083 const VkWriteDescriptorSet write =
2085 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2092 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2093 &imageInfos[bindingIndex],
2097 writes[bindingIndex] = write;
2105 const VkDescriptorImageInfo imageInfo =
2108 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2109 inputAttachmentLayout
2111 imageInfos[bindingIndex] = imageInfo;
2114 const VkWriteDescriptorSet write =
2116 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2123 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2124 &imageInfos[bindingIndex],
2128 writes[bindingIndex] = write;
2135 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2140 if (renderInfo.isSecondary())
2142 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2144 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
2145 pushRenderCommands(vk, *m_commandBuffer);
2146 endCommandBuffer(vk, *m_commandBuffer);
2150 bool isSecondary (void) const
2152 return m_commandBuffer;
2155 VkCommandBuffer getCommandBuffer (void) const
2157 DE_ASSERT(isSecondary());
2158 return *m_commandBuffer;
2161 void pushRenderCommands (const DeviceInterface& vk,
2162 VkCommandBuffer commandBuffer)
2164 if (!m_renderInfo.getColorClears().empty())
2166 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2168 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2170 const ColorClear& colorClear = colorClears[attachmentNdx];
2171 const VkClearAttachment attachment =
2173 VK_IMAGE_ASPECT_COLOR_BIT,
2175 makeClearValue(colorClear.getColor()),
2177 const VkClearRect rect =
2180 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2181 { colorClear.getSize().x(), colorClear.getSize().y() }
2183 0u, // baseArrayLayer
2187 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2191 if (m_renderInfo.getDepthStencilClear())
2193 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2194 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2195 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2196 const VkClearAttachment attachment =
2198 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2199 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2201 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2203 const VkClearRect rect =
2206 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2207 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2209 0u, // baseArrayLayer
2213 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2216 vector<VkImageMemoryBarrier> selfDeps;
2217 VkPipelineStageFlags srcStages = 0;
2218 VkPipelineStageFlags dstStages = 0;
2220 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2222 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2224 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2226 const VkImageMemoryBarrier barrier =
2228 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2231 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2232 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2234 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2235 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2237 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2238 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2240 m_colorAttachmentImages[colorAttachmentNdx], // image
2241 { // subresourceRange
2242 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2245 0, // baseArraySlice
2250 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2251 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2253 selfDeps.push_back(barrier);
2257 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2259 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2260 const bool hasDepth = hasDepthComponent(format.order);
2261 const bool hasStencil = hasStencilComponent(format.order);
2262 const VkImageMemoryBarrier barrier =
2264 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2267 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2268 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2270 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2271 VK_IMAGE_LAYOUT_GENERAL, // newLayout;
2273 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2274 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2276 m_depthStencilAttachmentImage, // image;
2277 { // subresourceRange;
2278 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2279 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2282 0, // baseArraySlice;
2287 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2288 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2290 selfDeps.push_back(barrier);
2294 if (!selfDeps.empty())
2296 DE_ASSERT(srcStages != 0);
2297 DE_ASSERT(dstStages != 0);
2298 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2301 if (m_renderInfo.getRenderQuad())
2303 const VkDeviceSize offset = 0;
2304 const VkBuffer vertexBuffer = *m_vertexBuffer;
2306 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2308 if (m_descriptorSet)
2310 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2311 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2314 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2315 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2320 const SubpassRenderInfo m_renderInfo;
2321 Move<VkCommandBuffer> m_commandBuffer;
2322 Move<VkPipeline> m_pipeline;
2323 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2324 Move<VkPipelineLayout> m_pipelineLayout;
2326 Move<VkShaderModule> m_vertexShaderModule;
2327 Move<VkShaderModule> m_fragmentShaderModule;
2329 Move<VkDescriptorPool> m_descriptorPool;
2330 Move<VkDescriptorSet> m_descriptorSet;
2331 Move<VkBuffer> m_vertexBuffer;
2332 de::MovePtr<Allocation> m_vertexBufferMemory;
2333 vector<VkImage> m_colorAttachmentImages;
2334 VkImage m_depthStencilAttachmentImage;
2337 void pushImageInitializationCommands (const DeviceInterface& vk,
2338 VkCommandBuffer commandBuffer,
2339 const vector<Attachment>& attachmentInfo,
2340 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2341 deUint32 queueIndex,
2342 const vector<Maybe<VkClearValue> >& clearValues)
2345 vector<VkImageMemoryBarrier> initializeLayouts;
2347 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2349 if (!clearValues[attachmentNdx])
2352 const VkImageMemoryBarrier barrier =
2354 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2357 (VkAccessFlags)0, // srcAccessMask
2358 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2360 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2361 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2363 queueIndex, // srcQueueFamilyIndex;
2364 queueIndex, // destQueueFamilyIndex;
2366 attachmentResources[attachmentNdx]->getImage(), // image;
2367 { // subresourceRange;
2368 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2371 0, // baseArraySlice;
2376 initializeLayouts.push_back(barrier);
2379 if (!initializeLayouts.empty())
2380 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2381 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2382 0, (const VkMemoryBarrier*)DE_NULL,
2383 0, (const VkBufferMemoryBarrier*)DE_NULL,
2384 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2387 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2389 if (!clearValues[attachmentNdx])
2392 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2394 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2396 const float clearNan = tcu::Float32::nan().asFloat();
2397 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2398 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2399 const VkClearDepthStencilValue depthStencil =
2404 const VkImageSubresourceRange range =
2406 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2407 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2414 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2418 const VkImageSubresourceRange range =
2420 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2423 0, // baseArrayLayer;
2426 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2428 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2433 vector<VkImageMemoryBarrier> renderPassLayouts;
2435 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2437 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2438 const VkImageMemoryBarrier barrier =
2440 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2443 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask
2444 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2446 oldLayout, // oldLayout
2447 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2449 queueIndex, // srcQueueFamilyIndex;
2450 queueIndex, // destQueueFamilyIndex;
2452 attachmentResources[attachmentNdx]->getImage(), // image;
2453 { // subresourceRange;
2454 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2457 0, // baseArraySlice;
2462 renderPassLayouts.push_back(barrier);
2465 if (!renderPassLayouts.empty())
2466 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2467 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2468 0, (const VkMemoryBarrier*)DE_NULL,
2469 0, (const VkBufferMemoryBarrier*)DE_NULL,
2470 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2474 void pushRenderPassCommands (const DeviceInterface& vk,
2475 VkCommandBuffer commandBuffer,
2476 VkRenderPass renderPass,
2477 VkFramebuffer framebuffer,
2478 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2479 const UVec2& renderPos,
2480 const UVec2& renderSize,
2481 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2482 TestConfig::RenderTypes render)
2484 const float clearNan = tcu::Float32::nan().asFloat();
2485 vector<VkClearValue> attachmentClearValues;
2487 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2489 if (renderPassClearValues[attachmentNdx])
2490 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2492 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2496 const VkRect2D renderArea =
2498 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2499 { renderSize.x(), renderSize.y() }
2502 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2504 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2506 if (subpassNdx == 0)
2507 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2509 vk.cmdNextSubpass(commandBuffer, contents);
2513 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2515 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2517 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2519 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2520 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2523 DE_FATAL("Invalid contents");
2527 vk.cmdEndRenderPass(commandBuffer);
2531 void pushReadImagesToBuffers (const DeviceInterface& vk,
2532 VkCommandBuffer commandBuffer,
2533 deUint32 queueIndex,
2535 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2536 const vector<Attachment>& attachmentInfo,
2537 const vector<bool>& isLazy,
2539 const UVec2& targetSize)
2542 vector<VkImageMemoryBarrier> imageBarriers;
2544 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2546 if (isLazy[attachmentNdx])
2549 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2550 const VkImageMemoryBarrier barrier =
2552 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2555 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2556 getAllMemoryReadFlags(), // dstAccessMask
2558 oldLayout, // oldLayout
2559 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2561 queueIndex, // srcQueueFamilyIndex
2562 queueIndex, // destQueueFamilyIndex
2564 attachmentResources[attachmentNdx]->getImage(), // image
2565 { // subresourceRange
2566 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2569 0, // baseArraySlice
2574 imageBarriers.push_back(barrier);
2577 if (!imageBarriers.empty())
2578 vk.cmdPipelineBarrier(commandBuffer,
2579 getAllPipelineStageFlags(),
2580 getAllPipelineStageFlags(),
2581 (VkDependencyFlags)0,
2582 0, (const VkMemoryBarrier*)DE_NULL,
2583 0, (const VkBufferMemoryBarrier*)DE_NULL,
2584 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2587 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2589 if (isLazy[attachmentNdx])
2592 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2593 const VkBufferImageCopy rect =
2596 0, // bufferRowLength
2597 0, // bufferImageHeight
2598 { // imageSubresource
2599 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2604 { 0, 0, 0 }, // imageOffset
2605 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2608 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2610 if (tcu::TextureFormat::DS == order)
2612 const VkBufferImageCopy stencilRect =
2615 0, // bufferRowLength
2616 0, // bufferImageHeight
2617 { // imageSubresource
2618 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2623 { 0, 0, 0 }, // imageOffset
2624 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2627 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2632 vector<VkBufferMemoryBarrier> bufferBarriers;
2634 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2636 if (isLazy[attachmentNdx])
2639 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2640 const VkBufferMemoryBarrier bufferBarrier =
2642 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2645 getAllMemoryWriteFlags(),
2646 getAllMemoryReadFlags(),
2651 attachmentResources[attachmentNdx]->getBuffer(),
2653 attachmentResources[attachmentNdx]->getBufferSize()
2656 bufferBarriers.push_back(bufferBarrier);
2658 if (tcu::TextureFormat::DS == order)
2660 const VkBufferMemoryBarrier secondaryBufferBarrier =
2662 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2665 getAllMemoryWriteFlags(),
2666 getAllMemoryReadFlags(),
2671 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2673 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2676 bufferBarriers.push_back(secondaryBufferBarrier);
2680 if (!bufferBarriers.empty())
2681 vk.cmdPipelineBarrier(commandBuffer,
2682 getAllPipelineStageFlags(),
2683 getAllPipelineStageFlags(),
2684 (VkDependencyFlags)0,
2685 0, (const VkMemoryBarrier*)DE_NULL,
2686 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2687 0, (const VkImageMemoryBarrier*)DE_NULL);
2694 PixelValue (const Maybe<bool>& x = nothing<bool>(),
2695 const Maybe<bool>& y = nothing<bool>(),
2696 const Maybe<bool>& z = nothing<bool>(),
2697 const Maybe<bool>& w = nothing<bool>());
2699 void setUndefined (size_t ndx);
2700 void setValue (size_t ndx, bool value);
2701 Maybe<bool> getValue (size_t ndx) const;
2707 PixelValue::PixelValue (const Maybe<bool>& x,
2708 const Maybe<bool>& y,
2709 const Maybe<bool>& z,
2710 const Maybe<bool>& w)
2713 const Maybe<bool> values[] =
2718 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
2721 setValue(ndx, *values[ndx]);
2726 DE_ASSERT(m_status <= 0xFFu);
2729 void PixelValue::setUndefined (size_t ndx)
2732 DE_ASSERT(m_status <= 0xFFu);
2734 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
2735 DE_ASSERT(m_status <= 0xFFu);
2738 void PixelValue::setValue (size_t ndx, bool value)
2741 DE_ASSERT(m_status <= 0xFFu);
2743 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
2746 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
2748 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
2750 DE_ASSERT(m_status <= 0xFFu);
2753 Maybe<bool> PixelValue::getValue (size_t ndx) const
2756 DE_ASSERT(m_status <= 0xFFu);
2758 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
2760 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
2763 return nothing<bool>();
2766 void clearReferenceValues (vector<PixelValue>& values,
2767 const UVec2& targetSize,
2768 const UVec2& offset,
2771 const PixelValue& value)
2773 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2774 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
2775 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
2777 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2778 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2780 for (int compNdx = 0; compNdx < 4; compNdx++)
2784 if (value.getValue(compNdx))
2785 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
2787 values[x + y * targetSize.x()].setUndefined(compNdx);
2793 void markUndefined (vector<PixelValue>& values,
2795 const UVec2& targetSize,
2796 const UVec2& offset,
2799 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2801 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2802 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2804 for (int compNdx = 0; compNdx < 4; compNdx++)
2807 values[x + y * targetSize.x()].setUndefined(compNdx);
2812 PixelValue clearValueToPixelValue (const VkClearValue& value,
2813 const tcu::TextureFormat& format)
2815 const bool isDepthAttachment = hasDepthComponent(format.order);
2816 const bool isStencilAttachment = hasStencilComponent(format.order);
2817 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
2818 PixelValue pixelValue;
2820 if (isDepthOrStencilAttachment)
2822 if (isDepthAttachment)
2824 if (value.depthStencil.depth == 1.0f)
2825 pixelValue.setValue(0, true);
2826 else if (value.depthStencil.depth == 0.0f)
2827 pixelValue.setValue(0, false);
2829 DE_FATAL("Unknown depth value");
2832 if (isStencilAttachment)
2834 if (value.depthStencil.stencil == 0xFFu)
2835 pixelValue.setValue(1, true);
2836 else if (value.depthStencil.stencil == 0x0u)
2837 pixelValue.setValue(1, false);
2839 DE_FATAL("Unknown stencil value");
2844 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2845 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2847 switch (channelClass)
2849 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2850 for (int i = 0; i < 4; i++)
2854 if (value.color.int32[i] == 1)
2855 pixelValue.setValue(i, true);
2856 else if (value.color.int32[i] == 0)
2857 pixelValue.setValue(i, false);
2859 DE_FATAL("Unknown clear color value");
2864 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2865 for (int i = 0; i < 4; i++)
2869 if (value.color.uint32[i] == 1u)
2870 pixelValue.setValue(i, true);
2871 else if (value.color.uint32[i] == 0u)
2872 pixelValue.setValue(i, false);
2874 DE_FATAL("Unknown clear color value");
2879 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2880 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2881 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2882 for (int i = 0; i < 4; i++)
2886 if (value.color.float32[i] == 1.0f)
2887 pixelValue.setValue(i, true);
2888 else if (value.color.float32[i] == 0.0f)
2889 pixelValue.setValue(i, false);
2891 DE_FATAL("Unknown clear color value");
2897 DE_FATAL("Unknown channel class");
2904 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
2905 const RenderPass& renderPassInfo,
2906 const UVec2& targetSize,
2907 const vector<Maybe<VkClearValue> >& imageClearValues,
2908 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2909 const vector<SubpassRenderInfo>& subpassRenderInfo,
2910 const UVec2& renderPos,
2911 const UVec2& renderSize)
2913 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2914 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2916 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2918 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2920 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2921 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2922 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
2924 reference.resize(targetSize.x() * targetSize.y());
2926 if (imageClearValues[attachmentNdx])
2927 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
2930 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2932 const Subpass& subpass = subpasses[subpassNdx];
2933 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2934 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2936 // Apply load op if attachment was used for the first time
2937 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2939 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2941 if (!attachmentUsed[attachmentIndex])
2943 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2944 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2945 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2947 DE_ASSERT(!tcu::hasDepthComponent(format.order));
2948 DE_ASSERT(!tcu::hasStencilComponent(format.order));
2950 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2951 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2952 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2953 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
2955 attachmentUsed[attachmentIndex] = true;
2959 // Apply load op to depth/stencil attachment if it was used for the first time
2960 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2962 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2964 // Apply load op if attachment was used for the first time
2965 if (!attachmentUsed[attachmentIndex])
2967 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2968 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2969 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2971 if (tcu::hasDepthComponent(format.order))
2973 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2974 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2975 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2976 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
2979 if (tcu::hasStencilComponent(format.order))
2981 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2982 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2983 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2984 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
2987 attachmentUsed[attachmentIndex] = true;
2991 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2993 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2994 const UVec2 offset = colorClear.getOffset();
2995 const UVec2 size = colorClear.getSize();
2996 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
2997 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2998 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2999 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3002 value.color = colorClear.getColor();
3004 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
3007 if (renderInfo.getDepthStencilClear())
3009 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
3010 const UVec2 offset = dsClear.getOffset();
3011 const UVec2 size = dsClear.getSize();
3012 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3013 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3014 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3015 const bool hasStencil = tcu::hasStencilComponent(format.order);
3016 const bool hasDepth = tcu::hasDepthComponent(format.order);
3017 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3020 value.depthStencil.depth = dsClear.getDepth();
3021 value.depthStencil.stencil = dsClear.getStencil();
3023 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
3026 if (renderInfo.getRenderQuad())
3028 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3029 const Vec2 posA = renderQuad.getCornerA();
3030 const Vec2 posB = renderQuad.getCornerB();
3031 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3032 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3033 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3034 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3035 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3036 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3038 DE_ASSERT(posAI.x() < posBI.x());
3039 DE_ASSERT(posAI.y() < posBI.y());
3041 if (subpass.getInputAttachments().empty())
3043 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3045 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3046 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3047 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3048 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3049 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3051 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3052 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3054 for (int compNdx = 0; compNdx < 4; compNdx++)
3056 const size_t index = subpassNdx + attachmentIndex + compNdx;
3057 const BoolOp op = boolOpFromIndex(index);
3058 const bool boolX = x % 2 == (int)(index % 2);
3059 const bool boolY = y % 2 == (int)((index / 2) % 2);
3061 if (channelMask[compNdx])
3062 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3067 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3069 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3070 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3071 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3072 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3074 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3075 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3077 if (tcu::hasDepthComponent(format.order))
3079 const size_t index = subpassNdx + 1;
3080 const BoolOp op = boolOpFromIndex(index);
3081 const bool boolX = x % 2 == (int)(index % 2);
3082 const bool boolY = y % 2 == (int)((index / 2) % 2);
3084 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3087 if (tcu::hasStencilComponent(format.order))
3089 const size_t index = subpassNdx;
3090 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3097 size_t outputComponentCount = 0;
3098 vector<Maybe<bool> > inputs;
3100 DE_ASSERT(posAI.x() < posBI.x());
3101 DE_ASSERT(posAI.y() < posBI.y());
3103 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3105 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3106 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3107 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3108 const int componentCount = tcu::getNumUsedChannels(format.order);
3110 outputComponentCount += (size_t)componentCount;
3113 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3114 outputComponentCount++;
3116 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3117 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3119 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3121 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3122 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3123 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3124 const int componentCount = tcu::getNumUsedChannels(format.order);
3126 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3127 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3130 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3131 ? ((inputs.size() / outputComponentCount)
3132 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3135 size_t outputValueNdx = 0;
3137 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3139 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3140 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3141 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3142 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3143 const int componentCount = tcu::getNumUsedChannels(format.order);
3145 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3147 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3148 const BoolOp op = boolOpFromIndex(index);
3149 const bool boolX = x % 2 == (int)(index % 2);
3150 const bool boolY = y % 2 == (int)((index / 2) % 2);
3151 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3153 for (size_t i = 0; i < inputsPerOutput; i++)
3157 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3158 output = tcu::nothing<bool>();
3160 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3164 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3166 reference[x + y * targetSize.x()].setUndefined(compNdx);
3169 outputValueNdx += componentCount;
3172 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3174 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3175 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3176 const size_t index = subpassNdx + attachmentIndex;
3177 const BoolOp op = boolOpFromIndex(index);
3178 const bool boolX = x % 2 == (int)(index % 2);
3179 const bool boolY = y % 2 == (int)((index / 2) % 2);
3180 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3182 for (size_t i = 0; i < inputsPerOutput; i++)
3186 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3187 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3189 output = tcu::nothing<bool>();
3193 reference[x + y * targetSize.x()].setValue(0, *output);
3195 reference[x + y * targetSize.x()].setUndefined(0);
3201 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3203 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3204 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3205 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3206 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3208 if (tcu::hasStencilComponent(format.order))
3210 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3211 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3213 const size_t index = subpassNdx;
3214 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3222 // Mark all attachments that were used but not stored as undefined
3223 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3225 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3226 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3227 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3228 const bool isStencilAttachment = hasStencilComponent(format.order);
3229 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3231 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3233 if (isDepthOrStencilAttachment)
3234 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3236 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3239 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3240 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3244 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3245 const vector<vector<PixelValue> >& referenceValues,
3246 const UVec2& targetSize,
3247 const RenderPass& renderPassInfo)
3249 referenceImages.resize(referenceValues.size());
3251 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3253 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3254 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3255 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3256 const bool hasDepth = tcu::hasDepthComponent(format.order);
3257 const bool hasStencil = tcu::hasStencilComponent(format.order);
3258 const bool hasDepthOrStencil = hasDepth || hasStencil;
3259 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3261 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3263 if (hasDepthOrStencil)
3267 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3269 for (deUint32 y = 0; y < targetSize.y(); y++)
3270 for (deUint32 x = 0; x < targetSize.x(); x++)
3272 if (reference[x + y * targetSize.x()].getValue(0))
3274 if (*reference[x + y * targetSize.x()].getValue(0))
3275 depthAccess.setPixDepth(1.0f, x, y);
3277 depthAccess.setPixDepth(0.0f, x, y);
3279 else // Fill with 3x3 grid
3280 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3286 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3288 for (deUint32 y = 0; y < targetSize.y(); y++)
3289 for (deUint32 x = 0; x < targetSize.x(); x++)
3291 if (reference[x + y * targetSize.x()].getValue(1))
3293 if (*reference[x + y * targetSize.x()].getValue(1))
3294 stencilAccess.setPixStencil(0xFFu, x, y);
3296 stencilAccess.setPixStencil(0x0u, x, y);
3298 else // Fill with 3x3 grid
3299 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3305 for (deUint32 y = 0; y < targetSize.y(); y++)
3306 for (deUint32 x = 0; x < targetSize.x(); x++)
3310 for (int compNdx = 0; compNdx < 4; compNdx++)
3312 if (reference[x + y * targetSize.x()].getValue(compNdx))
3314 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3315 color[compNdx] = 1.0f;
3317 color[compNdx] = 0.0f;
3319 else // Fill with 3x3 grid
3320 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3323 referenceImage.getAccess().setPixel(color, x, y);
3329 bool verifyColorAttachment (const vector<PixelValue>& reference,
3330 const ConstPixelBufferAccess& result,
3331 const PixelBufferAccess& errorImage)
3333 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3334 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3337 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3338 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3339 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3341 for (int y = 0; y < result.getHeight(); y++)
3342 for (int x = 0; x < result.getWidth(); x++)
3344 const Vec4 resultColor = result.getPixel(x, y);
3345 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3346 bool pixelOk = true;
3348 for (int compNdx = 0; compNdx < 4; compNdx++)
3350 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
3354 const bool value = *maybeValue;
3356 if ((value && (resultColor[compNdx] != 1.0f))
3357 || (!value && resultColor[compNdx] != 0.0f))
3364 errorImage.setPixel(red, x, y);
3368 errorImage.setPixel(green, x, y);
3374 bool verifyDepthAttachment (const vector<PixelValue>& reference,
3375 const ConstPixelBufferAccess& result,
3376 const PixelBufferAccess& errorImage)
3378 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3379 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3382 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3383 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3384 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3386 for (int y = 0; y < result.getHeight(); y++)
3387 for (int x = 0; x < result.getWidth(); x++)
3389 bool pixelOk = true;
3391 const float resultDepth = result.getPixDepth(x, y);
3392 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3393 const Maybe<bool> maybeValue = referenceValue.getValue(0);
3397 const bool value = *maybeValue;
3399 if ((value && (resultDepth != 1.0f))
3400 || (!value && resultDepth != 0.0f))
3406 errorImage.setPixel(red, x, y);
3410 errorImage.setPixel(green, x, y);
3416 bool verifyStencilAttachment (const vector<PixelValue>& reference,
3417 const ConstPixelBufferAccess& result,
3418 const PixelBufferAccess& errorImage)
3420 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3421 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3424 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3425 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3426 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3428 for (int y = 0; y < result.getHeight(); y++)
3429 for (int x = 0; x < result.getWidth(); x++)
3431 bool pixelOk = true;
3433 const deUint32 resultStencil = result.getPixStencil(x, y);
3434 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3435 const Maybe<bool> maybeValue = referenceValue.getValue(1);
3439 const bool value = *maybeValue;
3441 if ((value && (resultStencil != 0xFFu))
3442 || (!value && resultStencil != 0x0u))
3448 errorImage.setPixel(red, x, y);
3452 errorImage.setPixel(green, x, y);
3458 bool logAndVerifyImages (TestLog& log,
3459 const DeviceInterface& vk,
3461 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3462 const vector<bool>& attachmentIsLazy,
3463 const RenderPass& renderPassInfo,
3464 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3465 const vector<Maybe<VkClearValue> >& imageClearValues,
3466 const vector<SubpassRenderInfo>& subpassRenderInfo,
3467 const UVec2& targetSize,
3468 const TestConfig& config)
3470 vector<vector<PixelValue> > referenceValues;
3471 vector<tcu::TextureLevel> referenceAttachments;
3474 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
3476 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3477 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);
3479 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3481 if (!attachmentIsLazy[attachmentNdx])
3483 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3484 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3486 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3488 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3489 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3490 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3492 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3493 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3494 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3496 const VkMappedMemoryRange ranges[] =
3499 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3501 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3502 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3503 depthBufferSize // size;
3506 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3508 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3509 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3510 stencilBufferSize // size;
3513 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3516 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3517 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3518 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3519 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3521 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3522 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3524 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3526 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3527 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
3529 log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
3533 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3534 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
3536 log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
3543 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3544 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3546 const VkMappedMemoryRange range =
3548 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3550 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3551 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3554 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3556 if (tcu::hasDepthComponent(format.order))
3558 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3559 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3561 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3562 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3564 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3565 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3567 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3571 else if (tcu::hasStencilComponent(format.order))
3573 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3574 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3576 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3577 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3579 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3580 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3582 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3588 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3589 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3591 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3592 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3594 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3595 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3597 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3608 std::string getInputAttachmentType (VkFormat vkFormat)
3610 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3611 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3613 switch (channelClass)
3615 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3616 return "isubpassInput";
3618 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3619 return "usubpassInput";
3621 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3622 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3623 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3624 return "subpassInput";
3627 DE_FATAL("Unknown channel class");
3632 std::string getAttachmentType (VkFormat vkFormat)
3634 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3635 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3637 switch (channelClass)
3639 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3642 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3645 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3646 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3647 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3651 DE_FATAL("Unknown channel class");
3656 void createTestShaders (SourceCollections& dst, TestConfig config)
3658 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3660 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3662 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3664 const Subpass& subpass = subpasses[subpassNdx];
3665 deUint32 inputAttachmentBinding = 0;
3666 std::ostringstream vertexShader;
3667 std::ostringstream fragmentShader;
3669 vertexShader << "#version 310 es\n"
3670 << "layout(location = 0) in highp vec2 a_position;\n"
3671 << "void main (void) {\n"
3672 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
3675 fragmentShader << "#version 310 es\n"
3676 << "precision highp float;\n";
3678 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3680 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3681 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3682 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3683 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3684 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3686 if (isDepthFormat || isStencilFormat)
3690 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
3691 inputAttachmentBinding++;
3694 if (isStencilFormat)
3696 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
3697 inputAttachmentBinding++;
3702 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
3704 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
3705 inputAttachmentBinding++;
3709 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3711 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3712 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3715 fragmentShader << "void main (void) {\n";
3717 if (subpass.getInputAttachments().empty())
3719 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3721 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3722 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3724 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";
3726 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3728 const size_t index = subpassNdx + attachmentIndex + compNdx;
3729 const BoolOp op = boolOpFromIndex(index);
3732 fragmentShader << ",\n\t\t";
3734 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
3735 << ") " << boolOpToString(op) << " ("
3736 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3737 << ") ? 1.0 : 0.0)";
3740 fragmentShader << "));\n";
3743 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3745 const size_t index = subpassNdx + 1;
3746 const BoolOp op = boolOpFromIndex(index);
3748 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
3749 << ") " << boolOpToString(op) << " ("
3750 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3751 << ") ? 1.0 : 0.0);\n";
3756 size_t inputComponentCount = 0;
3757 size_t outputComponentCount = 0;
3759 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3761 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3762 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3763 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3764 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3766 inputComponentCount += componentCount;
3769 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3771 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3772 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3773 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3774 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3776 outputComponentCount += componentCount;
3779 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3780 outputComponentCount++;
3782 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
3783 ? ((inputComponentCount / outputComponentCount)
3784 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
3787 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"
3788 "\tbool outputs[" << outputComponentCount << "];\n";
3790 size_t inputValueNdx = 0;
3792 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3794 const char* const components[] =
3798 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3799 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3800 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3801 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3802 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3803 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3805 if (isDepthFormat || isStencilFormat)
3809 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
3813 if (isStencilFormat)
3815 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
3821 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3823 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
3829 size_t outputValueNdx = 0;
3831 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3833 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3834 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3835 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3836 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3837 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3839 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3841 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3842 const BoolOp op = boolOpFromIndex(index);
3844 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
3845 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3846 << ") " << boolOpToString(op) << " ("
3847 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3850 for (size_t i = 0; i < inputsPerOutput; i++)
3851 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
3854 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
3856 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3859 fragmentShader << ", ";
3861 if (compNdx < componentCount)
3862 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
3864 fragmentShader << "0";
3867 outputValueNdx += componentCount;
3869 fragmentShader << ");\n";
3872 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3874 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3875 const size_t index = subpassNdx + attachmentIndex;
3876 const BoolOp op = boolOpFromIndex(index);
3878 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
3879 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3880 << ") " << boolOpToString(op) << " ("
3881 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3884 for (size_t i = 0; i < inputsPerOutput; i++)
3885 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
3887 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
3891 fragmentShader << "}\n";
3893 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3894 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3899 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3901 bool lastAttachmentWasLazy = false;
3903 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3905 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3906 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3907 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3908 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3910 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3912 attachmentIsLazy.push_back(true);
3914 lastAttachmentWasLazy = true;
3916 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3918 attachmentIsLazy.push_back(false);
3919 lastAttachmentWasLazy = false;
3922 DE_FATAL("Unknown imageMemory");
3925 attachmentIsLazy.push_back(false);
3929 enum AttachmentRefType
3931 ATTACHMENTREFTYPE_COLOR,
3932 ATTACHMENTREFTYPE_DEPTH_STENCIL,
3933 ATTACHMENTREFTYPE_INPUT,
3934 ATTACHMENTREFTYPE_RESOLVE,
3937 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
3941 case VK_IMAGE_LAYOUT_GENERAL:
3942 case VK_IMAGE_LAYOUT_PREINITIALIZED:
3945 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3946 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3948 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3949 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3950 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3952 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3953 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3955 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3956 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3958 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3959 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3962 DE_FATAL("Unexpected image layout");
3967 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
3969 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
3971 const deUint32 attachment = references[referenceNdx].getAttachment();
3973 if (attachment != VK_ATTACHMENT_UNUSED)
3975 VkImageUsageFlags usage;
3979 case ATTACHMENTREFTYPE_COLOR:
3980 case ATTACHMENTREFTYPE_RESOLVE:
3981 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3984 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
3985 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3988 case ATTACHMENTREFTYPE_INPUT:
3989 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3993 DE_FATAL("Unexpected attachment reference type");
3998 attachmentImageUsage[attachment] |= usage;
4003 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4005 if (!references.empty())
4007 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4011 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4013 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4015 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4017 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4019 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4020 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4021 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4022 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4025 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4027 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4028 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4029 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
4031 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4032 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4034 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4035 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4037 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4038 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4040 if (!attachmentIsLazy[attachmentNdx])
4042 if (clearValues[attachmentNdx])
4043 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4045 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4049 const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
4051 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4052 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4057 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4059 bool lastSubpassWasSecondary = false;
4061 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4063 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4065 subpassIsSecondary.push_back(true);
4066 lastSubpassWasSecondary = true;
4068 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4070 subpassIsSecondary.push_back(false);
4071 lastSubpassWasSecondary = false;
4074 DE_FATAL("Unknown commandBuffer");
4078 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
4080 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4082 if (!isLazy[attachmentNdx])
4083 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4085 clearValues.push_back(nothing<VkClearValue>());
4089 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
4091 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4093 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4094 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4096 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4099 clearValues.push_back(nothing<VkClearValue>());
4103 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
4105 clearValues.resize(renderPass.getSubpasses().size());
4107 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4109 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
4110 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4112 clearValues[subpassNdx].resize(colorAttachments.size());
4114 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4116 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4117 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4119 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
4124 void logSubpassRenderInfo (TestLog& log,
4125 const SubpassRenderInfo& info)
4127 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4129 if (info.isSecondary())
4130 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4132 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4134 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4136 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4138 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4139 << ". Offset: " << colorClear.getOffset()
4140 << ", Size: " << colorClear.getSize()
4141 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
4144 if (info.getDepthStencilClear())
4146 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4148 log << TestLog::Message << "Clearing depth stencil attachment"
4149 << ". Offset: " << depthStencilClear.getOffset()
4150 << ", Size: " << depthStencilClear.getSize()
4151 << ", Depth: " << depthStencilClear.getDepth()
4152 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4155 if (info.getRenderQuad())
4157 const RenderQuad& renderQuad = *info.getRenderQuad();
4159 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4163 void logTestCaseInfo (TestLog& log,
4164 const TestConfig& config,
4165 const vector<bool>& attachmentIsLazy,
4166 const vector<Maybe<VkClearValue> >& imageClearValues,
4167 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4168 const vector<SubpassRenderInfo>& subpassRenderInfo)
4170 const RenderPass& renderPass = config.renderPass;
4172 logRenderPassInfo(log, renderPass);
4174 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4175 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4176 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4178 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4179 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4181 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4183 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4185 if (attachmentIsLazy[attachmentNdx])
4186 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4188 if (imageClearValues[attachmentNdx])
4189 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
4191 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4192 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
4195 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4197 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4199 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
4203 float roundToViewport (float x, deUint32 offset, deUint32 size)
4205 const float origin = (float)(offset) + ((float(size) / 2.0f));
4206 const float p = (float)(size) / 2.0f;
4207 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4209 return (((float)xi) - origin) / p;
4212 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4214 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4215 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4216 bool lastSubpassWasSecondary = false;
4218 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4220 const Subpass& subpass = subpasses[subpassNdx];
4221 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
4222 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
4223 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
4224 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
4225 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
4227 vector<ColorClear> colorClears;
4228 Maybe<DepthStencilClear> depthStencilClear;
4229 Maybe<RenderQuad> renderQuad;
4231 lastSubpassWasSecondary = subpassIsSecondary;
4233 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
4235 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4237 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4239 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4240 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4241 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4242 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
4243 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
4244 const VkClearColorValue color = randomColorClearValue(attachment, rng);
4246 colorClears.push_back(ColorClear(offset, size, color));
4249 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4251 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
4252 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4253 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
4254 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
4255 const VkClearValue value = randomClearValue(attachment, rng);
4257 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
4261 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4263 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
4264 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
4266 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
4267 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
4269 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
4270 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
4272 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
4275 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
4279 void checkTextureFormatSupport (TestLog& log,
4280 const InstanceInterface& vk,
4281 VkPhysicalDevice device,
4282 const vector<Attachment>& attachments)
4284 bool supported = true;
4286 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4288 const Attachment& attachment = attachments[attachmentNdx];
4289 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4290 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
4291 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
4292 VkFormatProperties properties;
4294 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
4296 if ((properties.optimalTilingFeatures & flags) != flags)
4299 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
4304 TCU_THROW(NotSupportedError, "Format not supported");
4307 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
4309 const UVec2 targetSize = config.targetSize;
4310 const UVec2 renderPos = config.renderPos;
4311 const UVec2 renderSize = config.renderSize;
4312 const RenderPass& renderPassInfo = config.renderPass;
4314 TestLog& log = context.getTestContext().getLog();
4315 de::Random rng (config.seed);
4317 vector<bool> attachmentIsLazy;
4318 vector<VkImageUsageFlags> attachmentImageUsage;
4319 vector<Maybe<VkClearValue> > imageClearValues;
4320 vector<Maybe<VkClearValue> > renderPassClearValues;
4322 vector<bool> subpassIsSecondary;
4323 vector<SubpassRenderInfo> subpassRenderInfo;
4324 vector<vector<VkClearColorValue> > subpassColorClearValues;
4326 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
4328 const std::string extensionName("VK_KHR_dedicated_allocation");
4330 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
4331 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
4334 if (!renderPassInfo.getInputAspects().empty())
4336 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2")))
4337 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
4340 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
4341 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
4342 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
4343 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
4345 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
4346 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
4347 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
4349 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
4351 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
4354 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
4356 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
4358 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4360 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
4361 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
4366 const InstanceInterface& vki = context.getInstanceInterface();
4367 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
4368 const VkDevice device = context.getDevice();
4369 const DeviceInterface& vk = context.getDeviceInterface();
4370 const VkQueue queue = context.getUniversalQueue();
4371 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
4372 Allocator& allocator = context.getDefaultAllocator();
4374 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
4375 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
4376 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4377 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4378 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4380 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
4381 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
4382 vector<VkImage> attachmentImages;
4383 vector<VkImageView> attachmentViews;
4384 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
4386 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4388 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
4390 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
4391 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
4392 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
4394 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
4397 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4398 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
4399 endCommandBuffer(vk, *initializeImagesCommandBuffer);
4402 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
4404 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4405 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments(), config.allocationKind)));
4407 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4408 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
4409 endCommandBuffer(vk, *renderCommandBuffer);
4411 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4412 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
4413 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
4415 const VkCommandBuffer commandBuffers[] =
4417 *initializeImagesCommandBuffer,
4418 *renderCommandBuffer,
4419 *readImagesToBuffersCommandBuffer
4421 const Unique<VkFence> fence (createFence(vk, device, 0u));
4423 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
4424 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
4428 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
4429 return tcu::TestStatus::pass("Pass");
4431 return tcu::TestStatus::fail("Result verification failed");
4435 static const VkFormat s_coreColorFormats[] =
4437 VK_FORMAT_R5G6B5_UNORM_PACK16,
4442 VK_FORMAT_R8G8_UNORM,
4443 VK_FORMAT_R8G8_SNORM,
4444 VK_FORMAT_R8G8_UINT,
4445 VK_FORMAT_R8G8_SINT,
4446 VK_FORMAT_R8G8B8A8_UNORM,
4447 VK_FORMAT_R8G8B8A8_SNORM,
4448 VK_FORMAT_R8G8B8A8_UINT,
4449 VK_FORMAT_R8G8B8A8_SINT,
4450 VK_FORMAT_R8G8B8A8_SRGB,
4451 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4452 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4453 VK_FORMAT_A8B8G8R8_UINT_PACK32,
4454 VK_FORMAT_A8B8G8R8_SINT_PACK32,
4455 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4456 VK_FORMAT_B8G8R8A8_UNORM,
4457 VK_FORMAT_B8G8R8A8_SRGB,
4458 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4459 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4460 VK_FORMAT_A2B10G10R10_UINT_PACK32,
4461 VK_FORMAT_R16_UNORM,
4462 VK_FORMAT_R16_SNORM,
4465 VK_FORMAT_R16_SFLOAT,
4466 VK_FORMAT_R16G16_UNORM,
4467 VK_FORMAT_R16G16_SNORM,
4468 VK_FORMAT_R16G16_UINT,
4469 VK_FORMAT_R16G16_SINT,
4470 VK_FORMAT_R16G16_SFLOAT,
4471 VK_FORMAT_R16G16B16A16_UNORM,
4472 VK_FORMAT_R16G16B16A16_SNORM,
4473 VK_FORMAT_R16G16B16A16_UINT,
4474 VK_FORMAT_R16G16B16A16_SINT,
4475 VK_FORMAT_R16G16B16A16_SFLOAT,
4478 VK_FORMAT_R32_SFLOAT,
4479 VK_FORMAT_R32G32_UINT,
4480 VK_FORMAT_R32G32_SINT,
4481 VK_FORMAT_R32G32_SFLOAT,
4482 VK_FORMAT_R32G32B32A32_UINT,
4483 VK_FORMAT_R32G32B32A32_SINT,
4484 VK_FORMAT_R32G32B32A32_SFLOAT
4487 static const VkFormat s_coreDepthStencilFormats[] =
4489 VK_FORMAT_D16_UNORM,
4491 VK_FORMAT_X8_D24_UNORM_PACK32,
4492 VK_FORMAT_D32_SFLOAT,
4494 VK_FORMAT_D24_UNORM_S8_UINT,
4495 VK_FORMAT_D32_SFLOAT_S8_UINT
4498 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4500 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
4501 const VkAttachmentLoadOp loadOps[] =
4503 VK_ATTACHMENT_LOAD_OP_LOAD,
4504 VK_ATTACHMENT_LOAD_OP_CLEAR,
4505 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4508 const VkAttachmentStoreOp storeOps[] =
4510 VK_ATTACHMENT_STORE_OP_STORE,
4511 VK_ATTACHMENT_STORE_OP_DONT_CARE
4514 const VkImageLayout initialAndFinalColorLayouts[] =
4516 VK_IMAGE_LAYOUT_GENERAL,
4517 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4518 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4519 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4520 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4523 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4525 VK_IMAGE_LAYOUT_GENERAL,
4526 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4527 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4528 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4529 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4530 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4533 const VkImageLayout subpassLayouts[] =
4535 VK_IMAGE_LAYOUT_GENERAL,
4536 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4539 const VkImageLayout depthStencilLayouts[] =
4541 VK_IMAGE_LAYOUT_GENERAL,
4542 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4545 const TestConfig::RenderTypes renderCommands[] =
4547 TestConfig::RENDERTYPES_NONE,
4548 TestConfig::RENDERTYPES_CLEAR,
4549 TestConfig::RENDERTYPES_DRAW,
4550 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4553 const TestConfig::CommandBufferTypes commandBuffers[] =
4555 TestConfig::COMMANDBUFFERTYPES_INLINE,
4556 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4557 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4560 const TestConfig::ImageMemory imageMemories[] =
4562 TestConfig::IMAGEMEMORY_STRICT,
4563 TestConfig::IMAGEMEMORY_LAZY,
4564 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4567 const UVec2 targetSizes[] =
4573 const UVec2 renderPositions[] =
4579 const UVec2 renderSizes[] =
4585 tcu::TestContext& testCtx = group->getTestContext();
4586 de::Random rng (1433774382u);
4588 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4590 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4591 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4592 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4594 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4596 const bool useDepthStencil = rng.getBool();
4597 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4598 vector<Attachment> attachments;
4599 vector<AttachmentReference> colorAttachmentReferences;
4601 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4603 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4604 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4605 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4606 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4608 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4609 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4610 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4612 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4613 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4615 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4616 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4619 if (useDepthStencil)
4621 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4622 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4623 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4624 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4626 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4627 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4629 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4630 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4632 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
4633 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4637 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4638 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4639 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4640 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
4641 const vector<SubpassDependency> deps;
4643 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4644 const RenderPass renderPass (attachments, subpasses, deps);
4645 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4646 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4647 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4649 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind));
4653 group->addChild(attachmentCountGroup.release());
4657 template<typename T>
4658 T chooseRandom (de::Random& rng, const set<T>& values)
4660 size_t ndx = ((size_t)rng.getUint32()) % values.size();
4661 typename set<T>::const_iterator iter = values.begin();
4663 for (; ndx > 0; ndx--)
4669 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4671 const deUint32 attachmentCounts[] = { 4, 8 };
4672 const VkAttachmentLoadOp loadOps[] =
4674 VK_ATTACHMENT_LOAD_OP_LOAD,
4675 VK_ATTACHMENT_LOAD_OP_CLEAR,
4676 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4679 const VkAttachmentStoreOp storeOps[] =
4681 VK_ATTACHMENT_STORE_OP_STORE,
4682 VK_ATTACHMENT_STORE_OP_DONT_CARE
4685 const VkImageLayout initialAndFinalColorLayouts[] =
4687 VK_IMAGE_LAYOUT_GENERAL,
4688 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4689 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4690 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4691 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4694 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4696 VK_IMAGE_LAYOUT_GENERAL,
4697 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4698 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4699 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4700 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4701 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4704 const VkImageLayout subpassLayouts[] =
4706 VK_IMAGE_LAYOUT_GENERAL,
4707 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4712 // Each pass uses one more attachmen than previous one
4713 ALLOCATIONTYPE_GROW,
4714 // Each pass uses one less attachment than previous one
4715 ALLOCATIONTYPE_SHRINK,
4716 // Each pass drops one attachment and picks up new one
4717 ALLOCATIONTYPE_ROLL,
4718 // Start by growing and end by shrinking
4719 ALLOCATIONTYPE_GROW_SHRINK,
4720 // Each subpass has single input and single output attachment
4721 ALLOCATIONTYPE_IO_CHAIN,
4722 // Each subpass has multiple inputs and multiple outputs attachment
4723 ALLOCATIONTYPE_IO_GENERIC
4726 const AllocationType allocationTypes[] =
4728 ALLOCATIONTYPE_GROW,
4729 ALLOCATIONTYPE_SHRINK,
4730 ALLOCATIONTYPE_ROLL,
4731 ALLOCATIONTYPE_GROW_SHRINK,
4732 ALLOCATIONTYPE_IO_CHAIN,
4733 ALLOCATIONTYPE_IO_GENERIC
4736 const char* const allocationTypeStr[] =
4742 "input_output_chain",
4746 const TestConfig::RenderTypes renderCommands[] =
4748 TestConfig::RENDERTYPES_NONE,
4749 TestConfig::RENDERTYPES_CLEAR,
4750 TestConfig::RENDERTYPES_DRAW,
4751 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4754 const TestConfig::CommandBufferTypes commandBuffers[] =
4756 TestConfig::COMMANDBUFFERTYPES_INLINE,
4757 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4758 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4761 const TestConfig::ImageMemory imageMemories[] =
4763 TestConfig::IMAGEMEMORY_STRICT,
4764 TestConfig::IMAGEMEMORY_LAZY,
4765 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4768 const UVec2 targetSizes[] =
4774 const UVec2 renderPositions[] =
4780 const UVec2 renderSizes[] =
4786 tcu::TestContext& testCtx = group->getTestContext();
4787 de::Random rng (3700649827u);
4789 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4791 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4792 const size_t testCaseCount = 100;
4793 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4795 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4797 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
4799 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
4800 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
4801 vector<Attachment> attachments;
4803 set<deUint32> definedAttachments;
4805 vector<Subpass> subpasses;
4806 set<deUint32> colorAttachments;
4807 set<deUint32> depthStencilAttachments;
4809 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
4811 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
4812 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4813 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4814 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4816 const VkImageLayout initialLayout = isDepthStencilAttachment
4817 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4818 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4819 const VkImageLayout finalizeLayout = isDepthStencilAttachment
4820 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4821 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4823 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4824 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4826 if (isDepthStencilAttachment)
4828 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4830 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
4831 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4832 definedAttachments.insert(attachmentIndex);
4834 depthStencilAttachments.insert(attachmentIndex);
4836 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4840 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4842 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4843 definedAttachments.insert(attachmentIndex);
4845 colorAttachments.insert(attachmentIndex);
4847 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4850 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>());
4851 vector<SubpassDependency> deps;
4853 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
4855 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
4856 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
4857 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
4858 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
4859 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
4860 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
4861 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
4862 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
4863 ? just(chooseRandom(rng, depthStencilAttachments))
4864 : nothing<deUint32>());
4865 std::vector<deUint32> subpassPreserveAttachments;
4867 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
4868 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
4870 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4871 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
4873 if (depthStencilAttachment)
4874 definedAttachments.insert(*depthStencilAttachment);
4877 std::vector<AttachmentReference> inputAttachmentReferences;
4878 std::vector<AttachmentReference> colorAttachmentReferences;
4879 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
4881 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4883 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
4884 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4885 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4887 if (lastUseOfAttachment[colorAttachmentIndex])
4889 const bool byRegion = rng.getBool();
4891 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
4892 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4893 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4894 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4895 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4897 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4898 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4899 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4900 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4902 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4903 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
4905 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4908 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
4910 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
4913 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
4915 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
4916 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
4917 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4919 if(lastUseOfAttachment[inputAttachmentIndex])
4921 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
4923 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
4924 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4925 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4926 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4927 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4929 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4930 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4931 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4932 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4934 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4935 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4937 VK_DEPENDENCY_BY_REGION_BIT));
4941 const bool byRegion = rng.getBool();
4943 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
4944 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4945 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4946 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4947 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4949 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4950 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4951 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4952 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4954 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4955 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4957 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4960 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
4962 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
4966 if (depthStencilAttachment)
4968 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4969 if (lastUseOfAttachment[*depthStencilAttachment])
4971 if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
4973 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
4974 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4975 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4976 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4977 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4979 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4980 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4981 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4982 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4984 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4985 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4987 VK_DEPENDENCY_BY_REGION_BIT));
4991 const bool byRegion = rng.getBool();
4993 deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
4994 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4995 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4996 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4997 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4999 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5000 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5001 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5002 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5004 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5005 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5007 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5011 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
5012 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
5015 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5017 vector<deUint32> preserveAttachments;
5018 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
5020 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
5021 preserveAttachments.push_back(attachmentIndex);
5024 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5025 inputAttachmentReferences,
5026 colorAttachmentReferences,
5027 vector<AttachmentReference>(),
5028 depthStencilAttachmentReference,
5029 preserveAttachments));
5033 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5034 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5035 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5037 const string testCaseName = de::toString(testCaseNdx);
5038 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5039 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5040 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5042 const RenderPass renderPass (attachments, subpasses, deps);
5044 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
5049 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
5050 vector<Attachment> attachments;
5051 vector<Subpass> subpasses;
5053 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5055 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5056 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5057 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5058 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5060 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5061 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5063 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5064 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5066 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5069 if (allocationType == ALLOCATIONTYPE_GROW)
5071 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5073 vector<AttachmentReference> colorAttachmentReferences;
5075 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5077 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5079 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5082 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5083 vector<AttachmentReference>(),
5084 colorAttachmentReferences,
5085 vector<AttachmentReference>(),
5086 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5087 vector<deUint32>()));
5090 else if (allocationType == ALLOCATIONTYPE_SHRINK)
5092 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5094 vector<AttachmentReference> colorAttachmentReferences;
5096 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5098 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5100 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5103 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5104 vector<AttachmentReference>(),
5105 colorAttachmentReferences,
5106 vector<AttachmentReference>(),
5107 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5108 vector<deUint32>()));
5111 else if (allocationType == ALLOCATIONTYPE_ROLL)
5113 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
5115 vector<AttachmentReference> colorAttachmentReferences;
5117 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
5119 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5121 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
5124 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5125 vector<AttachmentReference>(),
5126 colorAttachmentReferences,
5127 vector<AttachmentReference>(),
5128 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5129 vector<deUint32>()));
5132 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
5134 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5136 vector<AttachmentReference> colorAttachmentReferences;
5138 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5140 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5142 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5145 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5146 vector<AttachmentReference>(),
5147 colorAttachmentReferences,
5148 vector<AttachmentReference>(),
5149 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5150 vector<deUint32>()));
5153 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5155 vector<AttachmentReference> colorAttachmentReferences;
5157 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5159 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5161 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5164 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5165 vector<AttachmentReference>(),
5166 colorAttachmentReferences,
5167 vector<AttachmentReference>(),
5168 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5169 vector<deUint32>()));
5172 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
5174 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5175 vector<AttachmentReference>(),
5176 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5177 vector<AttachmentReference>(),
5178 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5179 vector<deUint32>()));
5181 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
5183 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5184 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5185 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5186 vector<AttachmentReference>(),
5187 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5188 vector<deUint32>()));
5192 DE_FATAL("Unknown allocation type");
5195 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5196 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5197 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5199 const string testCaseName = de::toString(testCaseNdx);
5200 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5201 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5202 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5204 vector<SubpassDependency> deps;
5206 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
5208 const bool byRegion = rng.getBool();
5209 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
5210 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5211 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5212 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5213 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5215 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5216 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5217 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5218 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5220 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5221 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5223 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5226 const RenderPass renderPass (attachments, subpasses, deps);
5228 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
5232 group->addChild(allocationTypeGroup.release());
5236 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5238 const UVec2 targetSize (64, 64);
5239 const UVec2 renderPos (0, 0);
5240 const UVec2 renderSize (64, 64);
5244 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5245 VK_SAMPLE_COUNT_1_BIT,
5246 VK_ATTACHMENT_LOAD_OP_CLEAR,
5247 VK_ATTACHMENT_STORE_OP_STORE,
5248 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5249 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5250 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5251 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5252 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5254 vector<AttachmentReference>(),
5255 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5256 vector<AttachmentReference>(),
5257 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5258 vector<deUint32>())),
5259 vector<SubpassDependency>());
5261 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5266 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5267 VK_SAMPLE_COUNT_1_BIT,
5268 VK_ATTACHMENT_LOAD_OP_CLEAR,
5269 VK_ATTACHMENT_STORE_OP_STORE,
5270 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5271 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5272 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5273 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5274 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5276 vector<AttachmentReference>(),
5277 vector<AttachmentReference>(),
5278 vector<AttachmentReference>(),
5279 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5280 vector<deUint32>())),
5281 vector<SubpassDependency>());
5283 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5288 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
5289 VK_SAMPLE_COUNT_1_BIT,
5290 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5291 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5292 VK_ATTACHMENT_LOAD_OP_CLEAR,
5293 VK_ATTACHMENT_STORE_OP_STORE,
5294 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5295 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5296 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5298 vector<AttachmentReference>(),
5299 vector<AttachmentReference>(),
5300 vector<AttachmentReference>(),
5301 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5302 vector<deUint32>())),
5303 vector<SubpassDependency>());
5305 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5310 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5311 VK_SAMPLE_COUNT_1_BIT,
5312 VK_ATTACHMENT_LOAD_OP_CLEAR,
5313 VK_ATTACHMENT_STORE_OP_STORE,
5314 VK_ATTACHMENT_LOAD_OP_CLEAR,
5315 VK_ATTACHMENT_STORE_OP_STORE,
5316 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5317 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5318 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5320 vector<AttachmentReference>(),
5321 vector<AttachmentReference>(),
5322 vector<AttachmentReference>(),
5323 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5324 vector<deUint32>())),
5325 vector<SubpassDependency>());
5327 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5332 const Attachment attachments[] =
5334 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5335 VK_SAMPLE_COUNT_1_BIT,
5336 VK_ATTACHMENT_LOAD_OP_CLEAR,
5337 VK_ATTACHMENT_STORE_OP_STORE,
5338 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5339 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5340 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5341 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5342 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5343 VK_SAMPLE_COUNT_1_BIT,
5344 VK_ATTACHMENT_LOAD_OP_CLEAR,
5345 VK_ATTACHMENT_STORE_OP_STORE,
5346 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5347 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5348 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5349 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5352 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5353 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5355 vector<AttachmentReference>(),
5356 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5357 vector<AttachmentReference>(),
5358 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5359 vector<deUint32>())),
5360 vector<SubpassDependency>());
5362 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5367 const Attachment attachments[] =
5369 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5370 VK_SAMPLE_COUNT_1_BIT,
5371 VK_ATTACHMENT_LOAD_OP_CLEAR,
5372 VK_ATTACHMENT_STORE_OP_STORE,
5373 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5374 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5375 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5376 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5377 Attachment(VK_FORMAT_S8_UINT,
5378 VK_SAMPLE_COUNT_1_BIT,
5379 VK_ATTACHMENT_LOAD_OP_CLEAR,
5380 VK_ATTACHMENT_STORE_OP_STORE,
5381 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5382 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5383 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5384 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5387 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5388 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5390 vector<AttachmentReference>(),
5391 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5392 vector<AttachmentReference>(),
5393 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5394 vector<deUint32>())),
5395 vector<SubpassDependency>());
5398 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5401 // color_depth_stencil
5403 const Attachment attachments[] =
5405 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5406 VK_SAMPLE_COUNT_1_BIT,
5407 VK_ATTACHMENT_LOAD_OP_CLEAR,
5408 VK_ATTACHMENT_STORE_OP_STORE,
5409 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5410 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5411 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5412 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5413 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5414 VK_SAMPLE_COUNT_1_BIT,
5415 VK_ATTACHMENT_LOAD_OP_CLEAR,
5416 VK_ATTACHMENT_STORE_OP_STORE,
5417 VK_ATTACHMENT_LOAD_OP_CLEAR,
5418 VK_ATTACHMENT_STORE_OP_STORE,
5419 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5420 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5423 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5424 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5426 vector<AttachmentReference>(),
5427 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5428 vector<AttachmentReference>(),
5429 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5430 vector<deUint32>())),
5431 vector<SubpassDependency>());
5433 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5437 std::string formatToName (VkFormat format)
5439 const std::string formatStr = de::toString(format);
5440 const std::string prefix = "VK_FORMAT_";
5442 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
5444 return de::toLower(formatStr.substr(prefix.length()));
5447 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5449 tcu::TestContext& testCtx = group->getTestContext();
5451 const UVec2 targetSize (64, 64);
5452 const UVec2 renderPos (0, 0);
5453 const UVec2 renderSize (64, 64);
5457 const char* const str;
5458 const VkAttachmentStoreOp op;
5461 { "store", VK_ATTACHMENT_STORE_OP_STORE },
5462 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
5467 const char* const str;
5468 const VkAttachmentLoadOp op;
5471 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
5472 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
5473 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
5478 const char* const str;
5479 const TestConfig::RenderTypes types;
5482 { "clear", TestConfig::RENDERTYPES_CLEAR },
5483 { "draw", TestConfig::RENDERTYPES_DRAW },
5484 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
5488 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
5490 const VkFormat format = s_coreColorFormats[formatNdx];
5491 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
5493 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5495 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5496 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5498 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5500 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
5501 VK_SAMPLE_COUNT_1_BIT,
5503 VK_ATTACHMENT_STORE_OP_STORE,
5504 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5505 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5506 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5507 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5508 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5510 vector<AttachmentReference>(),
5511 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5512 vector<AttachmentReference>(),
5513 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5514 vector<deUint32>())),
5515 vector<SubpassDependency>());
5517 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5520 formatGroup->addChild(loadOpGroup.release());
5524 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5526 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5528 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5529 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5531 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5533 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5534 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5536 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
5538 const bool useInputAspect = useInputAspectNdx != 0;
5540 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5543 vector<Attachment> attachments;
5544 vector<Subpass> subpasses;
5545 vector<SubpassDependency> deps;
5546 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5548 attachments.push_back(Attachment(format,
5549 VK_SAMPLE_COUNT_1_BIT,
5552 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5553 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5554 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5555 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5557 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5558 VK_SAMPLE_COUNT_1_BIT,
5559 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5560 VK_ATTACHMENT_STORE_OP_STORE,
5561 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5562 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5563 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5564 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5566 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5568 vector<AttachmentReference>(),
5569 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5570 vector<AttachmentReference>(),
5571 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5572 vector<deUint32>()));
5573 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5575 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5576 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5577 vector<AttachmentReference>(),
5578 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5579 vector<deUint32>()));
5581 deps.push_back(SubpassDependency(0, 1,
5583 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5584 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5586 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5587 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5588 vk::VK_DEPENDENCY_BY_REGION_BIT));
5592 const VkInputAttachmentAspectReferenceKHR inputAspect =
5596 VK_IMAGE_ASPECT_COLOR_BIT
5599 inputAspects.push_back(inputAspect);
5603 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5605 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5609 vector<Attachment> attachments;
5610 vector<Subpass> subpasses;
5611 vector<SubpassDependency> deps;
5612 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5614 attachments.push_back(Attachment(format,
5615 VK_SAMPLE_COUNT_1_BIT,
5618 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5619 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5620 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5621 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5623 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5625 vector<AttachmentReference>(),
5626 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5627 vector<AttachmentReference>(),
5628 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5629 vector<deUint32>()));
5630 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5632 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5633 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5634 vector<AttachmentReference>(),
5635 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5636 vector<deUint32>()));
5638 deps.push_back(SubpassDependency(0, 1,
5639 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5640 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5642 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5643 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5644 vk::VK_DEPENDENCY_BY_REGION_BIT));
5648 const VkInputAttachmentAspectReferenceKHR inputAspect =
5652 VK_IMAGE_ASPECT_COLOR_BIT
5655 inputAspects.push_back(inputAspect);
5659 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5661 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5667 loadOpGroup->addChild(storeOpGroup.release());
5670 inputGroup->addChild(loadOpGroup.release());
5673 formatGroup->addChild(inputGroup.release());
5676 group->addChild(formatGroup.release());
5679 // Depth stencil formats
5680 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
5682 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
5683 const tcu::TextureFormat format = mapVkFormat(vkFormat);
5684 const bool isStencilAttachment = hasStencilComponent(format.order);
5685 const bool isDepthAttachment = hasDepthComponent(format.order);
5686 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
5688 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5690 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5691 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5693 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5695 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5696 VK_SAMPLE_COUNT_1_BIT,
5697 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5698 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5699 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5700 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5701 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5702 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5703 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5705 vector<AttachmentReference>(),
5706 vector<AttachmentReference>(),
5707 vector<AttachmentReference>(),
5708 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5709 vector<deUint32>())),
5710 vector<SubpassDependency>());
5712 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5715 formatGroup->addChild(loadOpGroup.release());
5719 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5721 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5723 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5724 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5726 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5728 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5729 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5731 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
5733 const bool useInputAspect = useInputAspectNdx != 0;
5735 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5738 vector<Attachment> attachments;
5739 vector<Subpass> subpasses;
5740 vector<SubpassDependency> deps;
5741 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5743 attachments.push_back(Attachment(vkFormat,
5744 VK_SAMPLE_COUNT_1_BIT,
5747 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5748 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5749 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5750 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5752 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5753 VK_SAMPLE_COUNT_1_BIT,
5754 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5755 VK_ATTACHMENT_STORE_OP_STORE,
5756 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5757 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5758 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5759 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5761 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5763 vector<AttachmentReference>(),
5764 vector<AttachmentReference>(),
5765 vector<AttachmentReference>(),
5766 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5767 vector<deUint32>()));
5768 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5770 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5771 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5772 vector<AttachmentReference>(),
5773 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5774 vector<deUint32>()));
5776 deps.push_back(SubpassDependency(0, 1,
5777 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5778 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5780 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5781 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5784 deps.push_back(SubpassDependency(1, 1,
5785 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5786 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5788 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5789 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5790 vk::VK_DEPENDENCY_BY_REGION_BIT));
5794 const VkInputAttachmentAspectReferenceKHR inputAspect =
5798 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
5799 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
5802 inputAspects.push_back(inputAspect);
5806 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5808 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5812 vector<Attachment> attachments;
5813 vector<Subpass> subpasses;
5814 vector<SubpassDependency> deps;
5815 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5817 attachments.push_back(Attachment(vkFormat,
5818 VK_SAMPLE_COUNT_1_BIT,
5821 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5822 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5823 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5824 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5826 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5828 vector<AttachmentReference>(),
5829 vector<AttachmentReference>(),
5830 vector<AttachmentReference>(),
5831 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5832 vector<deUint32>()));
5833 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5835 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5836 vector<AttachmentReference>(),
5837 vector<AttachmentReference>(),
5838 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
5839 vector<deUint32>()));
5841 deps.push_back(SubpassDependency(0, 1,
5842 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5843 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5845 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5846 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5847 vk::VK_DEPENDENCY_BY_REGION_BIT));
5852 const VkInputAttachmentAspectReferenceKHR inputAspect =
5857 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
5858 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
5861 inputAspects.push_back(inputAspect);
5865 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5867 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5873 loadOpGroup->addChild(storeOpGroup.release());
5876 inputGroup->addChild(loadOpGroup.release());
5879 formatGroup->addChild(inputGroup.release());
5882 group->addChild(formatGroup.release());
5886 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5888 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind);
5889 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind);
5890 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind);
5891 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind);
5894 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx)
5896 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
5898 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED);
5900 return suballocationTestsGroup;
5903 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx)
5905 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
5907 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED);
5909 return dedicatedAllocationTestsGroup;
5914 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
5916 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
5917 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx);
5918 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx);
5920 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
5921 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx));
5923 renderpassTests->addChild(suballocationTestGroup.release());
5924 renderpassTests->addChild(dedicatedAllocationTestGroup.release());
5926 return renderpassTests.release();