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 : m_attachments (attachments)
669 , m_subpasses (subpasses)
670 , m_dependencies (dependencies)
674 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
675 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
676 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
679 const vector<Attachment> m_attachments;
680 const vector<Subpass> m_subpasses;
681 const vector<SubpassDependency> m_dependencies;
688 RENDERTYPES_NONE = 0,
689 RENDERTYPES_CLEAR = (1<<1),
690 RENDERTYPES_DRAW = (1<<2)
693 enum CommandBufferTypes
695 COMMANDBUFFERTYPES_INLINE = (1<<0),
696 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
701 IMAGEMEMORY_STRICT = (1<<0),
702 IMAGEMEMORY_LAZY = (1<<1)
705 TestConfig (const RenderPass& renderPass_,
706 RenderTypes renderTypes_,
707 CommandBufferTypes commandBufferTypes_,
708 ImageMemory imageMemory_,
709 const UVec2& targetSize_,
710 const UVec2& renderPos_,
711 const UVec2& renderSize_,
713 AllocationKind allocationKind_)
714 : renderPass (renderPass_)
715 , renderTypes (renderTypes_)
716 , commandBufferTypes (commandBufferTypes_)
717 , imageMemory (imageMemory_)
718 , targetSize (targetSize_)
719 , renderPos (renderPos_)
720 , renderSize (renderSize_)
722 , allocationKind (allocationKind_)
726 RenderPass renderPass;
727 RenderTypes renderTypes;
728 CommandBufferTypes commandBufferTypes;
729 ImageMemory imageMemory;
734 AllocationKind allocationKind;
737 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
739 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
742 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
744 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
747 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
749 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
752 void logRenderPassInfo (TestLog& log,
753 const RenderPass& renderPass)
755 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
758 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
759 const vector<Attachment>& attachments = renderPass.getAttachments();
761 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
763 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
764 const Attachment& attachment = attachments[attachmentNdx];
766 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
767 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
769 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
770 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
772 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
773 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
775 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
776 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
781 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
782 const vector<Subpass>& subpasses = renderPass.getSubpasses();
784 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
786 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
787 const Subpass& subpass = subpasses[subpassNdx];
789 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
790 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
791 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
792 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments();
794 if (!inputAttachments.empty())
796 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
798 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
800 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
801 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
803 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
804 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
808 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
810 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
811 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
813 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
814 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
817 if (!colorAttachments.empty())
819 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
821 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
823 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
824 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
826 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
827 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
831 if (!resolveAttachments.empty())
833 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
835 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
837 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
838 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
840 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
841 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
845 if (!preserveAttachments.empty())
847 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
849 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
851 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
852 const deUint32 preserveAttachment = preserveAttachments[preserveNdx];
854 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
861 if (!renderPass.getDependencies().empty())
863 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
865 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
867 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
868 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
870 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
871 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
873 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
874 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
876 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
877 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
878 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
883 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
885 const tcu::TextureFormat format = mapVkFormat(vkFormat);
886 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
887 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
889 std::ostringstream stream;
893 switch (channelClass)
895 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
896 for (int i = 0; i < 4; i++)
902 stream << value.int32[i];
908 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
909 for (int i = 0; i < 4; i++)
915 stream << value.uint32[i];
921 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
922 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
923 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
924 for (int i = 0; i < 4; i++)
930 stream << value.float32[i];
937 DE_FATAL("Unknown channel class");
945 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
947 const tcu::TextureFormat format = mapVkFormat(vkFormat);
949 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
951 std::ostringstream stream;
955 if (tcu::hasStencilComponent(format.order))
956 stream << "stencil: " << value.depthStencil.stencil;
958 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
961 if (tcu::hasDepthComponent(format.order))
962 stream << "depth: " << value.depthStencil.depth;
969 return clearColorToString(vkFormat, value.color);
972 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
974 const float clearNan = tcu::Float32::nan().asFloat();
975 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
976 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
977 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
978 VkClearColorValue clearColor;
980 switch (channelClass)
982 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
984 for (int ndx = 0; ndx < 4; ndx++)
986 if (!channelMask[ndx])
987 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
989 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
994 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
996 for (int ndx = 0; ndx < 4; ndx++)
998 if (!channelMask[ndx])
999 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
1001 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1006 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1007 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1008 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1010 for (int ndx = 0; ndx < 4; ndx++)
1012 if (!channelMask[ndx])
1013 clearColor.float32[ndx] = clearNan;
1015 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1021 DE_FATAL("Unknown channel class");
1027 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
1029 const VkAttachmentDescription attachmentDescription =
1033 attachment.getFormat(), // format
1034 attachment.getSamples(), // samples
1036 attachment.getLoadOp(), // loadOp
1037 attachment.getStoreOp(), // storeOp
1039 attachment.getStencilLoadOp(), // stencilLoadOp
1040 attachment.getStencilStoreOp(), // stencilStoreOp
1042 attachment.getInitialLayout(), // initialLayout
1043 attachment.getFinalLayout(), // finalLayout
1046 return attachmentDescription;
1049 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
1051 const VkAttachmentReference reference =
1053 referenceInfo.getAttachment(), // attachment;
1054 referenceInfo.getImageLayout() // layout;
1060 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
1061 vector<VkAttachmentReference>* attachmentReferenceLists,
1062 vector<deUint32>* preserveAttachmentReferences)
1064 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
1065 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
1066 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
1067 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
1069 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1070 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
1072 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1073 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
1075 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1076 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
1078 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
1080 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1081 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1083 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1086 const VkSubpassDescription subpassDescription =
1088 subpass.getFlags(), // flags;
1089 subpass.getPipelineBindPoint(), // pipelineBindPoint;
1091 (deUint32)inputAttachmentReferences.size(), // inputCount;
1092 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1094 (deUint32)colorAttachmentReferences.size(), // colorCount;
1095 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1096 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1098 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1099 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1100 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1103 return subpassDescription;
1107 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1109 const VkSubpassDependency dependency =
1111 dependencyInfo.getSrcPass(), // srcSubpass;
1112 dependencyInfo.getDstPass(), // destSubpass;
1114 dependencyInfo.getSrcStageMask(), // srcStageMask;
1115 dependencyInfo.getDstStageMask(), // destStageMask;
1117 dependencyInfo.getOutputMask(), // outputMask;
1118 dependencyInfo.getInputMask(), // inputMask;
1120 dependencyInfo.getFlags() // dependencyFlags;
1126 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1128 const RenderPass& renderPassInfo)
1130 const size_t perSubpassAttachmentReferenceLists = 4;
1131 vector<VkAttachmentDescription> attachments;
1132 vector<VkSubpassDescription> subpasses;
1133 vector<VkSubpassDependency> dependencies;
1134 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1135 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1137 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1138 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1140 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1141 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1143 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1144 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1147 const VkRenderPassCreateInfo createInfo =
1149 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1151 (VkRenderPassCreateFlags)0u,
1152 (deUint32)attachments.size(),
1153 (attachments.empty() ? DE_NULL : &attachments[0]),
1154 (deUint32)subpasses.size(),
1155 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1156 (deUint32)dependencies.size(),
1157 (dependencies.empty() ? DE_NULL : &dependencies[0])
1160 return createRenderPass(vk, device, &createInfo);
1164 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1166 VkRenderPass renderPass,
1168 const vector<VkImageView>& attachments)
1170 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1173 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1175 deUint32 queueIndex,
1178 VkSampleCountFlagBits samples,
1179 VkImageUsageFlags usageFlags,
1180 VkImageLayout layout)
1182 VkImageUsageFlags targetUsageFlags = 0;
1183 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1185 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1186 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1188 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1189 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1191 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1192 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1194 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1196 return createImage(vk, device,
1197 (VkImageCreateFlags)0,
1200 vk::makeExtent3D(size.x(), size.y(), 1u),
1204 VK_IMAGE_TILING_OPTIMAL,
1205 usageFlags | targetUsageFlags,
1206 VK_SHARING_MODE_EXCLUSIVE,
1212 de::MovePtr<Allocation> createImageMemory (const InstanceInterface& vki,
1213 const VkPhysicalDevice& vkd,
1214 const DeviceInterface& vk,
1216 Allocator& allocator,
1219 AllocationKind allocationKind)
1221 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1222 de::MovePtr<Allocation> allocation = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1224 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1229 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1233 VkImageAspectFlags aspect)
1235 const VkImageSubresourceRange range =
1244 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1247 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1249 const float clearNan = tcu::Float32::nan().asFloat();
1250 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1252 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1254 VkClearValue clearValue;
1256 clearValue.depthStencil.depth = clearNan;
1257 clearValue.depthStencil.stencil = 0xCDu;
1259 if (tcu::hasStencilComponent(format.order))
1260 clearValue.depthStencil.stencil = rng.getBool()
1264 if (tcu::hasDepthComponent(format.order))
1265 clearValue.depthStencil.depth = rng.getBool()
1273 VkClearValue clearValue;
1275 clearValue.color = randomColorClearValue(attachment, rng);
1281 class AttachmentResources
1284 AttachmentResources (const InstanceInterface& vki,
1285 const VkPhysicalDevice& physDevice,
1286 const DeviceInterface& vk,
1288 Allocator& allocator,
1289 deUint32 queueIndex,
1291 const Attachment& attachmentInfo,
1292 VkImageUsageFlags usageFlags,
1293 const AllocationKind allocationKind)
1294 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1295 , m_imageMemory (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
1296 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1298 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1299 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1300 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1302 if (isDepthFormat && isStencilFormat)
1304 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1305 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1307 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1310 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1312 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1314 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1316 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1317 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1319 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1320 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1322 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1323 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1325 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1327 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1328 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1330 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1334 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1336 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1337 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1339 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1344 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1346 return m_inputAttachmentViews;
1349 ~AttachmentResources (void)
1353 VkImageView getAttachmentView (void) const
1355 return *m_attachmentView;
1358 VkImage getImage (void) const
1363 VkBuffer getBuffer (void) const
1365 DE_ASSERT(*m_buffer != DE_NULL);
1369 VkDeviceSize getBufferSize (void) const
1371 DE_ASSERT(*m_buffer != DE_NULL);
1372 return m_bufferSize;
1375 const Allocation& getResultMemory (void) const
1377 DE_ASSERT(m_bufferMemory);
1378 return *m_bufferMemory;
1381 VkBuffer getSecondaryBuffer (void) const
1383 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1384 return *m_secondaryBuffer;
1387 VkDeviceSize getSecondaryBufferSize (void) const
1389 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1390 return m_secondaryBufferSize;
1393 const Allocation& getSecondaryResultMemory (void) const
1395 DE_ASSERT(m_secondaryBufferMemory);
1396 return *m_secondaryBufferMemory;
1400 const Unique<VkImage> m_image;
1401 const UniquePtr<Allocation> m_imageMemory;
1402 const Unique<VkImageView> m_attachmentView;
1404 Move<VkImageView> m_depthInputAttachmentView;
1405 Move<VkImageView> m_stencilInputAttachmentView;
1406 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1408 Move<VkBuffer> m_buffer;
1409 VkDeviceSize m_bufferSize;
1410 de::MovePtr<Allocation> m_bufferMemory;
1412 Move<VkBuffer> m_secondaryBuffer;
1413 VkDeviceSize m_secondaryBufferSize;
1414 de::MovePtr<Allocation> m_secondaryBufferMemory;
1417 void uploadBufferData (const DeviceInterface& vk,
1419 const Allocation& memory,
1423 const VkMappedMemoryRange range =
1425 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1427 memory.getMemory(), // mem;
1428 memory.getOffset(), // offset;
1429 (VkDeviceSize)size // size;
1431 void* const ptr = memory.getHostPtr();
1433 deMemcpy(ptr, data, size);
1434 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1437 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1439 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1443 case tcu::TextureFormat::D:
1444 case tcu::TextureFormat::DS:
1445 return VK_IMAGE_ASPECT_DEPTH_BIT;
1447 case tcu::TextureFormat::S:
1448 return VK_IMAGE_ASPECT_STENCIL_BIT;
1451 return VK_IMAGE_ASPECT_COLOR_BIT;
1458 RenderQuad (const Vec2& posA, const Vec2& posB)
1461 m_vertices[0] = posA;
1462 m_vertices[1] = Vec2(posA[0], posB[1]);
1463 m_vertices[2] = posB;
1465 m_vertices[3] = posB;
1466 m_vertices[4] = Vec2(posB[0], posA[1]);
1467 m_vertices[5] = posA;
1470 const Vec2& getCornerA (void) const
1472 return m_vertices[0];
1475 const Vec2& getCornerB (void) const
1477 return m_vertices[2];
1480 const void* getVertexPointer (void) const
1482 return &m_vertices[0];
1485 size_t getVertexDataSize (void) const
1487 return sizeof(Vec2) * m_vertices.size();
1491 vector<Vec2> m_vertices;
1497 ColorClear (const UVec2& offset,
1499 const VkClearColorValue& color)
1506 const UVec2& getOffset (void) const { return m_offset; }
1507 const UVec2& getSize (void) const { return m_size; }
1508 const VkClearColorValue& getColor (void) const { return m_color; }
1513 VkClearColorValue m_color;
1516 class DepthStencilClear
1519 DepthStencilClear (const UVec2& offset,
1526 , m_stencil (stencil)
1530 const UVec2& getOffset (void) const { return m_offset; }
1531 const UVec2& getSize (void) const { return m_size; }
1532 float getDepth (void) const { return m_depth; }
1533 deUint32 getStencil (void) const { return m_stencil; }
1536 const UVec2 m_offset;
1539 const float m_depth;
1540 const deUint32 m_stencil;
1543 class SubpassRenderInfo
1546 SubpassRenderInfo (const RenderPass& renderPass,
1547 deUint32 subpassIndex,
1551 const UVec2& viewportOffset,
1552 const UVec2& viewportSize,
1554 const Maybe<RenderQuad>& renderQuad,
1555 const vector<ColorClear>& colorClears,
1556 const Maybe<DepthStencilClear>& depthStencilClear)
1557 : m_viewportOffset (viewportOffset)
1558 , m_viewportSize (viewportSize)
1559 , m_subpassIndex (subpassIndex)
1560 , m_isSecondary (isSecondary_)
1561 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1562 , m_renderQuad (renderQuad)
1563 , m_colorClears (colorClears)
1564 , m_depthStencilClear (depthStencilClear)
1565 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1566 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1568 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1569 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1571 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1573 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1574 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1578 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1579 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1581 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1582 bool isSecondary (void) const { return m_isSecondary; }
1584 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1585 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1586 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1588 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); }
1589 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
1590 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1592 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1593 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1594 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1595 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1596 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1597 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1598 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1599 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1602 UVec2 m_viewportOffset;
1603 UVec2 m_viewportSize;
1605 deUint32 m_subpassIndex;
1607 VkSubpassDescriptionFlags m_flags;
1609 Maybe<RenderQuad> m_renderQuad;
1610 vector<ColorClear> m_colorClears;
1611 Maybe<DepthStencilClear> m_depthStencilClear;
1613 vector<AttachmentReference> m_colorAttachments;
1614 vector<Attachment> m_colorAttachmentInfo;
1616 Maybe<AttachmentReference> m_depthStencilAttachment;
1617 Maybe<Attachment> m_depthStencilAttachmentInfo;
1619 vector<AttachmentReference> m_inputAttachments;
1622 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1624 VkRenderPass renderPass,
1625 VkShaderModule vertexShaderModule,
1626 VkShaderModule fragmentShaderModule,
1627 VkPipelineLayout pipelineLayout,
1628 const SubpassRenderInfo& renderInfo)
1630 const VkSpecializationInfo emptyShaderSpecializations =
1632 0u, // mapEntryCount
1638 Maybe<VkSampleCountFlagBits> rasterSamples;
1639 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1641 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1643 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1645 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1647 rasterSamples = attachment.getSamples();
1650 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1652 VK_FALSE, // blendEnable
1653 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1654 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1655 VK_BLEND_OP_ADD, // blendOpColor
1656 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1657 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1658 VK_BLEND_OP_ADD, // blendOpAlpha
1659 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1662 attachmentBlendStates.push_back(attachmentBlendState);
1666 if (renderInfo.getDepthStencilAttachment())
1668 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1670 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1671 rasterSamples = attachment.getSamples();
1674 // If there are no attachment use single sample
1676 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1678 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1681 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1683 (VkPipelineShaderStageCreateFlags)0u,
1684 VK_SHADER_STAGE_VERTEX_BIT, // stage
1685 vertexShaderModule, // shader
1687 &emptyShaderSpecializations
1690 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1692 (VkPipelineShaderStageCreateFlags)0u,
1693 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1694 fragmentShaderModule, // shader
1696 &emptyShaderSpecializations
1699 const VkVertexInputBindingDescription vertexBinding =
1702 (deUint32)sizeof(tcu::Vec2), // strideInBytes
1703 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1705 const VkVertexInputAttributeDescription vertexAttrib =
1709 VK_FORMAT_R32G32_SFLOAT, // format
1710 0u, // offsetInBytes
1712 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1714 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1716 (VkPipelineVertexInputStateCreateFlags)0u,
1718 &vertexBinding, // pVertexBindingDescriptions
1719 1u, // attributeCount
1720 &vertexAttrib, // pVertexAttributeDescriptions
1722 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1724 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1726 (VkPipelineInputAssemblyStateCreateFlags)0u,
1727 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1728 VK_FALSE, // primitiveRestartEnable
1730 const VkViewport viewport =
1732 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1733 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1736 const VkRect2D scissor =
1738 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1739 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1741 const VkPipelineViewportStateCreateInfo viewportState =
1743 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1745 (VkPipelineViewportStateCreateFlags)0u,
1751 const VkPipelineRasterizationStateCreateInfo rasterState =
1753 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1755 (VkPipelineRasterizationStateCreateFlags)0u,
1756 VK_TRUE, // depthClipEnable
1757 VK_FALSE, // rasterizerDiscardEnable
1758 VK_POLYGON_MODE_FILL, // fillMode
1759 VK_CULL_MODE_NONE, // cullMode
1760 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1761 VK_FALSE, // depthBiasEnable
1763 0.0f, // depthBiasClamp
1764 0.0f, // slopeScaledDepthBias
1767 const VkPipelineMultisampleStateCreateInfo multisampleState =
1769 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1771 (VkPipelineMultisampleStateCreateFlags)0u,
1772 *rasterSamples, // rasterSamples
1773 VK_FALSE, // sampleShadingEnable
1774 0.0f, // minSampleShading
1775 DE_NULL, // pSampleMask
1776 VK_FALSE, // alphaToCoverageEnable
1777 VK_FALSE, // alphaToOneEnable
1779 const size_t stencilIndex = renderInfo.getSubpassIndex();
1780 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1782 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1784 (VkPipelineDepthStencilStateCreateFlags)0u,
1785 VK_TRUE, // depthTestEnable
1786 VK_TRUE, // depthWriteEnable
1787 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1788 VK_FALSE, // depthBoundsEnable
1789 VK_TRUE, // stencilTestEnable
1791 VK_STENCIL_OP_REPLACE, // stencilFailOp
1792 VK_STENCIL_OP_REPLACE, // stencilPassOp
1793 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1794 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1795 ~0u, // stencilCompareMask
1796 ~0u, // stencilWriteMask
1797 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1800 VK_STENCIL_OP_REPLACE, // stencilFailOp
1801 VK_STENCIL_OP_REPLACE, // stencilPassOp
1802 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1803 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1804 ~0u, // stencilCompareMask
1805 ~0u, // stencilWriteMask
1806 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1809 0.0f, // minDepthBounds;
1810 1.0f // maxDepthBounds;
1812 const VkPipelineColorBlendStateCreateInfo blendState =
1814 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1816 (VkPipelineColorBlendStateCreateFlags)0u,
1817 VK_FALSE, // logicOpEnable
1818 VK_LOGIC_OP_COPY, // logicOp
1819 (deUint32)attachmentBlendStates.size(), // attachmentCount
1820 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1821 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1823 const VkGraphicsPipelineCreateInfo createInfo =
1825 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1827 (VkPipelineCreateFlags)0u,
1830 shaderStages, // pStages
1832 &vertexInputState, // pVertexInputState
1833 &inputAssemblyState, // pInputAssemblyState
1834 DE_NULL, // pTessellationState
1835 &viewportState, // pViewportState
1836 &rasterState, // pRasterState
1837 &multisampleState, // pMultisampleState
1838 &depthStencilState, // pDepthStencilState
1839 &blendState, // pColorBlendState
1840 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1841 pipelineLayout, // layout
1843 renderPass, // renderPass
1844 renderInfo.getSubpassIndex(), // subpass
1845 DE_NULL, // basePipelineHandle
1846 0u // basePipelineIndex
1849 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1852 class SubpassRenderer
1855 SubpassRenderer (Context& context,
1856 const DeviceInterface& vk,
1858 Allocator& allocator,
1859 VkRenderPass renderPass,
1860 VkFramebuffer framebuffer,
1861 VkCommandPool commandBufferPool,
1862 deUint32 queueFamilyIndex,
1863 const vector<VkImage>& attachmentImages,
1864 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
1865 const SubpassRenderInfo& renderInfo,
1866 const vector<Attachment>& attachmentInfos,
1867 const AllocationKind allocationKind)
1868 : m_renderInfo (renderInfo)
1870 const InstanceInterface& vki = context.getInstanceInterface();
1871 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
1872 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1873 vector<VkDescriptorSetLayoutBinding> bindings;
1875 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
1876 m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);
1878 if (renderInfo.getDepthStencilAttachmentIndex())
1879 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
1881 if (renderInfo.getRenderQuad())
1883 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1885 if (renderInfo.getInputAttachmentCount() > 0)
1887 deUint32 bindingIndex = 0;
1889 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1891 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1892 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1893 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1894 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1895 const deUint32 bindingCount = isDepthFormat && isStencilFormat ? 2u : 1u;
1897 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
1899 const VkDescriptorSetLayoutBinding binding =
1902 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1904 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1908 bindings.push_back(binding);
1913 const VkDescriptorSetLayoutCreateInfo createInfo =
1915 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1919 (deUint32)bindings.size(),
1923 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
1926 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
1927 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1929 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1931 (vk::VkPipelineLayoutCreateFlags)0,
1932 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
1933 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
1934 0u, // pushConstantRangeCount;
1935 DE_NULL, // pPushConstantRanges;
1938 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1939 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1940 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
1941 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
1943 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
1944 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1946 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
1947 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
1949 if (renderInfo.getInputAttachmentCount() > 0)
1952 const VkDescriptorPoolSize poolSize =
1954 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1955 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
1956 renderInfo.getInputAttachmentCount() * 2u
1958 const VkDescriptorPoolCreateInfo createInfo =
1960 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1962 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1964 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
1965 renderInfo.getInputAttachmentCount() * 2u,
1970 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
1973 const VkDescriptorSetAllocateInfo allocateInfo =
1975 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1980 &descriptorSetLayout
1983 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
1986 vector<VkWriteDescriptorSet> writes (bindings.size());
1987 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
1988 deUint32 bindingIndex = 0;
1990 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1992 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1993 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1994 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1995 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1996 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
1998 if (isDepthFormat && isStencilFormat)
2001 const VkDescriptorImageInfo imageInfo =
2004 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2005 inputAttachmentLayout
2007 imageInfos[bindingIndex] = imageInfo;
2010 const VkWriteDescriptorSet write =
2012 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2019 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2020 &imageInfos[bindingIndex],
2024 writes[bindingIndex] = write;
2030 const VkDescriptorImageInfo imageInfo =
2033 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2034 inputAttachmentLayout
2036 imageInfos[bindingIndex] = imageInfo;
2039 const VkWriteDescriptorSet write =
2041 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2048 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2049 &imageInfos[bindingIndex],
2053 writes[bindingIndex] = write;
2061 const VkDescriptorImageInfo imageInfo =
2064 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2065 inputAttachmentLayout
2067 imageInfos[bindingIndex] = imageInfo;
2070 const VkWriteDescriptorSet write =
2072 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2079 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2080 &imageInfos[bindingIndex],
2084 writes[bindingIndex] = write;
2091 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2096 if (renderInfo.isSecondary())
2098 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2100 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
2101 pushRenderCommands(vk, *m_commandBuffer);
2102 endCommandBuffer(vk, *m_commandBuffer);
2106 bool isSecondary (void) const
2108 return m_commandBuffer;
2111 VkCommandBuffer getCommandBuffer (void) const
2113 DE_ASSERT(isSecondary());
2114 return *m_commandBuffer;
2117 void pushRenderCommands (const DeviceInterface& vk,
2118 VkCommandBuffer commandBuffer)
2120 if (!m_renderInfo.getColorClears().empty())
2122 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2124 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2126 const ColorClear& colorClear = colorClears[attachmentNdx];
2127 const VkClearAttachment attachment =
2129 VK_IMAGE_ASPECT_COLOR_BIT,
2131 makeClearValue(colorClear.getColor()),
2133 const VkClearRect rect =
2136 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2137 { colorClear.getSize().x(), colorClear.getSize().y() }
2139 0u, // baseArrayLayer
2143 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2147 if (m_renderInfo.getDepthStencilClear())
2149 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2150 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2151 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2152 const VkClearAttachment attachment =
2154 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2155 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2157 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2159 const VkClearRect rect =
2162 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2163 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2165 0u, // baseArrayLayer
2169 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2172 vector<VkImageMemoryBarrier> selfDeps;
2173 VkPipelineStageFlags srcStages = 0;
2174 VkPipelineStageFlags dstStages = 0;
2176 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2178 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2180 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2182 const VkImageMemoryBarrier barrier =
2184 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2187 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2188 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2190 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2191 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2193 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2194 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2196 m_colorAttachmentImages[colorAttachmentNdx], // image
2197 { // subresourceRange
2198 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2201 0, // baseArraySlice
2206 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2207 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2209 selfDeps.push_back(barrier);
2213 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2215 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2216 const bool hasDepth = hasDepthComponent(format.order);
2217 const bool hasStencil = hasStencilComponent(format.order);
2218 const VkImageMemoryBarrier barrier =
2220 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2223 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2224 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2226 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2227 VK_IMAGE_LAYOUT_GENERAL, // newLayout;
2229 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2230 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2232 m_depthStencilAttachmentImage, // image;
2233 { // subresourceRange;
2234 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2235 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2238 0, // baseArraySlice;
2243 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2244 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2246 selfDeps.push_back(barrier);
2250 if (!selfDeps.empty())
2252 DE_ASSERT(srcStages != 0);
2253 DE_ASSERT(dstStages != 0);
2254 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2257 if (m_renderInfo.getRenderQuad())
2259 const VkDeviceSize offset = 0;
2260 const VkBuffer vertexBuffer = *m_vertexBuffer;
2262 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2264 if (m_descriptorSet)
2266 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2267 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2270 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2271 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2276 const SubpassRenderInfo m_renderInfo;
2277 Move<VkCommandBuffer> m_commandBuffer;
2278 Move<VkPipeline> m_pipeline;
2279 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2280 Move<VkPipelineLayout> m_pipelineLayout;
2282 Move<VkShaderModule> m_vertexShaderModule;
2283 Move<VkShaderModule> m_fragmentShaderModule;
2285 Move<VkDescriptorPool> m_descriptorPool;
2286 Move<VkDescriptorSet> m_descriptorSet;
2287 Move<VkBuffer> m_vertexBuffer;
2288 de::MovePtr<Allocation> m_vertexBufferMemory;
2289 vector<VkImage> m_colorAttachmentImages;
2290 VkImage m_depthStencilAttachmentImage;
2293 void pushImageInitializationCommands (const DeviceInterface& vk,
2294 VkCommandBuffer commandBuffer,
2295 const vector<Attachment>& attachmentInfo,
2296 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2297 deUint32 queueIndex,
2298 const vector<Maybe<VkClearValue> >& clearValues)
2301 vector<VkImageMemoryBarrier> initializeLayouts;
2303 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2305 if (!clearValues[attachmentNdx])
2308 const VkImageMemoryBarrier barrier =
2310 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2313 (VkAccessFlags)0, // srcAccessMask
2314 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2316 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2317 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2319 queueIndex, // srcQueueFamilyIndex;
2320 queueIndex, // destQueueFamilyIndex;
2322 attachmentResources[attachmentNdx]->getImage(), // image;
2323 { // subresourceRange;
2324 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2327 0, // baseArraySlice;
2332 initializeLayouts.push_back(barrier);
2335 if (!initializeLayouts.empty())
2336 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2337 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2338 0, (const VkMemoryBarrier*)DE_NULL,
2339 0, (const VkBufferMemoryBarrier*)DE_NULL,
2340 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2343 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2345 if (!clearValues[attachmentNdx])
2348 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2350 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2352 const float clearNan = tcu::Float32::nan().asFloat();
2353 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2354 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2355 const VkClearDepthStencilValue depthStencil =
2360 const VkImageSubresourceRange range =
2362 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2363 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2370 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2374 const VkImageSubresourceRange range =
2376 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2379 0, // baseArrayLayer;
2382 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2384 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2389 vector<VkImageMemoryBarrier> renderPassLayouts;
2391 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2393 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2394 const VkImageMemoryBarrier barrier =
2396 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2399 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask
2400 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2402 oldLayout, // oldLayout
2403 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2405 queueIndex, // srcQueueFamilyIndex;
2406 queueIndex, // destQueueFamilyIndex;
2408 attachmentResources[attachmentNdx]->getImage(), // image;
2409 { // subresourceRange;
2410 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2413 0, // baseArraySlice;
2418 renderPassLayouts.push_back(barrier);
2421 if (!renderPassLayouts.empty())
2422 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2423 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2424 0, (const VkMemoryBarrier*)DE_NULL,
2425 0, (const VkBufferMemoryBarrier*)DE_NULL,
2426 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2430 void pushRenderPassCommands (const DeviceInterface& vk,
2431 VkCommandBuffer commandBuffer,
2432 VkRenderPass renderPass,
2433 VkFramebuffer framebuffer,
2434 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2435 const UVec2& renderPos,
2436 const UVec2& renderSize,
2437 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2438 TestConfig::RenderTypes render)
2440 const float clearNan = tcu::Float32::nan().asFloat();
2441 vector<VkClearValue> attachmentClearValues;
2443 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2445 if (renderPassClearValues[attachmentNdx])
2446 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2448 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2452 const VkRect2D renderArea =
2454 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2455 { renderSize.x(), renderSize.y() }
2458 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2460 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2462 if (subpassNdx == 0)
2463 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2465 vk.cmdNextSubpass(commandBuffer, contents);
2469 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2471 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2473 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2475 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2476 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2479 DE_FATAL("Invalid contents");
2483 vk.cmdEndRenderPass(commandBuffer);
2487 void pushReadImagesToBuffers (const DeviceInterface& vk,
2488 VkCommandBuffer commandBuffer,
2489 deUint32 queueIndex,
2491 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2492 const vector<Attachment>& attachmentInfo,
2493 const vector<bool>& isLazy,
2495 const UVec2& targetSize)
2498 vector<VkImageMemoryBarrier> imageBarriers;
2500 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2502 if (isLazy[attachmentNdx])
2505 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2506 const VkImageMemoryBarrier barrier =
2508 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2511 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2512 getAllMemoryReadFlags(), // dstAccessMask
2514 oldLayout, // oldLayout
2515 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2517 queueIndex, // srcQueueFamilyIndex
2518 queueIndex, // destQueueFamilyIndex
2520 attachmentResources[attachmentNdx]->getImage(), // image
2521 { // subresourceRange
2522 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2525 0, // baseArraySlice
2530 imageBarriers.push_back(barrier);
2533 if (!imageBarriers.empty())
2534 vk.cmdPipelineBarrier(commandBuffer,
2535 getAllPipelineStageFlags(),
2536 getAllPipelineStageFlags(),
2537 (VkDependencyFlags)0,
2538 0, (const VkMemoryBarrier*)DE_NULL,
2539 0, (const VkBufferMemoryBarrier*)DE_NULL,
2540 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2543 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2545 if (isLazy[attachmentNdx])
2548 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2549 const VkBufferImageCopy rect =
2552 0, // bufferRowLength
2553 0, // bufferImageHeight
2554 { // imageSubresource
2555 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2560 { 0, 0, 0 }, // imageOffset
2561 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2564 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2566 if (tcu::TextureFormat::DS == order)
2568 const VkBufferImageCopy stencilRect =
2571 0, // bufferRowLength
2572 0, // bufferImageHeight
2573 { // imageSubresource
2574 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2579 { 0, 0, 0 }, // imageOffset
2580 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2583 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2588 vector<VkBufferMemoryBarrier> bufferBarriers;
2590 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2592 if (isLazy[attachmentNdx])
2595 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2596 const VkBufferMemoryBarrier bufferBarrier =
2598 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2601 getAllMemoryWriteFlags(),
2602 getAllMemoryReadFlags(),
2607 attachmentResources[attachmentNdx]->getBuffer(),
2609 attachmentResources[attachmentNdx]->getBufferSize()
2612 bufferBarriers.push_back(bufferBarrier);
2614 if (tcu::TextureFormat::DS == order)
2616 const VkBufferMemoryBarrier secondaryBufferBarrier =
2618 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2621 getAllMemoryWriteFlags(),
2622 getAllMemoryReadFlags(),
2627 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2629 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2632 bufferBarriers.push_back(secondaryBufferBarrier);
2636 if (!bufferBarriers.empty())
2637 vk.cmdPipelineBarrier(commandBuffer,
2638 getAllPipelineStageFlags(),
2639 getAllPipelineStageFlags(),
2640 (VkDependencyFlags)0,
2641 0, (const VkMemoryBarrier*)DE_NULL,
2642 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2643 0, (const VkImageMemoryBarrier*)DE_NULL);
2650 PixelValue (const Maybe<bool>& x = nothing<bool>(),
2651 const Maybe<bool>& y = nothing<bool>(),
2652 const Maybe<bool>& z = nothing<bool>(),
2653 const Maybe<bool>& w = nothing<bool>());
2655 void setUndefined (size_t ndx);
2656 void setValue (size_t ndx, bool value);
2657 Maybe<bool> getValue (size_t ndx) const;
2663 PixelValue::PixelValue (const Maybe<bool>& x,
2664 const Maybe<bool>& y,
2665 const Maybe<bool>& z,
2666 const Maybe<bool>& w)
2669 const Maybe<bool> values[] =
2674 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
2677 setValue(ndx, *values[ndx]);
2682 DE_ASSERT(m_status <= 0xFFu);
2685 void PixelValue::setUndefined (size_t ndx)
2688 DE_ASSERT(m_status <= 0xFFu);
2690 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
2691 DE_ASSERT(m_status <= 0xFFu);
2694 void PixelValue::setValue (size_t ndx, bool value)
2697 DE_ASSERT(m_status <= 0xFFu);
2699 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
2702 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
2704 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
2706 DE_ASSERT(m_status <= 0xFFu);
2709 Maybe<bool> PixelValue::getValue (size_t ndx) const
2712 DE_ASSERT(m_status <= 0xFFu);
2714 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
2716 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
2719 return nothing<bool>();
2722 void clearReferenceValues (vector<PixelValue>& values,
2723 const UVec2& targetSize,
2724 const UVec2& offset,
2727 const PixelValue& value)
2729 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2730 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
2731 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
2733 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2734 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2736 for (int compNdx = 0; compNdx < 4; compNdx++)
2740 if (value.getValue(compNdx))
2741 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
2743 values[x + y * targetSize.x()].setUndefined(compNdx);
2749 void markUndefined (vector<PixelValue>& values,
2751 const UVec2& targetSize,
2752 const UVec2& offset,
2755 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2757 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2758 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2760 for (int compNdx = 0; compNdx < 4; compNdx++)
2763 values[x + y * targetSize.x()].setUndefined(compNdx);
2768 PixelValue clearValueToPixelValue (const VkClearValue& value,
2769 const tcu::TextureFormat& format)
2771 const bool isDepthAttachment = hasDepthComponent(format.order);
2772 const bool isStencilAttachment = hasStencilComponent(format.order);
2773 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
2774 PixelValue pixelValue;
2776 if (isDepthOrStencilAttachment)
2778 if (isDepthAttachment)
2780 if (value.depthStencil.depth == 1.0f)
2781 pixelValue.setValue(0, true);
2782 else if (value.depthStencil.depth == 0.0f)
2783 pixelValue.setValue(0, false);
2785 DE_FATAL("Unknown depth value");
2788 if (isStencilAttachment)
2790 if (value.depthStencil.stencil == 0xFFu)
2791 pixelValue.setValue(1, true);
2792 else if (value.depthStencil.stencil == 0x0u)
2793 pixelValue.setValue(1, false);
2795 DE_FATAL("Unknown stencil value");
2800 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2801 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2803 switch (channelClass)
2805 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2806 for (int i = 0; i < 4; i++)
2810 if (value.color.int32[i] == 1)
2811 pixelValue.setValue(i, true);
2812 else if (value.color.int32[i] == 0)
2813 pixelValue.setValue(i, false);
2815 DE_FATAL("Unknown clear color value");
2820 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2821 for (int i = 0; i < 4; i++)
2825 if (value.color.uint32[i] == 1u)
2826 pixelValue.setValue(i, true);
2827 else if (value.color.uint32[i] == 0u)
2828 pixelValue.setValue(i, false);
2830 DE_FATAL("Unknown clear color value");
2835 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2836 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2837 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2838 for (int i = 0; i < 4; i++)
2842 if (value.color.float32[i] == 1.0f)
2843 pixelValue.setValue(i, true);
2844 else if (value.color.float32[i] == 0.0f)
2845 pixelValue.setValue(i, false);
2847 DE_FATAL("Unknown clear color value");
2853 DE_FATAL("Unknown channel class");
2860 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
2861 const RenderPass& renderPassInfo,
2862 const UVec2& targetSize,
2863 const vector<Maybe<VkClearValue> >& imageClearValues,
2864 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2865 const vector<SubpassRenderInfo>& subpassRenderInfo,
2866 const UVec2& renderPos,
2867 const UVec2& renderSize)
2869 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2870 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2872 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2874 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2876 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2877 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2878 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
2880 reference.resize(targetSize.x() * targetSize.y());
2882 if (imageClearValues[attachmentNdx])
2883 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
2886 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2888 const Subpass& subpass = subpasses[subpassNdx];
2889 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2890 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2892 // Apply load op if attachment was used for the first time
2893 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2895 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2897 if (!attachmentUsed[attachmentIndex])
2899 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2900 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2901 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2903 DE_ASSERT(!tcu::hasDepthComponent(format.order));
2904 DE_ASSERT(!tcu::hasStencilComponent(format.order));
2906 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2907 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2908 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2909 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
2911 attachmentUsed[attachmentIndex] = true;
2915 // Apply load op to depth/stencil attachment if it was used for the first time
2916 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2918 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2920 // Apply load op if attachment was used for the first time
2921 if (!attachmentUsed[attachmentIndex])
2923 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2924 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2925 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2927 if (tcu::hasDepthComponent(format.order))
2929 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2930 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2931 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2932 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
2935 if (tcu::hasStencilComponent(format.order))
2937 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2938 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2939 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2940 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
2943 attachmentUsed[attachmentIndex] = true;
2947 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
2949 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
2950 const UVec2 offset = colorClear.getOffset();
2951 const UVec2 size = colorClear.getSize();
2952 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
2953 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2954 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2955 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2958 value.color = colorClear.getColor();
2960 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
2963 if (renderInfo.getDepthStencilClear())
2965 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
2966 const UVec2 offset = dsClear.getOffset();
2967 const UVec2 size = dsClear.getSize();
2968 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2969 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2970 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2971 const bool hasStencil = tcu::hasStencilComponent(format.order);
2972 const bool hasDepth = tcu::hasDepthComponent(format.order);
2973 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2976 value.depthStencil.depth = dsClear.getDepth();
2977 value.depthStencil.stencil = dsClear.getStencil();
2979 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
2982 if (renderInfo.getRenderQuad())
2984 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2985 const Vec2 posA = renderQuad.getCornerA();
2986 const Vec2 posB = renderQuad.getCornerB();
2987 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2988 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
2989 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
2990 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
2991 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
2992 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
2994 DE_ASSERT(posAI.x() < posBI.x());
2995 DE_ASSERT(posAI.y() < posBI.y());
2997 if (subpass.getInputAttachments().empty())
2999 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3001 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3002 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3003 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3004 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3005 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3007 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3008 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3010 for (int compNdx = 0; compNdx < 4; compNdx++)
3012 const size_t index = subpassNdx + attachmentIndex + compNdx;
3013 const BoolOp op = boolOpFromIndex(index);
3014 const bool boolX = x % 2 == (int)(index % 2);
3015 const bool boolY = y % 2 == (int)((index / 2) % 2);
3017 if (channelMask[compNdx])
3018 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3023 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3025 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3026 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3027 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3028 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3030 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3031 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3033 if (tcu::hasDepthComponent(format.order))
3035 const size_t index = subpassNdx + 1;
3036 const BoolOp op = boolOpFromIndex(index);
3037 const bool boolX = x % 2 == (int)(index % 2);
3038 const bool boolY = y % 2 == (int)((index / 2) % 2);
3040 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3043 if (tcu::hasStencilComponent(format.order))
3045 const size_t index = subpassNdx;
3046 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3053 size_t outputComponentCount = 0;
3054 vector<Maybe<bool> > inputs;
3056 DE_ASSERT(posAI.x() < posBI.x());
3057 DE_ASSERT(posAI.y() < posBI.y());
3059 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3061 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3062 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3063 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3064 const int componentCount = tcu::getNumUsedChannels(format.order);
3066 outputComponentCount += (size_t)componentCount;
3069 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3070 outputComponentCount++;
3072 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3073 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3075 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3077 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3078 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3079 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3080 const int componentCount = tcu::getNumUsedChannels(format.order);
3082 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3083 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3086 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3087 ? ((inputs.size() / outputComponentCount)
3088 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3091 size_t outputValueNdx = 0;
3093 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3095 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3096 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3097 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3098 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3099 const int componentCount = tcu::getNumUsedChannels(format.order);
3101 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3103 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3104 const BoolOp op = boolOpFromIndex(index);
3105 const bool boolX = x % 2 == (int)(index % 2);
3106 const bool boolY = y % 2 == (int)((index / 2) % 2);
3107 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3109 for (size_t i = 0; i < inputsPerOutput; i++)
3113 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3114 output = tcu::nothing<bool>();
3116 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3120 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3122 reference[x + y * targetSize.x()].setUndefined(compNdx);
3125 outputValueNdx += componentCount;
3128 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3130 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3131 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3132 const size_t index = subpassNdx + attachmentIndex;
3133 const BoolOp op = boolOpFromIndex(index);
3134 const bool boolX = x % 2 == (int)(index % 2);
3135 const bool boolY = y % 2 == (int)((index / 2) % 2);
3136 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3138 for (size_t i = 0; i < inputsPerOutput; i++)
3142 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3143 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3145 output = tcu::nothing<bool>();
3149 reference[x + y * targetSize.x()].setValue(0, *output);
3151 reference[x + y * targetSize.x()].setUndefined(0);
3157 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3159 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3160 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3161 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3162 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3164 if (tcu::hasStencilComponent(format.order))
3166 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3167 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3169 const size_t index = subpassNdx;
3170 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3178 // Mark all attachments that were used but not stored as undefined
3179 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3181 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3182 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3183 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3184 const bool isStencilAttachment = hasStencilComponent(format.order);
3185 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3187 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3189 if (isDepthOrStencilAttachment)
3190 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3192 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3195 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3196 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3200 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3201 const vector<vector<PixelValue> >& referenceValues,
3202 const UVec2& targetSize,
3203 const RenderPass& renderPassInfo)
3205 referenceImages.resize(referenceValues.size());
3207 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3209 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3210 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3211 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3212 const bool hasDepth = tcu::hasDepthComponent(format.order);
3213 const bool hasStencil = tcu::hasStencilComponent(format.order);
3214 const bool hasDepthOrStencil = hasDepth || hasStencil;
3215 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3217 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3219 if (hasDepthOrStencil)
3223 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3225 for (deUint32 y = 0; y < targetSize.y(); y++)
3226 for (deUint32 x = 0; x < targetSize.x(); x++)
3228 if (reference[x + y * targetSize.x()].getValue(0))
3230 if (*reference[x + y * targetSize.x()].getValue(0))
3231 depthAccess.setPixDepth(1.0f, x, y);
3233 depthAccess.setPixDepth(0.0f, x, y);
3235 else // Fill with 3x3 grid
3236 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3242 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3244 for (deUint32 y = 0; y < targetSize.y(); y++)
3245 for (deUint32 x = 0; x < targetSize.x(); x++)
3247 if (reference[x + y * targetSize.x()].getValue(1))
3249 if (*reference[x + y * targetSize.x()].getValue(1))
3250 stencilAccess.setPixStencil(0xFFu, x, y);
3252 stencilAccess.setPixStencil(0x0u, x, y);
3254 else // Fill with 3x3 grid
3255 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3261 for (deUint32 y = 0; y < targetSize.y(); y++)
3262 for (deUint32 x = 0; x < targetSize.x(); x++)
3266 for (int compNdx = 0; compNdx < 4; compNdx++)
3268 if (reference[x + y * targetSize.x()].getValue(compNdx))
3270 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3271 color[compNdx] = 1.0f;
3273 color[compNdx] = 0.0f;
3275 else // Fill with 3x3 grid
3276 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3279 referenceImage.getAccess().setPixel(color, x, y);
3285 bool verifyColorAttachment (const vector<PixelValue>& reference,
3286 const ConstPixelBufferAccess& result,
3287 const PixelBufferAccess& errorImage)
3289 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3290 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3293 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3294 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3295 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3297 for (int y = 0; y < result.getHeight(); y++)
3298 for (int x = 0; x < result.getWidth(); x++)
3300 const Vec4 resultColor = result.getPixel(x, y);
3301 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3302 bool pixelOk = true;
3304 for (int compNdx = 0; compNdx < 4; compNdx++)
3306 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
3310 const bool value = *maybeValue;
3312 if ((value && (resultColor[compNdx] != 1.0f))
3313 || (!value && resultColor[compNdx] != 0.0f))
3320 errorImage.setPixel(red, x, y);
3324 errorImage.setPixel(green, x, y);
3330 bool verifyDepthAttachment (const vector<PixelValue>& reference,
3331 const ConstPixelBufferAccess& result,
3332 const PixelBufferAccess& errorImage)
3334 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3335 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3338 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3339 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3340 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3342 for (int y = 0; y < result.getHeight(); y++)
3343 for (int x = 0; x < result.getWidth(); x++)
3345 bool pixelOk = true;
3347 const float resultDepth = result.getPixDepth(x, y);
3348 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3349 const Maybe<bool> maybeValue = referenceValue.getValue(0);
3353 const bool value = *maybeValue;
3355 if ((value && (resultDepth != 1.0f))
3356 || (!value && resultDepth != 0.0f))
3362 errorImage.setPixel(red, x, y);
3366 errorImage.setPixel(green, x, y);
3372 bool verifyStencilAttachment (const vector<PixelValue>& reference,
3373 const ConstPixelBufferAccess& result,
3374 const PixelBufferAccess& errorImage)
3376 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3377 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3380 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3381 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3382 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3384 for (int y = 0; y < result.getHeight(); y++)
3385 for (int x = 0; x < result.getWidth(); x++)
3387 bool pixelOk = true;
3389 const deUint32 resultStencil = result.getPixStencil(x, y);
3390 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3391 const Maybe<bool> maybeValue = referenceValue.getValue(1);
3395 const bool value = *maybeValue;
3397 if ((value && (resultStencil != 0xFFu))
3398 || (!value && resultStencil != 0x0u))
3404 errorImage.setPixel(red, x, y);
3408 errorImage.setPixel(green, x, y);
3414 bool logAndVerifyImages (TestLog& log,
3415 const DeviceInterface& vk,
3417 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3418 const vector<bool>& attachmentIsLazy,
3419 const RenderPass& renderPassInfo,
3420 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3421 const vector<Maybe<VkClearValue> >& imageClearValues,
3422 const vector<SubpassRenderInfo>& subpassRenderInfo,
3423 const UVec2& targetSize,
3424 const TestConfig& config)
3426 vector<vector<PixelValue> > referenceValues;
3427 vector<tcu::TextureLevel> referenceAttachments;
3430 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
3432 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3433 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);
3435 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3437 if (!attachmentIsLazy[attachmentNdx])
3439 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3440 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3442 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3444 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3445 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3446 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3448 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3449 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3450 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3452 const VkMappedMemoryRange ranges[] =
3455 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3457 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3458 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3459 depthBufferSize // size;
3462 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3464 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3465 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3466 stencilBufferSize // size;
3469 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3472 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3473 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3474 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3475 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3477 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3478 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3480 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3482 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3483 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
3485 log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
3489 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3490 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
3492 log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
3499 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3500 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3502 const VkMappedMemoryRange range =
3504 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3506 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3507 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3510 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3512 if (tcu::hasDepthComponent(format.order))
3514 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3515 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3517 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3518 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3520 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3521 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3523 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3527 else if (tcu::hasStencilComponent(format.order))
3529 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3530 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3532 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3533 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3535 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3536 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3538 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3544 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3545 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3547 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3548 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3550 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3551 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3553 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3564 std::string getInputAttachmentType (VkFormat vkFormat)
3566 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3567 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3569 switch (channelClass)
3571 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3572 return "isubpassInput";
3574 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3575 return "usubpassInput";
3577 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3578 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3579 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3580 return "subpassInput";
3583 DE_FATAL("Unknown channel class");
3588 std::string getAttachmentType (VkFormat vkFormat)
3590 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3591 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3593 switch (channelClass)
3595 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3598 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3601 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3602 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3603 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3607 DE_FATAL("Unknown channel class");
3612 void createTestShaders (SourceCollections& dst, TestConfig config)
3614 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3616 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3618 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3620 const Subpass& subpass = subpasses[subpassNdx];
3621 deUint32 inputAttachmentBinding = 0;
3622 std::ostringstream vertexShader;
3623 std::ostringstream fragmentShader;
3625 vertexShader << "#version 310 es\n"
3626 << "layout(location = 0) in highp vec2 a_position;\n"
3627 << "void main (void) {\n"
3628 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
3631 fragmentShader << "#version 310 es\n"
3632 << "precision highp float;\n";
3634 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3636 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3637 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3638 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3639 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3640 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3642 if (isDepthFormat || isStencilFormat)
3646 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
3647 inputAttachmentBinding++;
3650 if (isStencilFormat)
3652 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
3653 inputAttachmentBinding++;
3658 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
3660 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
3661 inputAttachmentBinding++;
3665 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3667 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3668 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3671 fragmentShader << "void main (void) {\n";
3673 if (subpass.getInputAttachments().empty())
3675 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3677 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3678 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3680 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";
3682 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3684 const size_t index = subpassNdx + attachmentIndex + compNdx;
3685 const BoolOp op = boolOpFromIndex(index);
3688 fragmentShader << ",\n\t\t";
3690 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
3691 << ") " << boolOpToString(op) << " ("
3692 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3693 << ") ? 1.0 : 0.0)";
3696 fragmentShader << "));\n";
3699 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3701 const size_t index = subpassNdx + 1;
3702 const BoolOp op = boolOpFromIndex(index);
3704 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
3705 << ") " << boolOpToString(op) << " ("
3706 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3707 << ") ? 1.0 : 0.0);\n";
3712 size_t inputComponentCount = 0;
3713 size_t outputComponentCount = 0;
3715 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3717 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3718 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3719 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3720 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3722 inputComponentCount += componentCount;
3725 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3727 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3728 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3729 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3730 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3732 outputComponentCount += componentCount;
3735 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3736 outputComponentCount++;
3738 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
3739 ? ((inputComponentCount / outputComponentCount)
3740 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
3743 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"
3744 "\tbool outputs[" << outputComponentCount << "];\n";
3746 size_t inputValueNdx = 0;
3748 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3750 const char* const components[] =
3754 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3755 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3756 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3757 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3758 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3759 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3761 if (isDepthFormat || isStencilFormat)
3765 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
3769 if (isStencilFormat)
3771 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
3777 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3779 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
3785 size_t outputValueNdx = 0;
3787 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3789 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3790 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3791 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3792 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3793 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3795 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3797 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3798 const BoolOp op = boolOpFromIndex(index);
3800 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
3801 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3802 << ") " << boolOpToString(op) << " ("
3803 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3806 for (size_t i = 0; i < inputsPerOutput; i++)
3807 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
3810 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
3812 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3815 fragmentShader << ", ";
3817 if (compNdx < componentCount)
3818 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
3820 fragmentShader << "0";
3823 outputValueNdx += componentCount;
3825 fragmentShader << ");\n";
3828 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3830 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3831 const size_t index = subpassNdx + attachmentIndex;
3832 const BoolOp op = boolOpFromIndex(index);
3834 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
3835 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3836 << ") " << boolOpToString(op) << " ("
3837 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3840 for (size_t i = 0; i < inputsPerOutput; i++)
3841 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
3843 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
3847 fragmentShader << "}\n";
3849 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3850 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3855 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3857 bool lastAttachmentWasLazy = false;
3859 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3861 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3862 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3863 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3864 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3866 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3868 attachmentIsLazy.push_back(true);
3870 lastAttachmentWasLazy = true;
3872 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3874 attachmentIsLazy.push_back(false);
3875 lastAttachmentWasLazy = false;
3878 DE_FATAL("Unknown imageMemory");
3881 attachmentIsLazy.push_back(false);
3885 enum AttachmentRefType
3887 ATTACHMENTREFTYPE_COLOR,
3888 ATTACHMENTREFTYPE_DEPTH_STENCIL,
3889 ATTACHMENTREFTYPE_INPUT,
3890 ATTACHMENTREFTYPE_RESOLVE,
3893 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
3897 case VK_IMAGE_LAYOUT_GENERAL:
3898 case VK_IMAGE_LAYOUT_PREINITIALIZED:
3901 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3902 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3904 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3905 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3906 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3908 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3909 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3911 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3912 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3914 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3915 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3918 DE_FATAL("Unexpected image layout");
3923 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
3925 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
3927 const deUint32 attachment = references[referenceNdx].getAttachment();
3929 if (attachment != VK_ATTACHMENT_UNUSED)
3931 VkImageUsageFlags usage;
3935 case ATTACHMENTREFTYPE_COLOR:
3936 case ATTACHMENTREFTYPE_RESOLVE:
3937 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3940 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
3941 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3944 case ATTACHMENTREFTYPE_INPUT:
3945 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3949 DE_FATAL("Unexpected attachment reference type");
3954 attachmentImageUsage[attachment] |= usage;
3959 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
3961 if (!references.empty())
3963 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
3967 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
3969 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
3971 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
3973 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
3975 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
3976 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
3977 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
3978 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
3981 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3983 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
3984 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
3985 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
3987 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
3988 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
3990 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
3991 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
3993 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
3994 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
3996 if (!attachmentIsLazy[attachmentNdx])
3998 if (clearValues[attachmentNdx])
3999 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4001 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4005 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);
4007 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4008 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4013 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4015 bool lastSubpassWasSecondary = false;
4017 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4019 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4021 subpassIsSecondary.push_back(true);
4022 lastSubpassWasSecondary = true;
4024 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4026 subpassIsSecondary.push_back(false);
4027 lastSubpassWasSecondary = false;
4030 DE_FATAL("Unknown commandBuffer");
4034 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
4036 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4038 if (!isLazy[attachmentNdx])
4039 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4041 clearValues.push_back(nothing<VkClearValue>());
4045 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
4047 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4049 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4050 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4052 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4055 clearValues.push_back(nothing<VkClearValue>());
4059 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
4061 clearValues.resize(renderPass.getSubpasses().size());
4063 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4065 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
4066 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4068 clearValues[subpassNdx].resize(colorAttachments.size());
4070 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4072 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4073 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4075 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
4080 void logSubpassRenderInfo (TestLog& log,
4081 const SubpassRenderInfo& info)
4083 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4085 if (info.isSecondary())
4086 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4088 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4090 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4092 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4094 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4095 << ". Offset: " << colorClear.getOffset()
4096 << ", Size: " << colorClear.getSize()
4097 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
4100 if (info.getDepthStencilClear())
4102 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4104 log << TestLog::Message << "Clearing depth stencil attachment"
4105 << ". Offset: " << depthStencilClear.getOffset()
4106 << ", Size: " << depthStencilClear.getSize()
4107 << ", Depth: " << depthStencilClear.getDepth()
4108 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4111 if (info.getRenderQuad())
4113 const RenderQuad& renderQuad = *info.getRenderQuad();
4115 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4119 void logTestCaseInfo (TestLog& log,
4120 const TestConfig& config,
4121 const vector<bool>& attachmentIsLazy,
4122 const vector<Maybe<VkClearValue> >& imageClearValues,
4123 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4124 const vector<SubpassRenderInfo>& subpassRenderInfo)
4126 const RenderPass& renderPass = config.renderPass;
4128 logRenderPassInfo(log, renderPass);
4130 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4131 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4132 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4134 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4135 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4137 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4139 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4141 if (attachmentIsLazy[attachmentNdx])
4142 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4144 if (imageClearValues[attachmentNdx])
4145 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
4147 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4148 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
4151 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4153 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4155 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
4159 float roundToViewport (float x, deUint32 offset, deUint32 size)
4161 const float origin = (float)(offset) + ((float(size) / 2.0f));
4162 const float p = (float)(size) / 2.0f;
4163 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4165 return (((float)xi) - origin) / p;
4168 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4170 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4171 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4172 bool lastSubpassWasSecondary = false;
4174 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4176 const Subpass& subpass = subpasses[subpassNdx];
4177 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
4178 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
4179 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
4180 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
4181 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
4183 vector<ColorClear> colorClears;
4184 Maybe<DepthStencilClear> depthStencilClear;
4185 Maybe<RenderQuad> renderQuad;
4187 lastSubpassWasSecondary = subpassIsSecondary;
4189 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
4191 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4193 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4195 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4196 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4197 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4198 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
4199 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
4200 const VkClearColorValue color = randomColorClearValue(attachment, rng);
4202 colorClears.push_back(ColorClear(offset, size, color));
4205 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4207 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
4208 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4209 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
4210 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
4211 const VkClearValue value = randomClearValue(attachment, rng);
4213 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
4217 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4219 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
4220 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
4222 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
4223 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
4225 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
4226 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
4228 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
4231 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
4235 void checkTextureFormatSupport (TestLog& log,
4236 const InstanceInterface& vk,
4237 VkPhysicalDevice device,
4238 const vector<Attachment>& attachments)
4240 bool supported = true;
4242 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4244 const Attachment& attachment = attachments[attachmentNdx];
4245 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4246 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
4247 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
4248 VkFormatProperties properties;
4250 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
4252 if ((properties.optimalTilingFeatures & flags) != flags)
4255 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
4260 TCU_THROW(NotSupportedError, "Format not supported");
4263 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
4265 const UVec2 targetSize = config.targetSize;
4266 const UVec2 renderPos = config.renderPos;
4267 const UVec2 renderSize = config.renderSize;
4268 const RenderPass& renderPassInfo = config.renderPass;
4270 TestLog& log = context.getTestContext().getLog();
4271 de::Random rng (config.seed);
4273 vector<bool> attachmentIsLazy;
4274 vector<VkImageUsageFlags> attachmentImageUsage;
4275 vector<Maybe<VkClearValue> > imageClearValues;
4276 vector<Maybe<VkClearValue> > renderPassClearValues;
4278 vector<bool> subpassIsSecondary;
4279 vector<SubpassRenderInfo> subpassRenderInfo;
4280 vector<vector<VkClearColorValue> > subpassColorClearValues;
4282 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
4284 const std::string extensionName("VK_KHR_dedicated_allocation");
4286 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
4287 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
4290 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
4291 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
4292 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
4293 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
4295 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
4296 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
4297 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
4299 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
4301 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
4304 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
4306 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
4308 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4310 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
4311 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
4316 const InstanceInterface& vki = context.getInstanceInterface();
4317 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
4318 const VkDevice device = context.getDevice();
4319 const DeviceInterface& vk = context.getDeviceInterface();
4320 const VkQueue queue = context.getUniversalQueue();
4321 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
4322 Allocator& allocator = context.getDefaultAllocator();
4324 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
4325 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
4326 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4327 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4328 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4330 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
4331 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
4332 vector<VkImage> attachmentImages;
4333 vector<VkImageView> attachmentViews;
4334 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
4336 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4338 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
4340 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
4341 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
4342 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
4344 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
4347 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4348 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
4349 endCommandBuffer(vk, *initializeImagesCommandBuffer);
4352 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
4354 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4355 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)));
4357 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4358 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
4359 endCommandBuffer(vk, *renderCommandBuffer);
4361 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4362 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
4363 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
4365 const VkCommandBuffer commandBuffers[] =
4367 *initializeImagesCommandBuffer,
4368 *renderCommandBuffer,
4369 *readImagesToBuffersCommandBuffer
4371 const Unique<VkFence> fence (createFence(vk, device, 0u));
4373 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
4374 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
4378 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
4379 return tcu::TestStatus::pass("Pass");
4381 return tcu::TestStatus::fail("Result verification failed");
4385 static const VkFormat s_coreColorFormats[] =
4387 VK_FORMAT_R5G6B5_UNORM_PACK16,
4392 VK_FORMAT_R8G8_UNORM,
4393 VK_FORMAT_R8G8_SNORM,
4394 VK_FORMAT_R8G8_UINT,
4395 VK_FORMAT_R8G8_SINT,
4396 VK_FORMAT_R8G8B8A8_UNORM,
4397 VK_FORMAT_R8G8B8A8_SNORM,
4398 VK_FORMAT_R8G8B8A8_UINT,
4399 VK_FORMAT_R8G8B8A8_SINT,
4400 VK_FORMAT_R8G8B8A8_SRGB,
4401 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4402 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4403 VK_FORMAT_A8B8G8R8_UINT_PACK32,
4404 VK_FORMAT_A8B8G8R8_SINT_PACK32,
4405 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4406 VK_FORMAT_B8G8R8A8_UNORM,
4407 VK_FORMAT_B8G8R8A8_SRGB,
4408 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4409 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4410 VK_FORMAT_A2B10G10R10_UINT_PACK32,
4411 VK_FORMAT_R16_UNORM,
4412 VK_FORMAT_R16_SNORM,
4415 VK_FORMAT_R16_SFLOAT,
4416 VK_FORMAT_R16G16_UNORM,
4417 VK_FORMAT_R16G16_SNORM,
4418 VK_FORMAT_R16G16_UINT,
4419 VK_FORMAT_R16G16_SINT,
4420 VK_FORMAT_R16G16_SFLOAT,
4421 VK_FORMAT_R16G16B16A16_UNORM,
4422 VK_FORMAT_R16G16B16A16_SNORM,
4423 VK_FORMAT_R16G16B16A16_UINT,
4424 VK_FORMAT_R16G16B16A16_SINT,
4425 VK_FORMAT_R16G16B16A16_SFLOAT,
4428 VK_FORMAT_R32_SFLOAT,
4429 VK_FORMAT_R32G32_UINT,
4430 VK_FORMAT_R32G32_SINT,
4431 VK_FORMAT_R32G32_SFLOAT,
4432 VK_FORMAT_R32G32B32A32_UINT,
4433 VK_FORMAT_R32G32B32A32_SINT,
4434 VK_FORMAT_R32G32B32A32_SFLOAT
4437 static const VkFormat s_coreDepthStencilFormats[] =
4439 VK_FORMAT_D16_UNORM,
4441 VK_FORMAT_X8_D24_UNORM_PACK32,
4442 VK_FORMAT_D32_SFLOAT,
4444 VK_FORMAT_D24_UNORM_S8_UINT,
4445 VK_FORMAT_D32_SFLOAT_S8_UINT
4448 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4450 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
4451 const VkAttachmentLoadOp loadOps[] =
4453 VK_ATTACHMENT_LOAD_OP_LOAD,
4454 VK_ATTACHMENT_LOAD_OP_CLEAR,
4455 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4458 const VkAttachmentStoreOp storeOps[] =
4460 VK_ATTACHMENT_STORE_OP_STORE,
4461 VK_ATTACHMENT_STORE_OP_DONT_CARE
4464 const VkImageLayout initialAndFinalColorLayouts[] =
4466 VK_IMAGE_LAYOUT_GENERAL,
4467 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4468 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4469 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4470 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4473 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4475 VK_IMAGE_LAYOUT_GENERAL,
4476 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4477 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4478 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4479 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4480 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4483 const VkImageLayout subpassLayouts[] =
4485 VK_IMAGE_LAYOUT_GENERAL,
4486 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4489 const VkImageLayout depthStencilLayouts[] =
4491 VK_IMAGE_LAYOUT_GENERAL,
4492 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4495 const TestConfig::RenderTypes renderCommands[] =
4497 TestConfig::RENDERTYPES_NONE,
4498 TestConfig::RENDERTYPES_CLEAR,
4499 TestConfig::RENDERTYPES_DRAW,
4500 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4503 const TestConfig::CommandBufferTypes commandBuffers[] =
4505 TestConfig::COMMANDBUFFERTYPES_INLINE,
4506 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4507 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4510 const TestConfig::ImageMemory imageMemories[] =
4512 TestConfig::IMAGEMEMORY_STRICT,
4513 TestConfig::IMAGEMEMORY_LAZY,
4514 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4517 const UVec2 targetSizes[] =
4523 const UVec2 renderPositions[] =
4529 const UVec2 renderSizes[] =
4535 tcu::TestContext& testCtx = group->getTestContext();
4536 de::Random rng (1433774382u);
4538 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4540 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4541 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4542 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4544 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4546 const bool useDepthStencil = rng.getBool();
4547 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4548 vector<Attachment> attachments;
4549 vector<AttachmentReference> colorAttachmentReferences;
4551 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4553 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4554 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4555 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4556 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4558 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4559 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4560 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4562 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4563 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4565 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4566 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4569 if (useDepthStencil)
4571 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4572 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4573 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4574 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4576 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4577 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4579 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4580 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4582 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
4583 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4587 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4588 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4589 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4590 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>()));
4591 const vector<SubpassDependency> deps;
4593 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4594 const RenderPass renderPass (attachments, subpasses, deps);
4595 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4596 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4597 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4599 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind));
4603 group->addChild(attachmentCountGroup.release());
4607 template<typename T>
4608 T chooseRandom (de::Random& rng, const set<T>& values)
4610 size_t ndx = ((size_t)rng.getUint32()) % values.size();
4611 typename set<T>::const_iterator iter = values.begin();
4613 for (; ndx > 0; ndx--)
4619 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4621 const deUint32 attachmentCounts[] = { 4, 8 };
4622 const VkAttachmentLoadOp loadOps[] =
4624 VK_ATTACHMENT_LOAD_OP_LOAD,
4625 VK_ATTACHMENT_LOAD_OP_CLEAR,
4626 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4629 const VkAttachmentStoreOp storeOps[] =
4631 VK_ATTACHMENT_STORE_OP_STORE,
4632 VK_ATTACHMENT_STORE_OP_DONT_CARE
4635 const VkImageLayout initialAndFinalColorLayouts[] =
4637 VK_IMAGE_LAYOUT_GENERAL,
4638 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4639 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4640 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4641 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4644 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4646 VK_IMAGE_LAYOUT_GENERAL,
4647 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4648 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4649 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4650 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4651 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4654 const VkImageLayout subpassLayouts[] =
4656 VK_IMAGE_LAYOUT_GENERAL,
4657 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4662 // Each pass uses one more attachmen than previous one
4663 ALLOCATIONTYPE_GROW,
4664 // Each pass uses one less attachment than previous one
4665 ALLOCATIONTYPE_SHRINK,
4666 // Each pass drops one attachment and picks up new one
4667 ALLOCATIONTYPE_ROLL,
4668 // Start by growing and end by shrinking
4669 ALLOCATIONTYPE_GROW_SHRINK,
4670 // Each subpass has single input and single output attachment
4671 ALLOCATIONTYPE_IO_CHAIN,
4672 // Each subpass has multiple inputs and multiple outputs attachment
4673 ALLOCATIONTYPE_IO_GENERIC
4676 const AllocationType allocationTypes[] =
4678 ALLOCATIONTYPE_GROW,
4679 ALLOCATIONTYPE_SHRINK,
4680 ALLOCATIONTYPE_ROLL,
4681 ALLOCATIONTYPE_GROW_SHRINK,
4682 ALLOCATIONTYPE_IO_CHAIN,
4683 ALLOCATIONTYPE_IO_GENERIC
4686 const char* const allocationTypeStr[] =
4692 "input_output_chain",
4696 const TestConfig::RenderTypes renderCommands[] =
4698 TestConfig::RENDERTYPES_NONE,
4699 TestConfig::RENDERTYPES_CLEAR,
4700 TestConfig::RENDERTYPES_DRAW,
4701 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4704 const TestConfig::CommandBufferTypes commandBuffers[] =
4706 TestConfig::COMMANDBUFFERTYPES_INLINE,
4707 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4708 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4711 const TestConfig::ImageMemory imageMemories[] =
4713 TestConfig::IMAGEMEMORY_STRICT,
4714 TestConfig::IMAGEMEMORY_LAZY,
4715 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4718 const UVec2 targetSizes[] =
4724 const UVec2 renderPositions[] =
4730 const UVec2 renderSizes[] =
4736 tcu::TestContext& testCtx = group->getTestContext();
4737 de::Random rng (3700649827u);
4739 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4741 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4742 const size_t testCaseCount = 100;
4743 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4745 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4747 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
4749 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
4750 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
4751 vector<Attachment> attachments;
4753 set<deUint32> definedAttachments;
4755 vector<Subpass> subpasses;
4756 set<deUint32> colorAttachments;
4757 set<deUint32> depthStencilAttachments;
4759 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
4761 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
4762 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4763 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4764 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4766 const VkImageLayout initialLayout = isDepthStencilAttachment
4767 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4768 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4769 const VkImageLayout finalizeLayout = isDepthStencilAttachment
4770 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4771 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4773 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4774 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4776 if (isDepthStencilAttachment)
4778 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4780 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
4781 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4782 definedAttachments.insert(attachmentIndex);
4784 depthStencilAttachments.insert(attachmentIndex);
4786 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4790 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4792 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4793 definedAttachments.insert(attachmentIndex);
4795 colorAttachments.insert(attachmentIndex);
4797 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4800 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>());
4801 vector<SubpassDependency> deps;
4803 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
4805 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
4806 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
4807 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
4808 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
4809 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
4810 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
4811 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
4812 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
4813 ? just(chooseRandom(rng, depthStencilAttachments))
4814 : nothing<deUint32>());
4815 std::vector<deUint32> subpassPreserveAttachments;
4817 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
4818 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
4820 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4821 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
4823 if (depthStencilAttachment)
4824 definedAttachments.insert(*depthStencilAttachment);
4827 std::vector<AttachmentReference> inputAttachmentReferences;
4828 std::vector<AttachmentReference> colorAttachmentReferences;
4829 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
4831 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
4833 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
4834 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4835 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4837 if (lastUseOfAttachment[colorAttachmentIndex])
4839 const bool byRegion = rng.getBool();
4841 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
4842 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4843 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4844 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4845 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4847 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4848 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4849 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4850 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4852 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4853 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
4855 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4858 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
4860 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
4863 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
4865 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
4866 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
4867 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
4869 if(lastUseOfAttachment[inputAttachmentIndex])
4871 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
4873 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
4874 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4875 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4876 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4877 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4879 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4880 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4881 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4882 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4884 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4885 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4887 VK_DEPENDENCY_BY_REGION_BIT));
4891 const bool byRegion = rng.getBool();
4893 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
4894 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4895 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4896 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4897 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4899 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4900 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
4901 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
4902 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
4904 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4905 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
4907 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
4910 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
4912 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
4916 if (depthStencilAttachment)
4918 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
4919 if (lastUseOfAttachment[*depthStencilAttachment])
4921 if(*lastUseOfAttachment[*depthStencilAttachment] == 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[*depthStencilAttachment], 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));
4961 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
4962 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
4965 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
4967 vector<deUint32> preserveAttachments;
4968 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
4970 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
4971 preserveAttachments.push_back(attachmentIndex);
4974 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
4975 inputAttachmentReferences,
4976 colorAttachmentReferences,
4977 vector<AttachmentReference>(),
4978 depthStencilAttachmentReference,
4979 preserveAttachments));
4983 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4984 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4985 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4987 const string testCaseName = de::toString(testCaseNdx);
4988 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4989 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4990 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4992 const RenderPass renderPass (attachments, subpasses, deps);
4994 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
4999 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
5000 vector<Attachment> attachments;
5001 vector<Subpass> subpasses;
5003 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5005 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5006 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5007 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5008 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5010 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5011 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5013 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5014 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5016 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5019 if (allocationType == ALLOCATIONTYPE_GROW)
5021 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5023 vector<AttachmentReference> colorAttachmentReferences;
5025 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5027 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5029 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5032 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5033 vector<AttachmentReference>(),
5034 colorAttachmentReferences,
5035 vector<AttachmentReference>(),
5036 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5037 vector<deUint32>()));
5040 else if (allocationType == ALLOCATIONTYPE_SHRINK)
5042 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5044 vector<AttachmentReference> colorAttachmentReferences;
5046 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5048 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5050 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5053 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5054 vector<AttachmentReference>(),
5055 colorAttachmentReferences,
5056 vector<AttachmentReference>(),
5057 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5058 vector<deUint32>()));
5061 else if (allocationType == ALLOCATIONTYPE_ROLL)
5063 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
5065 vector<AttachmentReference> colorAttachmentReferences;
5067 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
5069 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5071 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
5074 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5075 vector<AttachmentReference>(),
5076 colorAttachmentReferences,
5077 vector<AttachmentReference>(),
5078 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5079 vector<deUint32>()));
5082 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
5084 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5086 vector<AttachmentReference> colorAttachmentReferences;
5088 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5090 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5092 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5095 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5096 vector<AttachmentReference>(),
5097 colorAttachmentReferences,
5098 vector<AttachmentReference>(),
5099 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5100 vector<deUint32>()));
5103 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5105 vector<AttachmentReference> colorAttachmentReferences;
5107 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5109 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5111 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5114 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5115 vector<AttachmentReference>(),
5116 colorAttachmentReferences,
5117 vector<AttachmentReference>(),
5118 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5119 vector<deUint32>()));
5122 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
5124 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5125 vector<AttachmentReference>(),
5126 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5127 vector<AttachmentReference>(),
5128 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5129 vector<deUint32>()));
5131 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
5133 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5134 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5135 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5136 vector<AttachmentReference>(),
5137 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5138 vector<deUint32>()));
5142 DE_FATAL("Unknown allocation type");
5145 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5146 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5147 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5149 const string testCaseName = de::toString(testCaseNdx);
5150 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5151 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5152 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5154 vector<SubpassDependency> deps;
5156 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
5158 const bool byRegion = rng.getBool();
5159 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
5160 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5161 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5162 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5163 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5165 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5166 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5167 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5168 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5170 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5171 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5173 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5176 const RenderPass renderPass (attachments, subpasses, deps);
5178 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
5182 group->addChild(allocationTypeGroup.release());
5186 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5188 const UVec2 targetSize (64, 64);
5189 const UVec2 renderPos (0, 0);
5190 const UVec2 renderSize (64, 64);
5194 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5195 VK_SAMPLE_COUNT_1_BIT,
5196 VK_ATTACHMENT_LOAD_OP_CLEAR,
5197 VK_ATTACHMENT_STORE_OP_STORE,
5198 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5199 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5200 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5201 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5202 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5204 vector<AttachmentReference>(),
5205 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5206 vector<AttachmentReference>(),
5207 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5208 vector<deUint32>())),
5209 vector<SubpassDependency>());
5211 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));
5216 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5217 VK_SAMPLE_COUNT_1_BIT,
5218 VK_ATTACHMENT_LOAD_OP_CLEAR,
5219 VK_ATTACHMENT_STORE_OP_STORE,
5220 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5221 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5222 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5223 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5224 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5226 vector<AttachmentReference>(),
5227 vector<AttachmentReference>(),
5228 vector<AttachmentReference>(),
5229 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5230 vector<deUint32>())),
5231 vector<SubpassDependency>());
5233 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));
5238 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
5239 VK_SAMPLE_COUNT_1_BIT,
5240 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5241 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5242 VK_ATTACHMENT_LOAD_OP_CLEAR,
5243 VK_ATTACHMENT_STORE_OP_STORE,
5244 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5245 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5246 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5248 vector<AttachmentReference>(),
5249 vector<AttachmentReference>(),
5250 vector<AttachmentReference>(),
5251 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5252 vector<deUint32>())),
5253 vector<SubpassDependency>());
5255 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));
5260 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5261 VK_SAMPLE_COUNT_1_BIT,
5262 VK_ATTACHMENT_LOAD_OP_CLEAR,
5263 VK_ATTACHMENT_STORE_OP_STORE,
5264 VK_ATTACHMENT_LOAD_OP_CLEAR,
5265 VK_ATTACHMENT_STORE_OP_STORE,
5266 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5267 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5268 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5270 vector<AttachmentReference>(),
5271 vector<AttachmentReference>(),
5272 vector<AttachmentReference>(),
5273 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5274 vector<deUint32>())),
5275 vector<SubpassDependency>());
5277 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));
5282 const Attachment attachments[] =
5284 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5285 VK_SAMPLE_COUNT_1_BIT,
5286 VK_ATTACHMENT_LOAD_OP_CLEAR,
5287 VK_ATTACHMENT_STORE_OP_STORE,
5288 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5289 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5290 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5291 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5292 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5293 VK_SAMPLE_COUNT_1_BIT,
5294 VK_ATTACHMENT_LOAD_OP_CLEAR,
5295 VK_ATTACHMENT_STORE_OP_STORE,
5296 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5297 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5298 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5299 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5302 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5303 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5305 vector<AttachmentReference>(),
5306 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5307 vector<AttachmentReference>(),
5308 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5309 vector<deUint32>())),
5310 vector<SubpassDependency>());
5312 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));
5317 const Attachment attachments[] =
5319 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5320 VK_SAMPLE_COUNT_1_BIT,
5321 VK_ATTACHMENT_LOAD_OP_CLEAR,
5322 VK_ATTACHMENT_STORE_OP_STORE,
5323 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5324 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5325 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5326 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5327 Attachment(VK_FORMAT_S8_UINT,
5328 VK_SAMPLE_COUNT_1_BIT,
5329 VK_ATTACHMENT_LOAD_OP_CLEAR,
5330 VK_ATTACHMENT_STORE_OP_STORE,
5331 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5332 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5333 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5334 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5337 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5338 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5340 vector<AttachmentReference>(),
5341 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5342 vector<AttachmentReference>(),
5343 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5344 vector<deUint32>())),
5345 vector<SubpassDependency>());
5348 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));
5351 // color_depth_stencil
5353 const Attachment attachments[] =
5355 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5356 VK_SAMPLE_COUNT_1_BIT,
5357 VK_ATTACHMENT_LOAD_OP_CLEAR,
5358 VK_ATTACHMENT_STORE_OP_STORE,
5359 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5360 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5361 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5362 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5363 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5364 VK_SAMPLE_COUNT_1_BIT,
5365 VK_ATTACHMENT_LOAD_OP_CLEAR,
5366 VK_ATTACHMENT_STORE_OP_STORE,
5367 VK_ATTACHMENT_LOAD_OP_CLEAR,
5368 VK_ATTACHMENT_STORE_OP_STORE,
5369 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5370 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5373 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5374 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5376 vector<AttachmentReference>(),
5377 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5378 vector<AttachmentReference>(),
5379 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5380 vector<deUint32>())),
5381 vector<SubpassDependency>());
5383 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));
5387 std::string formatToName (VkFormat format)
5389 const std::string formatStr = de::toString(format);
5390 const std::string prefix = "VK_FORMAT_";
5392 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
5394 return de::toLower(formatStr.substr(prefix.length()));
5397 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5399 tcu::TestContext& testCtx = group->getTestContext();
5401 const UVec2 targetSize (64, 64);
5402 const UVec2 renderPos (0, 0);
5403 const UVec2 renderSize (64, 64);
5407 const char* const str;
5408 const VkAttachmentStoreOp op;
5411 { "store", VK_ATTACHMENT_STORE_OP_STORE },
5412 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
5417 const char* const str;
5418 const VkAttachmentLoadOp op;
5421 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
5422 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
5423 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
5428 const char* const str;
5429 const TestConfig::RenderTypes types;
5432 { "clear", TestConfig::RENDERTYPES_CLEAR },
5433 { "draw", TestConfig::RENDERTYPES_DRAW },
5434 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
5438 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
5440 const VkFormat format = s_coreColorFormats[formatNdx];
5441 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
5443 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5445 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5446 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5448 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5450 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
5451 VK_SAMPLE_COUNT_1_BIT,
5453 VK_ATTACHMENT_STORE_OP_STORE,
5454 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5455 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5456 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5457 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5458 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5460 vector<AttachmentReference>(),
5461 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5462 vector<AttachmentReference>(),
5463 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5464 vector<deUint32>())),
5465 vector<SubpassDependency>());
5467 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));
5470 formatGroup->addChild(loadOpGroup.release());
5474 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5476 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5478 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5479 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5481 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5483 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5484 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5486 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5489 vector<Attachment> attachments;
5490 vector<Subpass> subpasses;
5491 vector<SubpassDependency> deps;
5493 attachments.push_back(Attachment(format,
5494 VK_SAMPLE_COUNT_1_BIT,
5497 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5498 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5499 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5500 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5502 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5503 VK_SAMPLE_COUNT_1_BIT,
5504 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5505 VK_ATTACHMENT_STORE_OP_STORE,
5506 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5507 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5508 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5509 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5511 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5513 vector<AttachmentReference>(),
5514 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5515 vector<AttachmentReference>(),
5516 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5517 vector<deUint32>()));
5518 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5520 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5521 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5522 vector<AttachmentReference>(),
5523 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5524 vector<deUint32>()));
5526 deps.push_back(SubpassDependency(0, 1,
5528 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5529 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5531 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5532 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5533 vk::VK_DEPENDENCY_BY_REGION_BIT));
5536 const RenderPass renderPass (attachments, subpasses, deps);
5538 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5542 vector<Attachment> attachments;
5543 vector<Subpass> subpasses;
5544 vector<SubpassDependency> deps;
5546 attachments.push_back(Attachment(format,
5547 VK_SAMPLE_COUNT_1_BIT,
5550 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5551 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5552 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5553 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5555 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5557 vector<AttachmentReference>(),
5558 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5559 vector<AttachmentReference>(),
5560 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5561 vector<deUint32>()));
5562 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5564 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5565 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5566 vector<AttachmentReference>(),
5567 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5568 vector<deUint32>()));
5570 deps.push_back(SubpassDependency(0, 1,
5571 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5572 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5574 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5575 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5576 vk::VK_DEPENDENCY_BY_REGION_BIT));
5579 const RenderPass renderPass (attachments, subpasses, deps);
5581 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5586 loadOpGroup->addChild(storeOpGroup.release());
5589 inputGroup->addChild(loadOpGroup.release());
5592 formatGroup->addChild(inputGroup.release());
5595 group->addChild(formatGroup.release());
5598 // Depth stencil formats
5599 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
5601 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
5602 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
5604 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5606 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5607 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5609 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5611 const tcu::TextureFormat format = mapVkFormat(vkFormat);
5612 const bool isStencilAttachment = hasStencilComponent(format.order);
5613 const bool isDepthAttachment = hasDepthComponent(format.order);
5614 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5615 VK_SAMPLE_COUNT_1_BIT,
5616 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5617 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5618 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5619 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5620 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5621 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5622 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5624 vector<AttachmentReference>(),
5625 vector<AttachmentReference>(),
5626 vector<AttachmentReference>(),
5627 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5628 vector<deUint32>())),
5629 vector<SubpassDependency>());
5631 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));
5634 formatGroup->addChild(loadOpGroup.release());
5638 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5640 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5642 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5643 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5645 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5647 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5648 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5650 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5653 vector<Attachment> attachments;
5654 vector<Subpass> subpasses;
5655 vector<SubpassDependency> deps;
5657 attachments.push_back(Attachment(vkFormat,
5658 VK_SAMPLE_COUNT_1_BIT,
5661 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5662 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5663 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5664 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5666 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5667 VK_SAMPLE_COUNT_1_BIT,
5668 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5669 VK_ATTACHMENT_STORE_OP_STORE,
5670 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5671 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5672 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5673 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5675 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5677 vector<AttachmentReference>(),
5678 vector<AttachmentReference>(),
5679 vector<AttachmentReference>(),
5680 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5681 vector<deUint32>()));
5682 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5684 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5685 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5686 vector<AttachmentReference>(),
5687 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5688 vector<deUint32>()));
5690 deps.push_back(SubpassDependency(0, 1,
5691 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5692 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5694 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5695 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5698 deps.push_back(SubpassDependency(1, 1,
5699 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5700 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5702 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5703 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5704 vk::VK_DEPENDENCY_BY_REGION_BIT));
5706 const RenderPass renderPass (attachments, subpasses, deps);
5708 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5712 vector<Attachment> attachments;
5713 vector<Subpass> subpasses;
5714 vector<SubpassDependency> deps;
5716 attachments.push_back(Attachment(vkFormat,
5717 VK_SAMPLE_COUNT_1_BIT,
5720 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5721 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5722 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5723 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5725 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5727 vector<AttachmentReference>(),
5728 vector<AttachmentReference>(),
5729 vector<AttachmentReference>(),
5730 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5731 vector<deUint32>()));
5732 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5734 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5735 vector<AttachmentReference>(),
5736 vector<AttachmentReference>(),
5737 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
5738 vector<deUint32>()));
5740 deps.push_back(SubpassDependency(0, 1,
5741 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5742 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5744 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5745 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5746 vk::VK_DEPENDENCY_BY_REGION_BIT));
5749 const RenderPass renderPass (attachments, subpasses, deps);
5751 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5756 loadOpGroup->addChild(storeOpGroup.release());
5759 inputGroup->addChild(loadOpGroup.release());
5762 formatGroup->addChild(inputGroup.release());
5765 group->addChild(formatGroup.release());
5769 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5771 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind);
5772 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind);
5773 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind);
5774 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind);
5777 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx)
5779 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
5781 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED);
5783 return suballocationTestsGroup;
5786 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx)
5788 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
5790 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED);
5792 return dedicatedAllocationTestsGroup;
5797 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
5799 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
5800 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx);
5801 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx);
5803 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
5804 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx));
5806 renderpassTests->addChild(suballocationTestGroup.release());
5807 renderpassTests->addChild(dedicatedAllocationTestGroup.release());
5809 renderpassTests->addChild(createRenderPassMultisampleTests(testCtx));
5810 renderpassTests->addChild(createRenderPassMultisampleResolveTests(testCtx));
5812 return renderpassTests.release();