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"
25 #include "vktRenderPassTestsUtil.hpp"
27 #include "vktRenderPassMultisampleTests.hpp"
28 #include "vktRenderPassMultisampleResolveTests.hpp"
29 #include "vktRenderPassSampleReadTests.hpp"
30 #include "vktRenderPassSparseRenderTargetTests.hpp"
31 #include "vktRenderPassSubpassDependencyTests.hpp"
32 #include "vktRenderPassUnusedAttachmentTests.hpp"
33 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
34 #include "vktRenderPassDepthStencilResolveTests.hpp"
35 #include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
36 #include "vktRenderPassFragmentDensityMapTests.hpp"
37 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
39 #include "vktTestCaseUtil.hpp"
40 #include "vktTestGroupUtil.hpp"
43 #include "vkDeviceUtil.hpp"
44 #include "vkImageUtil.hpp"
45 #include "vkMemUtil.hpp"
46 #include "vkPlatform.hpp"
47 #include "vkPrograms.hpp"
48 #include "vkQueryUtil.hpp"
50 #include "vkRefUtil.hpp"
51 #include "vkStrUtil.hpp"
52 #include "vkTypeUtil.hpp"
53 #include "vkCmdUtil.hpp"
54 #include "vkObjUtil.hpp"
56 #include "tcuFloat.hpp"
57 #include "tcuFormatUtil.hpp"
58 #include "tcuMaybe.hpp"
59 #include "tcuResultCollector.hpp"
60 #include "tcuTestLog.hpp"
61 #include "tcuTextureUtil.hpp"
62 #include "tcuVectorUtil.hpp"
64 #include "deRandom.hpp"
65 #include "deSTLUtil.hpp"
66 #include "deSharedPtr.hpp"
67 #include "deStringUtil.hpp"
68 #include "deUniquePtr.hpp"
90 using tcu::ConstPixelBufferAccess;
91 using tcu::PixelBufferAccess;
106 using namespace renderpass;
108 typedef vector<deUint8> DepthValuesArray;
110 static const deUint8 DEPTH_VALUES[] = { 0u, 255u, 1u };
114 ALLOCATION_KIND_SUBALLOCATED,
115 ALLOCATION_KIND_DEDICATED,
118 struct TestConfigExternal
120 TestConfigExternal (AllocationKind allocationKind_,
121 RenderPassType renderPassType_)
122 : allocationKind (allocationKind_)
123 , renderPassType (renderPassType_)
127 AllocationKind allocationKind;
128 RenderPassType renderPassType;
131 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
132 const DeviceInterface& vkd,
133 const VkPhysicalDevice& physDevice,
134 const VkDevice device,
135 const VkBuffer& buffer,
136 const MemoryRequirement requirement,
137 Allocator& allocator,
138 AllocationKind allocationKind)
140 switch (allocationKind)
142 case ALLOCATION_KIND_SUBALLOCATED:
144 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
146 return allocator.allocate(memoryRequirements, requirement);
149 case ALLOCATION_KIND_DEDICATED:
151 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
156 TCU_THROW(InternalError, "Invalid allocation kind");
161 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
162 const DeviceInterface& vkd,
163 const VkPhysicalDevice& physDevice,
164 const VkDevice device,
165 const VkImage& image,
166 const MemoryRequirement requirement,
167 Allocator& allocator,
168 AllocationKind allocationKind)
170 switch (allocationKind)
172 case ALLOCATION_KIND_SUBALLOCATED:
174 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
176 return allocator.allocate(memoryRequirements, requirement);
179 case ALLOCATION_KIND_DEDICATED:
181 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
186 TCU_THROW(InternalError, "Invalid allocation kind");
199 const char* boolOpToString (BoolOp op)
216 DE_FATAL("Unknown boolean operation.");
221 bool performBoolOp (BoolOp op, bool a, bool b)
238 DE_FATAL("Unknown boolean operation.");
243 BoolOp boolOpFromIndex (size_t index)
253 return ops[index % DE_LENGTH_OF_ARRAY(ops)];
256 static float requiredDepthEpsilon(VkFormat format)
258 // Possible precision loss in the unorm depth pipeline means that we need to check depths
259 // that go in and back out of the depth buffer with an epsilon rather than an exact match
260 deUint32 unormBits = 0;
264 case VK_FORMAT_D16_UNORM:
267 case VK_FORMAT_X8_D24_UNORM_PACK32:
268 case VK_FORMAT_D24_UNORM_S8_UINT:
271 case VK_FORMAT_D32_SFLOAT:
272 case VK_FORMAT_D32_SFLOAT_S8_UINT:
279 return 1.0f / (float)((1 << unormBits) - 1);
281 return 0.0f; // Require exact match
284 static bool depthsEqual(float a, float b, float epsilon)
286 return fabs(a - b) <= epsilon;
289 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
291 VkFramebufferCreateFlags pCreateInfo_flags,
292 VkRenderPass pCreateInfo_renderPass,
293 deUint32 pCreateInfo_attachmentCount,
294 const VkImageView* pCreateInfo_pAttachments,
295 deUint32 pCreateInfo_width,
296 deUint32 pCreateInfo_height,
297 deUint32 pCreateInfo_layers)
299 const VkFramebufferCreateInfo pCreateInfo =
301 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
304 pCreateInfo_renderPass,
305 pCreateInfo_attachmentCount,
306 pCreateInfo_pAttachments,
311 return createFramebuffer(vk, device, &pCreateInfo);
314 Move<VkImage> createImage (const DeviceInterface& vk,
316 VkImageCreateFlags pCreateInfo_flags,
317 VkImageType pCreateInfo_imageType,
318 VkFormat pCreateInfo_format,
319 VkExtent3D pCreateInfo_extent,
320 deUint32 pCreateInfo_mipLevels,
321 deUint32 pCreateInfo_arrayLayers,
322 VkSampleCountFlagBits pCreateInfo_samples,
323 VkImageTiling pCreateInfo_tiling,
324 VkImageUsageFlags pCreateInfo_usage,
325 VkSharingMode pCreateInfo_sharingMode,
326 deUint32 pCreateInfo_queueFamilyCount,
327 const deUint32* pCreateInfo_pQueueFamilyIndices,
328 VkImageLayout pCreateInfo_initialLayout)
330 const VkImageCreateInfo pCreateInfo =
332 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
335 pCreateInfo_imageType,
338 pCreateInfo_mipLevels,
339 pCreateInfo_arrayLayers,
343 pCreateInfo_sharingMode,
344 pCreateInfo_queueFamilyCount,
345 pCreateInfo_pQueueFamilyIndices,
346 pCreateInfo_initialLayout
348 return createImage(vk, device, &pCreateInfo);
351 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
353 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
356 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
358 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
361 Move<VkImageView> createImageView (const DeviceInterface& vk,
363 VkImageViewCreateFlags pCreateInfo_flags,
364 VkImage pCreateInfo_image,
365 VkImageViewType pCreateInfo_viewType,
366 VkFormat pCreateInfo_format,
367 VkComponentMapping pCreateInfo_components,
368 VkImageSubresourceRange pCreateInfo_subresourceRange)
370 const VkImageViewCreateInfo pCreateInfo =
372 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
376 pCreateInfo_viewType,
378 pCreateInfo_components,
379 pCreateInfo_subresourceRange,
381 return createImageView(vk, device, &pCreateInfo);
384 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
386 VkBufferCreateFlags pCreateInfo_flags,
387 VkDeviceSize pCreateInfo_size,
388 VkBufferUsageFlags pCreateInfo_usage,
389 VkSharingMode pCreateInfo_sharingMode,
390 deUint32 pCreateInfo_queueFamilyCount,
391 const deUint32* pCreateInfo_pQueueFamilyIndices)
393 const VkBufferCreateInfo pCreateInfo =
395 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
400 pCreateInfo_sharingMode,
401 pCreateInfo_queueFamilyCount,
402 pCreateInfo_pQueueFamilyIndices,
404 return createBuffer(vk, device, &pCreateInfo);
407 VkRenderPassBeginInfo createRenderPassBeginInfo (VkRenderPass pRenderPassBegin_renderPass,
408 VkFramebuffer pRenderPassBegin_framebuffer,
409 VkRect2D pRenderPassBegin_renderArea,
410 deUint32 pRenderPassBegin_clearValueCount,
411 const VkClearValue* pRenderPassBegin_pAttachmentClearValues)
413 const VkRenderPassBeginInfo renderPassBeginInfo =
415 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
417 pRenderPassBegin_renderPass,
418 pRenderPassBegin_framebuffer,
419 pRenderPassBegin_renderArea,
420 pRenderPassBegin_clearValueCount,
421 pRenderPassBegin_pAttachmentClearValues,
424 return renderPassBeginInfo;
427 void beginCommandBuffer (const DeviceInterface& vk,
428 VkCommandBuffer cmdBuffer,
429 VkCommandBufferUsageFlags pBeginInfo_flags,
430 VkRenderPass pInheritanceInfo_renderPass,
431 deUint32 pInheritanceInfo_subpass,
432 VkFramebuffer pInheritanceInfo_framebuffer,
433 VkBool32 pInheritanceInfo_occlusionQueryEnable,
434 VkQueryControlFlags pInheritanceInfo_queryFlags,
435 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
437 const VkCommandBufferInheritanceInfo pInheritanceInfo =
439 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
441 pInheritanceInfo_renderPass,
442 pInheritanceInfo_subpass,
443 pInheritanceInfo_framebuffer,
444 pInheritanceInfo_occlusionQueryEnable,
445 pInheritanceInfo_queryFlags,
446 pInheritanceInfo_pipelineStatistics,
448 const VkCommandBufferBeginInfo pBeginInfo =
450 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
455 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
458 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
460 const VkSubmitInfo submitInfo =
462 VK_STRUCTURE_TYPE_SUBMIT_INFO,
464 0u, // waitSemaphoreCount
465 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
466 (const VkPipelineStageFlags*)DE_NULL,
467 cmdBufferCount, // commandBufferCount
469 0u, // signalSemaphoreCount
470 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
472 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
475 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
477 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
480 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
482 const tcu::TextureFormat format = mapVkFormat(vkFormat);
484 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
486 switch (format.order)
488 case tcu::TextureFormat::DS:
489 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
491 case tcu::TextureFormat::D:
492 return VK_IMAGE_ASPECT_DEPTH_BIT;
494 case tcu::TextureFormat::S:
495 return VK_IMAGE_ASPECT_STENCIL_BIT;
498 return VK_IMAGE_ASPECT_COLOR_BIT;
502 VkAccessFlags getAllMemoryReadFlags (void)
504 return VK_ACCESS_TRANSFER_READ_BIT
505 | VK_ACCESS_UNIFORM_READ_BIT
506 | VK_ACCESS_HOST_READ_BIT
507 | VK_ACCESS_INDEX_READ_BIT
508 | VK_ACCESS_SHADER_READ_BIT
509 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
510 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
511 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
512 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
513 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
516 VkAccessFlags getAllMemoryWriteFlags (void)
518 return VK_ACCESS_TRANSFER_WRITE_BIT
519 | VK_ACCESS_HOST_WRITE_BIT
520 | VK_ACCESS_SHADER_WRITE_BIT
521 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
522 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
525 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
529 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
530 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
531 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
532 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
533 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT;
534 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT;
535 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT;
536 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
537 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
539 return (VkAccessFlags)0;
543 VkPipelineStageFlags getAllPipelineStageFlags (void)
545 /* All relevant flags for a pipeline containing VS+PS. */
546 return VK_PIPELINE_STAGE_TRANSFER_BIT
547 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
548 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
549 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
550 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
551 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
552 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
553 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
554 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
555 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
556 | VK_PIPELINE_STAGE_HOST_BIT;
559 class AttachmentReference
562 AttachmentReference (deUint32 attachment,
563 VkImageLayout layout,
564 VkImageAspectFlags aspectMask = static_cast<VkImageAspectFlags>(0u))
565 : m_attachment (attachment)
567 , m_aspectMask (aspectMask)
571 deUint32 getAttachment (void) const { return m_attachment; }
572 VkImageLayout getImageLayout (void) const { return m_layout; }
573 VkImageAspectFlags getAspectMask (void) const { return m_aspectMask; }
574 void setImageLayout (VkImageLayout layout) { m_layout = layout; }
577 deUint32 m_attachment;
578 VkImageLayout m_layout;
579 VkImageAspectFlags m_aspectMask;
585 Subpass (VkPipelineBindPoint pipelineBindPoint,
586 VkSubpassDescriptionFlags flags,
587 const vector<AttachmentReference>& inputAttachments,
588 const vector<AttachmentReference>& colorAttachments,
589 const vector<AttachmentReference>& resolveAttachments,
590 AttachmentReference depthStencilAttachment,
591 const vector<deUint32>& preserveAttachments,
592 bool omitBlendState = false)
593 : m_pipelineBindPoint (pipelineBindPoint)
595 , m_inputAttachments (inputAttachments)
596 , m_colorAttachments (colorAttachments)
597 , m_resolveAttachments (resolveAttachments)
598 , m_depthStencilAttachment (depthStencilAttachment)
599 , m_preserveAttachments (preserveAttachments)
600 , m_omitBlendState (omitBlendState)
604 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
605 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
606 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
607 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
608 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
609 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
610 const vector<deUint32>& getPreserveAttachments (void) const { return m_preserveAttachments; }
611 bool getOmitBlendState (void) const { return m_omitBlendState; }
614 VkPipelineBindPoint m_pipelineBindPoint;
615 VkSubpassDescriptionFlags m_flags;
617 vector<AttachmentReference> m_inputAttachments;
618 vector<AttachmentReference> m_colorAttachments;
619 vector<AttachmentReference> m_resolveAttachments;
620 AttachmentReference m_depthStencilAttachment;
622 vector<deUint32> m_preserveAttachments;
623 bool m_omitBlendState;
626 class SubpassDependency
629 SubpassDependency (deUint32 srcPass,
632 VkPipelineStageFlags srcStageMask,
633 VkPipelineStageFlags dstStageMask,
635 VkAccessFlags srcAccessMask,
636 VkAccessFlags dstAccessMask,
638 VkDependencyFlags flags)
639 : m_srcPass (srcPass)
640 , m_dstPass (dstPass)
642 , m_srcStageMask (srcStageMask)
643 , m_dstStageMask (dstStageMask)
645 , m_srcAccessMask (srcAccessMask)
646 , m_dstAccessMask (dstAccessMask)
651 deUint32 getSrcPass (void) const { return m_srcPass; }
652 deUint32 getDstPass (void) const { return m_dstPass; }
654 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
655 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
657 VkAccessFlags getSrcAccessMask (void) const { return m_srcAccessMask; }
658 VkAccessFlags getDstAccessMask (void) const { return m_dstAccessMask; }
660 VkDependencyFlags getFlags (void) const { return m_flags; }
662 void setSrcAccessMask (const VkAccessFlags& flags) { m_srcAccessMask = flags; }
663 void setDstAccessMask (const VkAccessFlags& flags) { m_dstAccessMask = flags; }
669 VkPipelineStageFlags m_srcStageMask;
670 VkPipelineStageFlags m_dstStageMask;
672 VkAccessFlags m_srcAccessMask;
673 VkAccessFlags m_dstAccessMask;
674 VkDependencyFlags m_flags;
680 Attachment (VkFormat format,
681 VkSampleCountFlagBits samples,
683 VkAttachmentLoadOp loadOp,
684 VkAttachmentStoreOp storeOp,
686 VkAttachmentLoadOp stencilLoadOp,
687 VkAttachmentStoreOp stencilStoreOp,
689 VkImageLayout initialLayout,
690 VkImageLayout finalLayout)
692 , m_samples (samples)
695 , m_storeOp (storeOp)
697 , m_stencilLoadOp (stencilLoadOp)
698 , m_stencilStoreOp (stencilStoreOp)
700 , m_initialLayout (initialLayout)
701 , m_finalLayout (finalLayout)
705 VkFormat getFormat (void) const { return m_format; }
706 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
708 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
709 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
712 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
713 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
715 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
716 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
720 VkSampleCountFlagBits m_samples;
722 VkAttachmentLoadOp m_loadOp;
723 VkAttachmentStoreOp m_storeOp;
725 VkAttachmentLoadOp m_stencilLoadOp;
726 VkAttachmentStoreOp m_stencilStoreOp;
728 VkImageLayout m_initialLayout;
729 VkImageLayout m_finalLayout;
735 RenderPass (const vector<Attachment>& attachments,
736 const vector<Subpass>& subpasses,
737 const vector<SubpassDependency>& dependencies,
738 const vector<VkInputAttachmentAspectReference> inputAspects = vector<VkInputAttachmentAspectReference>())
739 : m_attachments (attachments)
740 , m_subpasses (subpasses)
741 , m_dependencies (dependencies)
742 , m_inputAspects (inputAspects)
746 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
747 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
748 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
749 const vector<VkInputAttachmentAspectReference>& getInputAspects (void) const { return m_inputAspects; }
752 const vector<Attachment> m_attachments;
753 const vector<Subpass> m_subpasses;
754 const vector<SubpassDependency> m_dependencies;
755 const vector<VkInputAttachmentAspectReference> m_inputAspects;
762 RENDERTYPES_NONE = 0,
763 RENDERTYPES_CLEAR = (1<<1),
764 RENDERTYPES_DRAW = (1<<2)
767 enum CommandBufferTypes
769 COMMANDBUFFERTYPES_INLINE = (1<<0),
770 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
775 IMAGEMEMORY_STRICT = (1<<0),
776 IMAGEMEMORY_LAZY = (1<<1)
779 TestConfig (const RenderPass& renderPass_,
780 RenderTypes renderTypes_,
781 CommandBufferTypes commandBufferTypes_,
782 ImageMemory imageMemory_,
783 const UVec2& targetSize_,
784 const UVec2& renderPos_,
785 const UVec2& renderSize_,
786 deBool useFormatCompCount_,
788 deUint32 drawStartNdx_,
789 AllocationKind allocationKind_,
790 RenderPassType renderPassType_,
791 vector<DeviceCoreFeature> requiredFeatures_ = vector<DeviceCoreFeature>())
792 : renderPass (renderPass_)
793 , renderTypes (renderTypes_)
794 , commandBufferTypes (commandBufferTypes_)
795 , imageMemory (imageMemory_)
796 , targetSize (targetSize_)
797 , renderPos (renderPos_)
798 , renderSize (renderSize_)
799 , useFormatCompCount (useFormatCompCount_)
801 , drawStartNdx (drawStartNdx_)
802 , allocationKind (allocationKind_)
803 , renderPassType (renderPassType_)
804 , requiredFeatures (requiredFeatures_)
806 DepthValuesArray shuffledDepthValues (&DEPTH_VALUES[0], &DEPTH_VALUES[DE_LENGTH_OF_ARRAY(DEPTH_VALUES)]);
807 de::Random rng (seed + 1);
809 rng.shuffle(shuffledDepthValues.begin(), shuffledDepthValues.end());
811 depthValues.push_back(shuffledDepthValues[0]);
812 depthValues.push_back(shuffledDepthValues[1]);
815 RenderPass renderPass;
816 RenderTypes renderTypes;
817 CommandBufferTypes commandBufferTypes;
818 ImageMemory imageMemory;
822 deBool useFormatCompCount;
824 deUint32 drawStartNdx;
825 AllocationKind allocationKind;
826 RenderPassType renderPassType;
827 vector<DeviceCoreFeature> requiredFeatures;
828 DepthValuesArray depthValues;
831 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
833 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
836 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
838 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
841 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
843 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
846 void checkSupport (Context& context, TestConfig config)
848 for (size_t featureNdx = 0; featureNdx < config.requiredFeatures.size(); featureNdx++)
849 context.requireDeviceCoreFeature(config.requiredFeatures[featureNdx]);
852 void logRenderPassInfo (TestLog& log,
853 const RenderPass& renderPass)
855 const bool useExternalInputAspect = !renderPass.getInputAspects().empty();
856 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
859 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
860 const vector<Attachment>& attachments = renderPass.getAttachments();
862 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
864 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
865 const Attachment& attachment = attachments[attachmentNdx];
867 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
868 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
870 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
871 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
873 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
874 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
876 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
877 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
881 if (useExternalInputAspect)
883 const tcu::ScopedLogSection inputAspectSection (log, "InputAspects", "InputAspects");
885 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
887 const VkInputAttachmentAspectReference& inputAspect (renderPass.getInputAspects()[aspectNdx]);
889 log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
890 log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex << TestLog::EndMessage;
891 log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask) << TestLog::EndMessage;
896 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
897 const vector<Subpass>& subpasses = renderPass.getSubpasses();
899 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
901 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
902 const Subpass& subpass = subpasses[subpassNdx];
904 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
905 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
906 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
907 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments();
909 if (!inputAttachments.empty())
911 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
913 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
915 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
916 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
918 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
919 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
920 if (!useExternalInputAspect)
921 log << TestLog::Message << "AspectMask: " << inputAttachment.getAspectMask() << TestLog::EndMessage;
925 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
927 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
928 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
930 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
931 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
934 if (!colorAttachments.empty())
936 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
938 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
940 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
941 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
943 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
944 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
948 if (!resolveAttachments.empty())
950 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
952 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
954 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
955 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
957 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
958 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
962 if (!preserveAttachments.empty())
964 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
966 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
968 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
969 const deUint32 preserveAttachment = preserveAttachments[preserveNdx];
971 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
978 if (!renderPass.getDependencies().empty())
980 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
982 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
984 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
985 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
987 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
988 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
990 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
991 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
993 log << TestLog::Message << "Input Mask: " << dep.getDstAccessMask() << TestLog::EndMessage;
994 log << TestLog::Message << "Output Mask: " << dep.getSrcAccessMask() << TestLog::EndMessage;
995 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
1000 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value, deBool useFormatCompCount)
1002 const tcu::TextureFormat format = mapVkFormat(vkFormat);
1003 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
1004 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
1005 const deUint32 componentCount = (useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(format.order) : 4);
1007 std::ostringstream stream;
1011 switch (channelClass)
1013 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1014 for (deUint32 i = 0; i < componentCount; i++)
1020 stream << value.int32[i];
1026 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1027 for (deUint32 i = 0; i < componentCount; i++)
1033 stream << value.uint32[i];
1039 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1040 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1041 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1042 for (deUint32 i = 0; i < componentCount; i++)
1048 stream << value.float32[i];
1055 DE_FATAL("Unknown channel class");
1060 return stream.str();
1063 std::string clearValueToString (VkFormat vkFormat, VkClearValue value, deBool useFormatCompCount)
1065 const tcu::TextureFormat format = mapVkFormat(vkFormat);
1067 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1069 std::ostringstream stream;
1073 if (tcu::hasStencilComponent(format.order))
1074 stream << "stencil: " << value.depthStencil.stencil;
1076 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
1079 if (tcu::hasDepthComponent(format.order))
1080 stream << "depth: " << value.depthStencil.depth;
1084 return stream.str();
1087 return clearColorToString(vkFormat, value.color, useFormatCompCount);
1090 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng, deBool useFormatCompCount)
1092 const float clearNan = tcu::Float32::nan().asFloat();
1093 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1094 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
1095 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
1096 const deUint32 componentCount = (useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(format.order) : 4);
1097 VkClearColorValue clearColor;
1099 switch (channelClass)
1101 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1103 for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1105 if (!channelMask[ndx])
1106 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
1108 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1113 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1115 for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1117 if (!channelMask[ndx])
1118 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
1120 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1125 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1126 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1127 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1129 for (deUint32 ndx = 0; ndx < componentCount; ndx++)
1131 if (!channelMask[ndx])
1132 clearColor.float32[ndx] = clearNan;
1134 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1140 DE_FATAL("Unknown channel class");
1146 template <typename AttachmentDesc>
1147 AttachmentDesc createAttachmentDescription (const Attachment& attachment)
1149 const AttachmentDesc attachmentDescription // VkAttachmentDescription || VkAttachmentDescription2KHR
1151 // || VkStructureType sType;
1152 DE_NULL, // || const void* pNext;
1153 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
1154 attachment.getFormat(), // VkFormat format; || VkFormat format;
1155 attachment.getSamples(), // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
1156 attachment.getLoadOp(), // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
1157 attachment.getStoreOp(), // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
1158 attachment.getStencilLoadOp(), // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
1159 attachment.getStencilStoreOp(), // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
1160 attachment.getInitialLayout(), // VkImageLayout initialLayout; || VkImageLayout initialLayout;
1161 attachment.getFinalLayout() // VkImageLayout finalLayout; || VkImageLayout finalLayout;
1164 return attachmentDescription;
1167 template <typename AttachmentRef>
1168 AttachmentRef createAttachmentReference (const AttachmentReference& referenceInfo)
1170 const AttachmentRef reference // VkAttachmentReference || VkAttachmentReference2KHR
1172 // || VkStructureType sType;
1173 DE_NULL, // || const void* pNext;
1174 referenceInfo.getAttachment(), // deUint32 attachment; || deUint32 attachment;
1175 referenceInfo.getImageLayout(), // VkImageLayout layout; || VkImageLayout layout;
1176 referenceInfo.getAspectMask() // || VkImageAspectFlags aspectMask;
1182 template <typename SubpassDesc, typename AttachmentRef>
1183 SubpassDesc createSubpassDescription (const Subpass& subpass,
1184 vector<AttachmentRef>* attachmentReferenceLists,
1185 vector<deUint32>* preserveAttachmentReferences)
1187 vector<AttachmentRef>& inputAttachmentReferences = attachmentReferenceLists[0];
1188 vector<AttachmentRef>& colorAttachmentReferences = attachmentReferenceLists[1];
1189 vector<AttachmentRef>& resolveAttachmentReferences = attachmentReferenceLists[2];
1190 vector<AttachmentRef>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
1192 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1193 colorAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getColorAttachments()[attachmentNdx]));
1195 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1196 inputAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getInputAttachments()[attachmentNdx]));
1198 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1199 resolveAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getResolveAttachments()[attachmentNdx]));
1201 depthStencilAttachmentReferences.push_back(createAttachmentReference<AttachmentRef>(subpass.getDepthStencilAttachment()));
1203 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1204 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1206 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1209 const SubpassDesc subpassDescription // VkSubpassDescription || VkSubpassDescription2KHR
1211 // || VkStructureType sType;
1212 DE_NULL, // || const void* pNext;
1213 subpass.getFlags(), // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
1214 subpass.getPipelineBindPoint(), // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
1215 0u, // || deUint32 viewMask;
1216 (deUint32)inputAttachmentReferences.size(), // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
1217 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
1218 (deUint32)colorAttachmentReferences.size(), // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
1219 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
1220 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
1221 &depthStencilAttachmentReferences[0], // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
1222 (deUint32)preserveAttachmentReferences->size(), // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
1223 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
1226 return subpassDescription;
1230 template <typename SubpassDep>
1231 SubpassDep createSubpassDependency (const SubpassDependency& dependencyInfo)
1233 const SubpassDep dependency // VkSubpassDependency || VkSubpassDependency2KHR
1235 // || VkStructureType sType;
1236 DE_NULL, // || const void* pNext;
1237 dependencyInfo.getSrcPass(), // deUint32 srcSubpass; || deUint32 srcSubpass;
1238 dependencyInfo.getDstPass(), // deUint32 dstSubpass; || deUint32 dstSubpass;
1239 dependencyInfo.getSrcStageMask(), // VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
1240 dependencyInfo.getDstStageMask(), // VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
1241 dependencyInfo.getSrcAccessMask(), // VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
1242 dependencyInfo.getDstAccessMask(), // VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
1243 dependencyInfo.getFlags(), // VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
1244 0u // || deInt32 viewOffset;
1250 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> createRenderPassInputAttachmentAspectCreateInfo(const RenderPass& renderPassInfo)
1252 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> result (DE_NULL);
1254 if (!renderPassInfo.getInputAspects().empty())
1256 const VkRenderPassInputAttachmentAspectCreateInfo inputAspectCreateInfo =
1258 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
1261 (deUint32)renderPassInfo.getInputAspects().size(),
1262 renderPassInfo.getInputAspects().data(),
1265 result = de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>(new VkRenderPassInputAttachmentAspectCreateInfo(inputAspectCreateInfo));
1271 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
1272 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1274 const RenderPass& renderPassInfo)
1276 const size_t perSubpassAttachmentReferenceLists = 4;
1277 vector<AttachmentDesc> attachments;
1278 vector<SubpassDesc> subpasses;
1279 vector<SubpassDep> dependencies;
1280 vector<vector<AttachmentRef> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1281 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1282 de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> inputAspectCreateInfo(createRenderPassInputAttachmentAspectCreateInfo(renderPassInfo));
1284 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1285 attachments.push_back(createAttachmentDescription<AttachmentDesc>(renderPassInfo.getAttachments()[attachmentNdx]));
1287 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1288 subpasses.push_back(createSubpassDescription<SubpassDesc>(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1290 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1291 dependencies.push_back(createSubpassDependency<SubpassDep>(renderPassInfo.getDependencies()[depNdx]));
1293 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
1295 // VkStructureType sType; || VkStructureType sType;
1296 inputAspectCreateInfo.get(), // const void* pNext; || const void* pNext;
1297 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
1298 (deUint32)attachments.size(), // deUint32 attachmentCount; || deUint32 attachmentCount;
1299 (attachments.empty() ? DE_NULL : &attachments[0]), // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
1300 (deUint32)subpasses.size(), // deUint32 subpassCount; || deUint32 subpassCount;
1301 (subpasses.empty() ? DE_NULL : &subpasses[0]), // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
1302 (deUint32)dependencies.size(), // deUint32 dependencyCount; || deUint32 dependencyCount;
1303 (dependencies.empty() ? DE_NULL : &dependencies[0]), // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
1304 0u, // || deUint32 correlatedViewMaskCount;
1305 DE_NULL // || const deUint32* pCorrelatedViewMasks;
1308 return renderPassCreator.createRenderPass(vk, device);
1311 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1313 const RenderPass& renderPassInfo,
1314 const RenderPassType renderPassType)
1316 switch (renderPassType)
1318 case RENDERPASS_TYPE_LEGACY:
1319 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, renderPassInfo);
1320 case RENDERPASS_TYPE_RENDERPASS2:
1321 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, renderPassInfo);
1323 TCU_THROW(InternalError, "Impossible");
1327 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1329 VkRenderPass renderPass,
1331 const vector<VkImageView>& attachments)
1333 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1336 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1338 deUint32 queueIndex,
1341 VkSampleCountFlagBits samples,
1342 VkImageUsageFlags usageFlags,
1343 VkImageLayout layout)
1345 VkImageUsageFlags targetUsageFlags = 0;
1346 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1348 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1349 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1351 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1352 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1354 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1355 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1357 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1359 return createImage(vk, device,
1360 (VkImageCreateFlags)0,
1363 vk::makeExtent3D(size.x(), size.y(), 1u),
1367 VK_IMAGE_TILING_OPTIMAL,
1368 usageFlags | targetUsageFlags,
1369 VK_SHARING_MODE_EXCLUSIVE,
1375 de::MovePtr<Allocation> createImageMemory (const InstanceInterface& vki,
1376 const VkPhysicalDevice& vkd,
1377 const DeviceInterface& vk,
1379 Allocator& allocator,
1382 AllocationKind allocationKind)
1384 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1385 de::MovePtr<Allocation> allocation = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1387 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1392 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1396 VkImageAspectFlags aspect)
1398 const VkImageSubresourceRange range =
1407 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1410 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng, deBool useFormatCompCount, const DepthValuesArray& depthValues)
1412 const float clearNan = tcu::Float32::nan().asFloat();
1413 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1415 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1417 VkClearValue clearValue;
1419 clearValue.depthStencil.depth = clearNan;
1420 clearValue.depthStencil.stencil = 0xCDu;
1422 if (tcu::hasStencilComponent(format.order))
1423 clearValue.depthStencil.stencil = rng.getBool()
1427 if (tcu::hasDepthComponent(format.order))
1428 clearValue.depthStencil.depth = float(depthValues[rng.getBool() ? 1 : 0]) / 255.0f;
1434 VkClearValue clearValue;
1436 clearValue.color = randomColorClearValue(attachment, rng, useFormatCompCount);
1442 class AttachmentResources
1445 AttachmentResources (const InstanceInterface& vki,
1446 const VkPhysicalDevice& physDevice,
1447 const DeviceInterface& vk,
1449 Allocator& allocator,
1450 deUint32 queueIndex,
1452 const Attachment& attachmentInfo,
1453 VkImageUsageFlags usageFlags,
1454 const AllocationKind allocationKind)
1455 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1456 , m_imageMemory (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
1457 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1459 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1460 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1461 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1463 if (isDepthFormat && isStencilFormat)
1465 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1466 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1468 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1471 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1473 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1475 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1477 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1478 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1480 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1481 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1483 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1484 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1486 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1488 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1489 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1491 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1495 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1497 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1498 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1500 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1505 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1507 return m_inputAttachmentViews;
1510 ~AttachmentResources (void)
1514 VkImageView getAttachmentView (void) const
1516 return *m_attachmentView;
1519 VkImage getImage (void) const
1524 VkBuffer getBuffer (void) const
1526 DE_ASSERT(*m_buffer != DE_NULL);
1530 VkDeviceSize getBufferSize (void) const
1532 DE_ASSERT(*m_buffer != DE_NULL);
1533 return m_bufferSize;
1536 const Allocation& getResultMemory (void) const
1538 DE_ASSERT(m_bufferMemory);
1539 return *m_bufferMemory;
1542 VkBuffer getSecondaryBuffer (void) const
1544 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1545 return *m_secondaryBuffer;
1548 VkDeviceSize getSecondaryBufferSize (void) const
1550 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1551 return m_secondaryBufferSize;
1554 const Allocation& getSecondaryResultMemory (void) const
1556 DE_ASSERT(m_secondaryBufferMemory);
1557 return *m_secondaryBufferMemory;
1561 const Unique<VkImage> m_image;
1562 const UniquePtr<Allocation> m_imageMemory;
1563 const Unique<VkImageView> m_attachmentView;
1565 Move<VkImageView> m_depthInputAttachmentView;
1566 Move<VkImageView> m_stencilInputAttachmentView;
1567 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1569 Move<VkBuffer> m_buffer;
1570 VkDeviceSize m_bufferSize;
1571 de::MovePtr<Allocation> m_bufferMemory;
1573 Move<VkBuffer> m_secondaryBuffer;
1574 VkDeviceSize m_secondaryBufferSize;
1575 de::MovePtr<Allocation> m_secondaryBufferMemory;
1578 void uploadBufferData (const DeviceInterface& vk,
1580 const Allocation& memory,
1583 VkDeviceSize nonCoherentAtomSize)
1585 // Expand the range to flush to account for the nonCoherentAtomSize
1586 const VkDeviceSize roundedOffset = de::roundDown(memory.getOffset(), nonCoherentAtomSize);
1587 const VkDeviceSize roundedSize = de::roundUp(memory.getOffset() - roundedOffset + static_cast<VkDeviceSize>(size), nonCoherentAtomSize);
1589 const VkMappedMemoryRange range =
1591 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1593 memory.getMemory(), // mem;
1594 roundedOffset, // offset;
1595 roundedSize, // size;
1597 void* const ptr = memory.getHostPtr();
1599 deMemcpy(ptr, data, size);
1600 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1603 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1605 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);
1609 case tcu::TextureFormat::D:
1610 case tcu::TextureFormat::DS:
1611 return VK_IMAGE_ASPECT_DEPTH_BIT;
1613 case tcu::TextureFormat::S:
1614 return VK_IMAGE_ASPECT_STENCIL_BIT;
1617 return VK_IMAGE_ASPECT_COLOR_BIT;
1621 deUint32 getAttachmentNdx (const vector<AttachmentReference>& colorAttachments, size_t ndx)
1623 return (colorAttachments[ndx].getAttachment() == VK_ATTACHMENT_UNUSED) ? (deUint32)ndx : colorAttachments[ndx].getAttachment();
1629 RenderQuad (const Vec2& posA, const Vec2& posB)
1632 m_vertices[0] = posA;
1633 m_vertices[1] = Vec2(posA[0], posB[1]);
1634 m_vertices[2] = posB;
1636 m_vertices[3] = posB;
1637 m_vertices[4] = Vec2(posB[0], posA[1]);
1638 m_vertices[5] = posA;
1641 const Vec2& getCornerA (void) const
1643 return m_vertices[0];
1646 const Vec2& getCornerB (void) const
1648 return m_vertices[2];
1651 const void* getVertexPointer (void) const
1653 return &m_vertices[0];
1656 size_t getVertexDataSize (void) const
1658 return sizeof(Vec2) * m_vertices.size();
1662 vector<Vec2> m_vertices;
1668 ColorClear (const UVec2& offset,
1670 const VkClearColorValue& color)
1677 const UVec2& getOffset (void) const { return m_offset; }
1678 const UVec2& getSize (void) const { return m_size; }
1679 const VkClearColorValue& getColor (void) const { return m_color; }
1684 VkClearColorValue m_color;
1687 class DepthStencilClear
1690 DepthStencilClear (const UVec2& offset,
1697 , m_stencil (stencil)
1701 const UVec2& getOffset (void) const { return m_offset; }
1702 const UVec2& getSize (void) const { return m_size; }
1703 float getDepth (void) const { return m_depth; }
1704 deUint32 getStencil (void) const { return m_stencil; }
1707 const UVec2 m_offset;
1710 const float m_depth;
1711 const deUint32 m_stencil;
1714 class SubpassRenderInfo
1717 SubpassRenderInfo (const RenderPass& renderPass,
1718 deUint32 subpassIndex,
1719 deUint32 drawStartNdx,
1722 bool omitBlendState_,
1724 const UVec2& viewportOffset,
1725 const UVec2& viewportSize,
1727 const Maybe<RenderQuad>& renderQuad,
1728 const vector<ColorClear>& colorClears,
1729 const Maybe<DepthStencilClear>& depthStencilClear)
1730 : m_viewportOffset (viewportOffset)
1731 , m_viewportSize (viewportSize)
1732 , m_subpassIndex (subpassIndex)
1733 , m_drawStartNdx (drawStartNdx)
1734 , m_isSecondary (isSecondary_)
1735 , m_omitBlendState (omitBlendState_)
1736 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1737 , m_renderQuad (renderQuad)
1738 , m_colorClears (colorClears)
1739 , m_depthStencilClear (depthStencilClear)
1740 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1741 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1743 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1744 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[getAttachmentNdx(m_colorAttachments, attachmentNdx)]);
1746 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1748 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1749 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1753 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
1754 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1756 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
1757 deUint32 getDrawStartNdx (void) const { return m_drawStartNdx; }
1758 bool isSecondary (void) const { return m_isSecondary; }
1759 bool getOmitBlendState (void) const { return m_omitBlendState; }
1761 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
1762 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
1763 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1765 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); }
1766 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
1767 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1769 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
1770 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
1771 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
1772 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
1773 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
1774 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
1775 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
1776 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1779 UVec2 m_viewportOffset;
1780 UVec2 m_viewportSize;
1782 deUint32 m_subpassIndex;
1783 deUint32 m_drawStartNdx;
1785 bool m_omitBlendState;
1786 VkSubpassDescriptionFlags m_flags;
1788 Maybe<RenderQuad> m_renderQuad;
1789 vector<ColorClear> m_colorClears;
1790 Maybe<DepthStencilClear> m_depthStencilClear;
1792 vector<AttachmentReference> m_colorAttachments;
1793 vector<Attachment> m_colorAttachmentInfo;
1795 Maybe<AttachmentReference> m_depthStencilAttachment;
1796 Maybe<Attachment> m_depthStencilAttachmentInfo;
1798 vector<AttachmentReference> m_inputAttachments;
1801 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1803 VkRenderPass renderPass,
1804 VkShaderModule vertexShaderModule,
1805 VkShaderModule fragmentShaderModule,
1806 VkPipelineLayout pipelineLayout,
1807 const SubpassRenderInfo& renderInfo)
1809 Maybe<VkSampleCountFlagBits> rasterSamples;
1810 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1812 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1814 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1816 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1818 rasterSamples = attachment.getSamples();
1821 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1823 VK_FALSE, // blendEnable
1824 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1825 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1826 VK_BLEND_OP_ADD, // blendOpColor
1827 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1828 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1829 VK_BLEND_OP_ADD, // blendOpAlpha
1830 (attachmentNdx < renderInfo.getDrawStartNdx() ? (deUint32)0 :
1831 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT) // channelWriteMask
1834 attachmentBlendStates.push_back(attachmentBlendState);
1838 if (renderInfo.getDepthStencilAttachment())
1840 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1842 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1843 rasterSamples = attachment.getSamples();
1846 // If there are no attachment use single sample
1848 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1850 const VkVertexInputBindingDescription vertexBinding =
1853 (deUint32)sizeof(tcu::Vec2), // strideInBytes
1854 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1857 const VkVertexInputAttributeDescription vertexAttrib =
1861 VK_FORMAT_R32G32_SFLOAT, // format
1862 0u, // offsetInBytes
1865 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1867 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1869 (VkPipelineVertexInputStateCreateFlags)0u,
1871 &vertexBinding, // pVertexBindingDescriptions
1872 1u, // attributeCount
1873 &vertexAttrib, // pVertexAttributeDescriptions
1876 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1878 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType
1879 DE_NULL, // const void* pNext
1880 0u, // VkPipelineInputAssemblyStateCreateFlags flags
1881 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology
1882 VK_FALSE // VkBool32 primitiveRestartEnable
1885 const VkViewport viewport =
1887 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1888 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1892 const VkRect2D scissor =
1894 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1895 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1898 const VkPipelineViewportStateCreateInfo viewportState =
1900 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1901 DE_NULL, // const void* pNext
1902 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1903 1u, // deUint32 viewportCount
1904 &viewport, // const VkViewport* pViewports
1905 1u, // deUint32 scissorCount
1906 &scissor // const VkRect2D* pScissors
1909 const VkPipelineRasterizationStateCreateInfo rasterizationState =
1911 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
1912 DE_NULL, // const void* pNext
1913 0u, // VkPipelineRasterizationStateCreateFlags flags
1914 VK_FALSE, // VkBool32 depthClampEnable
1915 VK_FALSE, // VkBool32 rasterizerDiscardEnable
1916 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
1917 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
1918 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
1919 VK_FALSE, // VkBool32 depthBiasEnable
1920 0.0f, // float depthBiasConstantFactor
1921 0.0f, // float depthBiasClamp
1922 0.0f, // float depthBiasSlopeFactor
1923 1.0f // float lineWidth
1926 const VkPipelineMultisampleStateCreateInfo multisampleState =
1928 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1930 (VkPipelineMultisampleStateCreateFlags)0u,
1931 *rasterSamples, // rasterSamples
1932 VK_FALSE, // sampleShadingEnable
1933 0.0f, // minSampleShading
1934 DE_NULL, // pSampleMask
1935 VK_FALSE, // alphaToCoverageEnable
1936 VK_FALSE, // alphaToOneEnable
1938 const size_t stencilIndex = renderInfo.getSubpassIndex();
1940 const VkBool32 writeDepth = renderInfo.getDepthStencilAttachmentLayout()
1941 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1942 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
1946 const VkBool32 writeStencil = renderInfo.getDepthStencilAttachmentLayout()
1947 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1948 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
1952 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1954 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1956 (VkPipelineDepthStencilStateCreateFlags)0u,
1957 writeDepth, // depthTestEnable
1958 writeDepth, // depthWriteEnable
1959 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1960 VK_FALSE, // depthBoundsEnable
1961 writeStencil, // stencilTestEnable
1963 VK_STENCIL_OP_REPLACE, // stencilFailOp
1964 VK_STENCIL_OP_REPLACE, // stencilPassOp
1965 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1966 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1967 ~0u, // stencilCompareMask
1968 ~0u, // stencilWriteMask
1969 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1972 VK_STENCIL_OP_REPLACE, // stencilFailOp
1973 VK_STENCIL_OP_REPLACE, // stencilPassOp
1974 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1975 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1976 ~0u, // stencilCompareMask
1977 ~0u, // stencilWriteMask
1978 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1981 0.0f, // minDepthBounds;
1982 1.0f // maxDepthBounds;
1985 const VkPipelineColorBlendStateCreateInfo blendState =
1987 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1989 (VkPipelineColorBlendStateCreateFlags)0u,
1990 VK_FALSE, // logicOpEnable
1991 VK_LOGIC_OP_COPY, // logicOp
1992 (deUint32)attachmentBlendStates.size(), // attachmentCount
1993 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1994 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1997 return makeGraphicsPipeline(vk, // const DeviceInterface& vk
1998 device, // const VkDevice device
1999 pipelineLayout, // const VkPipelineLayout pipelineLayout
2000 vertexShaderModule, // const VkShaderModule vertexShaderModule
2001 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2002 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2003 DE_NULL, // const VkShaderModule geometryShaderModule
2004 fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2005 renderPass, // const VkRenderPass renderPass
2006 renderInfo.getSubpassIndex(), // const deUint32 subpass
2007 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2008 &inputAssemblyState, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2009 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2010 &viewportState, // const VkPipelineViewportStateCreateInfo* pViewportStat;
2011 &rasterizationState, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState
2012 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2013 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
2014 renderInfo.getOmitBlendState()
2015 ? DE_NULL : &blendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
2018 class SubpassRenderer
2021 SubpassRenderer (Context& context,
2022 const DeviceInterface& vk,
2024 Allocator& allocator,
2025 VkRenderPass renderPass,
2026 VkFramebuffer framebuffer,
2027 VkCommandPool commandBufferPool,
2028 deUint32 queueFamilyIndex,
2029 const vector<VkImage>& attachmentImages,
2030 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
2031 const SubpassRenderInfo& renderInfo,
2032 const vector<Attachment>& attachmentInfos,
2033 const AllocationKind allocationKind)
2034 : m_renderInfo (renderInfo)
2036 const InstanceInterface& vki = context.getInstanceInterface();
2037 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
2038 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
2039 vector<VkDescriptorSetLayoutBinding> bindings;
2041 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2043 const deUint32 attachmentNdx = (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ? colorAttachmentNdx
2044 : renderInfo.getColorAttachmentIndex(colorAttachmentNdx);
2046 m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
2049 if (renderInfo.getDepthStencilAttachmentIndex())
2050 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
2052 if (renderInfo.getRenderQuad())
2054 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
2056 if (renderInfo.getInputAttachmentCount() > 0)
2058 deUint32 bindingIndex = 0;
2060 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2062 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2063 const VkImageLayout layout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2064 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2065 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2066 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2067 const deUint32 bindingCount = (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2068 && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2072 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
2074 const VkDescriptorSetLayoutBinding binding =
2077 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2079 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
2083 bindings.push_back(binding);
2088 const VkDescriptorSetLayoutCreateInfo createInfo =
2090 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2094 (deUint32)bindings.size(),
2098 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
2101 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
2102 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2104 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
2106 (vk::VkPipelineLayoutCreateFlags)0,
2107 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
2108 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
2109 0u, // pushConstantRangeCount;
2110 DE_NULL, // pPushConstantRanges;
2113 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
2114 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
2115 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
2116 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
2118 // Round up the vertex buffer size to honor nonCoherentAtomSize.
2119 const auto properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2120 const auto vertexBufferSize = de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()), properties.limits.nonCoherentAtomSize);
2122 m_vertexBuffer = createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2123 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
2125 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
2127 uploadBufferData(vk, device, *m_vertexBufferMemory, static_cast<size_t>(vertexBufferSize), renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);
2129 if (renderInfo.getInputAttachmentCount() > 0)
2132 const VkDescriptorPoolSize poolSize =
2134 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2135 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2136 renderInfo.getInputAttachmentCount() * 2u
2138 const VkDescriptorPoolCreateInfo createInfo =
2140 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2142 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2144 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2145 renderInfo.getInputAttachmentCount() * 2u,
2150 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2153 const VkDescriptorSetAllocateInfo allocateInfo =
2155 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2160 &descriptorSetLayout
2163 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2166 vector<VkWriteDescriptorSet> writes (bindings.size());
2167 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
2168 deUint32 bindingIndex = 0;
2170 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2172 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2173 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2174 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2175 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2176 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2179 if (isDepthFormat && isStencilFormat)
2181 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2183 const VkDescriptorImageInfo imageInfo =
2186 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2187 inputAttachmentLayout
2189 imageInfos[bindingIndex] = imageInfo;
2192 const VkWriteDescriptorSet write =
2194 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2201 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2202 &imageInfos[bindingIndex],
2206 writes[bindingIndex] = write;
2212 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2214 const VkDescriptorImageInfo imageInfo =
2217 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2218 inputAttachmentLayout
2220 imageInfos[bindingIndex] = imageInfo;
2223 const VkWriteDescriptorSet write =
2225 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2232 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2233 &imageInfos[bindingIndex],
2237 writes[bindingIndex] = write;
2245 const VkDescriptorImageInfo imageInfo =
2248 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2249 inputAttachmentLayout
2251 imageInfos[bindingIndex] = imageInfo;
2254 const VkWriteDescriptorSet write =
2256 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2263 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2264 &imageInfos[bindingIndex],
2268 writes[bindingIndex] = write;
2275 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2280 if (renderInfo.isSecondary())
2282 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2284 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
2285 pushRenderCommands(vk, *m_commandBuffer);
2286 endCommandBuffer(vk, *m_commandBuffer);
2290 bool isSecondary (void) const
2292 return m_commandBuffer;
2295 VkCommandBuffer getCommandBuffer (void) const
2297 DE_ASSERT(isSecondary());
2298 return *m_commandBuffer;
2301 void pushRenderCommands (const DeviceInterface& vk,
2302 VkCommandBuffer commandBuffer)
2304 if (!m_renderInfo.getColorClears().empty())
2306 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2308 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2310 const ColorClear& colorClear = colorClears[attachmentNdx];
2311 const VkClearAttachment attachment =
2313 VK_IMAGE_ASPECT_COLOR_BIT,
2315 makeClearValue(colorClear.getColor()),
2317 const VkClearRect rect =
2320 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2321 { colorClear.getSize().x(), colorClear.getSize().y() }
2323 0u, // baseArrayLayer
2327 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2331 if (m_renderInfo.getDepthStencilClear())
2333 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2334 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2335 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2336 const VkImageLayout layout = *m_renderInfo.getDepthStencilAttachmentLayout();
2337 const VkClearAttachment attachment =
2339 (VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2340 | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2342 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2344 const VkClearRect rect =
2347 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2348 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2350 0u, // baseArrayLayer
2354 if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2355 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
2357 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2361 vector<VkImageMemoryBarrier> selfDeps;
2362 VkPipelineStageFlags srcStages = 0;
2363 VkPipelineStageFlags dstStages = 0;
2365 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2367 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2369 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2371 const VkImageMemoryBarrier barrier =
2373 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2376 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2377 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2379 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2380 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2382 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2383 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2385 m_colorAttachmentImages[colorAttachmentNdx], // image
2386 { // subresourceRange
2387 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2390 0, // baseArraySlice
2395 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2396 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2398 selfDeps.push_back(barrier);
2402 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2404 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2405 const bool hasDepth = hasDepthComponent(format.order);
2406 const bool hasStencil = hasStencilComponent(format.order);
2407 const VkImageMemoryBarrier barrier =
2409 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2412 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2413 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2415 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // oldLayout
2416 m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // newLayout;
2418 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2419 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2421 m_depthStencilAttachmentImage, // image;
2422 { // subresourceRange;
2423 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2424 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2427 0, // baseArraySlice;
2432 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2433 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2435 selfDeps.push_back(barrier);
2439 if (!selfDeps.empty())
2441 DE_ASSERT(srcStages != 0);
2442 DE_ASSERT(dstStages != 0);
2443 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2446 if (m_renderInfo.getRenderQuad())
2448 const VkDeviceSize offset = 0;
2449 const VkBuffer vertexBuffer = *m_vertexBuffer;
2451 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2453 if (m_descriptorSet)
2455 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2456 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2459 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2460 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2465 const SubpassRenderInfo m_renderInfo;
2466 Move<VkCommandBuffer> m_commandBuffer;
2467 Move<VkPipeline> m_pipeline;
2468 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2469 Move<VkPipelineLayout> m_pipelineLayout;
2471 Move<VkShaderModule> m_vertexShaderModule;
2472 Move<VkShaderModule> m_fragmentShaderModule;
2474 Move<VkDescriptorPool> m_descriptorPool;
2475 Move<VkDescriptorSet> m_descriptorSet;
2476 Move<VkBuffer> m_vertexBuffer;
2477 de::MovePtr<Allocation> m_vertexBufferMemory;
2478 vector<VkImage> m_colorAttachmentImages;
2479 VkImage m_depthStencilAttachmentImage;
2482 void pushImageInitializationCommands (const DeviceInterface& vk,
2483 VkCommandBuffer commandBuffer,
2484 const vector<Attachment>& attachmentInfo,
2485 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2486 deUint32 queueIndex,
2487 const vector<Maybe<VkClearValue> >& clearValues)
2490 vector<VkImageMemoryBarrier> initializeLayouts;
2492 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2494 if (!clearValues[attachmentNdx])
2497 const VkImageMemoryBarrier barrier =
2499 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2502 (VkAccessFlags)0, // srcAccessMask
2503 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2505 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2506 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2508 queueIndex, // srcQueueFamilyIndex;
2509 queueIndex, // destQueueFamilyIndex;
2511 attachmentResources[attachmentNdx]->getImage(), // image;
2512 { // subresourceRange;
2513 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2516 0, // baseArraySlice;
2521 initializeLayouts.push_back(barrier);
2524 if (!initializeLayouts.empty())
2525 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2526 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2527 0, (const VkMemoryBarrier*)DE_NULL,
2528 0, (const VkBufferMemoryBarrier*)DE_NULL,
2529 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2532 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2534 if (!clearValues[attachmentNdx])
2537 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2539 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2541 const float clearNan = tcu::Float32::nan().asFloat();
2542 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2543 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2544 const VkClearDepthStencilValue depthStencil =
2549 const VkImageSubresourceRange range =
2551 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2552 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2559 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2563 const VkImageSubresourceRange range =
2565 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2568 0, // baseArrayLayer;
2571 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2573 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2578 vector<VkImageMemoryBarrier> renderPassLayouts;
2580 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2582 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2583 const VkImageMemoryBarrier barrier =
2585 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2588 getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2589 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2591 oldLayout, // oldLayout
2592 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2594 queueIndex, // srcQueueFamilyIndex;
2595 queueIndex, // destQueueFamilyIndex;
2597 attachmentResources[attachmentNdx]->getImage(), // image;
2598 { // subresourceRange;
2599 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2602 0, // baseArraySlice;
2607 renderPassLayouts.push_back(barrier);
2610 if (!renderPassLayouts.empty())
2611 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2612 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2613 0, (const VkMemoryBarrier*)DE_NULL,
2614 0, (const VkBufferMemoryBarrier*)DE_NULL,
2615 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2619 template<typename RenderpassSubpass>
2620 void pushRenderPassCommands (const DeviceInterface& vk,
2621 VkCommandBuffer commandBuffer,
2622 VkRenderPass renderPass,
2623 VkFramebuffer framebuffer,
2624 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2625 const UVec2& renderPos,
2626 const UVec2& renderSize,
2627 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2628 TestConfig::RenderTypes render)
2630 const float clearNan = tcu::Float32::nan().asFloat();
2631 vector<VkClearValue> attachmentClearValues;
2632 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
2634 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2636 if (renderPassClearValues[attachmentNdx])
2637 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2639 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2643 const VkRect2D renderArea =
2645 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2646 { renderSize.x(), renderSize.y() }
2649 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2651 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2652 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, contents);
2653 const VkRenderPassBeginInfo renderPassBeginInfo = createRenderPassBeginInfo(renderPass,
2656 (deUint32)attachmentClearValues.size(),
2657 attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);
2659 if (subpassNdx == 0)
2660 RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
2662 RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2666 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2668 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2670 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2672 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2673 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2676 DE_FATAL("Invalid contents");
2680 RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
2684 void pushRenderPassCommands (const DeviceInterface& vk,
2685 VkCommandBuffer commandBuffer,
2686 VkRenderPass renderPass,
2687 VkFramebuffer framebuffer,
2688 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2689 const UVec2& renderPos,
2690 const UVec2& renderSize,
2691 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2692 TestConfig::RenderTypes render,
2693 RenderPassType renderPassType)
2695 switch (renderPassType)
2697 case RENDERPASS_TYPE_LEGACY:
2698 return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, render);
2699 case RENDERPASS_TYPE_RENDERPASS2:
2700 return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, render);
2702 TCU_THROW(InternalError, "Impossible");
2706 void pushReadImagesToBuffers (const DeviceInterface& vk,
2707 VkCommandBuffer commandBuffer,
2708 deUint32 queueIndex,
2710 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2711 const vector<Attachment>& attachmentInfo,
2712 const vector<bool>& isLazy,
2714 const UVec2& targetSize)
2717 vector<VkImageMemoryBarrier> imageBarriers;
2719 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2721 if (isLazy[attachmentNdx])
2724 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2725 const VkImageMemoryBarrier barrier =
2727 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2730 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2731 getAllMemoryReadFlags(), // dstAccessMask
2733 oldLayout, // oldLayout
2734 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2736 queueIndex, // srcQueueFamilyIndex
2737 queueIndex, // destQueueFamilyIndex
2739 attachmentResources[attachmentNdx]->getImage(), // image
2740 { // subresourceRange
2741 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2744 0, // baseArraySlice
2749 imageBarriers.push_back(barrier);
2752 if (!imageBarriers.empty())
2753 vk.cmdPipelineBarrier(commandBuffer,
2754 getAllPipelineStageFlags(),
2755 getAllPipelineStageFlags(),
2756 (VkDependencyFlags)0,
2757 0, (const VkMemoryBarrier*)DE_NULL,
2758 0, (const VkBufferMemoryBarrier*)DE_NULL,
2759 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2762 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2764 if (isLazy[attachmentNdx])
2767 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2768 const VkBufferImageCopy rect =
2771 0, // bufferRowLength
2772 0, // bufferImageHeight
2773 { // imageSubresource
2774 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2779 { 0, 0, 0 }, // imageOffset
2780 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2783 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2785 if (tcu::TextureFormat::DS == order)
2787 const VkBufferImageCopy stencilRect =
2790 0, // bufferRowLength
2791 0, // bufferImageHeight
2792 { // imageSubresource
2793 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2798 { 0, 0, 0 }, // imageOffset
2799 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2802 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2807 vector<VkBufferMemoryBarrier> bufferBarriers;
2809 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2811 if (isLazy[attachmentNdx])
2814 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2815 const VkBufferMemoryBarrier bufferBarrier =
2817 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2820 getAllMemoryWriteFlags(),
2821 getAllMemoryReadFlags(),
2826 attachmentResources[attachmentNdx]->getBuffer(),
2828 attachmentResources[attachmentNdx]->getBufferSize()
2831 bufferBarriers.push_back(bufferBarrier);
2833 if (tcu::TextureFormat::DS == order)
2835 const VkBufferMemoryBarrier secondaryBufferBarrier =
2837 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2840 getAllMemoryWriteFlags(),
2841 getAllMemoryReadFlags(),
2846 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2848 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2851 bufferBarriers.push_back(secondaryBufferBarrier);
2855 if (!bufferBarriers.empty())
2856 vk.cmdPipelineBarrier(commandBuffer,
2857 getAllPipelineStageFlags(),
2858 getAllPipelineStageFlags(),
2859 (VkDependencyFlags)0,
2860 0, (const VkMemoryBarrier*)DE_NULL,
2861 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2862 0, (const VkImageMemoryBarrier*)DE_NULL);
2869 PixelValue (const Maybe<bool>& x = nothing<bool>(),
2870 const Maybe<bool>& y = nothing<bool>(),
2871 const Maybe<bool>& z = nothing<bool>(),
2872 const Maybe<bool>& w = nothing<bool>());
2874 void setUndefined (size_t ndx);
2875 void setValue (size_t ndx, bool value);
2876 Maybe<bool> getValue (size_t ndx) const;
2882 PixelValue::PixelValue (const Maybe<bool>& x,
2883 const Maybe<bool>& y,
2884 const Maybe<bool>& z,
2885 const Maybe<bool>& w)
2888 const Maybe<bool> values[] =
2893 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
2896 setValue(ndx, *values[ndx]);
2901 DE_ASSERT(m_status <= 0xFFu);
2904 void PixelValue::setUndefined (size_t ndx)
2907 DE_ASSERT(m_status <= 0xFFu);
2909 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
2910 DE_ASSERT(m_status <= 0xFFu);
2913 void PixelValue::setValue (size_t ndx, bool value)
2916 DE_ASSERT(m_status <= 0xFFu);
2918 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
2921 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
2923 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
2925 DE_ASSERT(m_status <= 0xFFu);
2928 Maybe<bool> PixelValue::getValue (size_t ndx) const
2931 DE_ASSERT(m_status <= 0xFFu);
2933 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
2935 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
2938 return nothing<bool>();
2941 void clearReferenceValues (vector<PixelValue>& values,
2942 const UVec2& targetSize,
2943 const UVec2& offset,
2946 const PixelValue& value)
2948 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2949 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
2950 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
2952 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2953 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2955 for (int compNdx = 0; compNdx < 4; compNdx++)
2959 if (value.getValue(compNdx))
2960 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
2962 values[x + y * targetSize.x()].setUndefined(compNdx);
2968 void markUndefined (vector<PixelValue>& values,
2970 const UVec2& targetSize,
2971 const UVec2& offset,
2974 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2976 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2977 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2979 for (int compNdx = 0; compNdx < 4; compNdx++)
2982 values[x + y * targetSize.x()].setUndefined(compNdx);
2987 PixelValue clearValueToPixelValue (const VkClearValue& value,
2988 const tcu::TextureFormat& format,
2989 const DepthValuesArray& depthValues)
2991 const bool isDepthAttachment = hasDepthComponent(format.order);
2992 const bool isStencilAttachment = hasStencilComponent(format.order);
2993 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
2994 PixelValue pixelValue;
2996 if (isDepthOrStencilAttachment)
2998 if (isDepthAttachment)
3000 if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
3001 pixelValue.setValue(0, true);
3002 else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
3003 pixelValue.setValue(0, false);
3005 DE_FATAL("Unknown depth value");
3008 if (isStencilAttachment)
3010 if (value.depthStencil.stencil == 0xFFu)
3011 pixelValue.setValue(1, true);
3012 else if (value.depthStencil.stencil == 0x0u)
3013 pixelValue.setValue(1, false);
3015 DE_FATAL("Unknown stencil value");
3020 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3021 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3023 switch (channelClass)
3025 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3026 for (int i = 0; i < 4; i++)
3030 if (value.color.int32[i] == 1)
3031 pixelValue.setValue(i, true);
3032 else if (value.color.int32[i] == 0)
3033 pixelValue.setValue(i, false);
3035 DE_FATAL("Unknown clear color value");
3040 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3041 for (int i = 0; i < 4; i++)
3045 if (value.color.uint32[i] == 1u)
3046 pixelValue.setValue(i, true);
3047 else if (value.color.uint32[i] == 0u)
3048 pixelValue.setValue(i, false);
3050 DE_FATAL("Unknown clear color value");
3055 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3056 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3057 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3058 for (int i = 0; i < 4; i++)
3062 if (value.color.float32[i] == 1.0f)
3063 pixelValue.setValue(i, true);
3064 else if (value.color.float32[i] == 0.0f)
3065 pixelValue.setValue(i, false);
3067 DE_FATAL("Unknown clear color value");
3073 DE_FATAL("Unknown channel class");
3080 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
3081 const RenderPass& renderPassInfo,
3082 const UVec2& targetSize,
3083 const vector<Maybe<VkClearValue> >& imageClearValues,
3084 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3085 const vector<SubpassRenderInfo>& subpassRenderInfo,
3086 const UVec2& renderPos,
3087 const UVec2& renderSize,
3088 const deUint32 drawStartNdx,
3089 const DepthValuesArray& depthValues)
3091 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
3092 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
3094 referenceAttachments.resize(renderPassInfo.getAttachments().size());
3096 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3098 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3099 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3100 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
3102 reference.resize(targetSize.x() * targetSize.y());
3104 if (imageClearValues[attachmentNdx])
3105 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
3108 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3110 const Subpass& subpass = subpasses[subpassNdx];
3111 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
3112 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
3114 // Apply load op if attachment was used for the first time
3115 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
3117 const deUint32 attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);
3119 if (!attachmentUsed[attachmentIndex] && colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
3121 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3122 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3123 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3125 DE_ASSERT(!tcu::hasDepthComponent(format.order));
3126 DE_ASSERT(!tcu::hasStencilComponent(format.order));
3128 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3129 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3130 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3131 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3133 attachmentUsed[attachmentIndex] = true;
3137 // Apply load op to depth/stencil attachment if it was used for the first time
3138 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3140 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3142 // Apply load op if attachment was used for the first time
3143 if (!attachmentUsed[attachmentIndex])
3145 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3146 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3147 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3149 if (tcu::hasDepthComponent(format.order))
3151 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3152 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3153 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3154 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3157 if (tcu::hasStencilComponent(format.order))
3159 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3160 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3161 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3162 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3165 attachmentUsed[attachmentIndex] = true;
3169 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
3171 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
3172 const UVec2 offset = colorClear.getOffset();
3173 const UVec2 size = colorClear.getSize();
3174 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
3175 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3176 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3177 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3180 value.color = colorClear.getColor();
3182 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format, depthValues));
3185 if (renderInfo.getDepthStencilClear())
3187 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
3188 const UVec2 offset = dsClear.getOffset();
3189 const UVec2 size = dsClear.getSize();
3190 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3191 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3192 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3193 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3194 const bool hasStencil = tcu::hasStencilComponent(format.order)
3195 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
3196 const bool hasDepth = tcu::hasDepthComponent(format.order)
3197 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
3198 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3201 value.depthStencil.depth = dsClear.getDepth();
3202 value.depthStencil.stencil = dsClear.getStencil();
3204 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format, depthValues));
3207 if (renderInfo.getRenderQuad())
3209 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3210 const Vec2 posA = renderQuad.getCornerA();
3211 const Vec2 posB = renderQuad.getCornerB();
3212 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3213 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3214 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3215 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3216 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3217 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3219 DE_ASSERT(posAI.x() < posBI.x());
3220 DE_ASSERT(posAI.y() < posBI.y());
3222 if (subpass.getInputAttachments().empty())
3224 for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3226 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3228 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
3231 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3232 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3233 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3234 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3236 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3237 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3239 for (int compNdx = 0; compNdx < 4; compNdx++)
3241 const size_t index = subpassNdx + attachmentIndex + compNdx;
3242 const BoolOp op = boolOpFromIndex(index);
3243 const bool boolX = x % 2 == (int)(index % 2);
3244 const bool boolY = y % 2 == (int)((index / 2) % 2);
3246 if (channelMask[compNdx])
3247 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3252 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3254 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3255 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3256 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3257 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3258 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3260 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3261 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3263 if (tcu::hasDepthComponent(format.order)
3264 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3265 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3267 const size_t index = subpassNdx + 1;
3268 const BoolOp op = boolOpFromIndex(index);
3269 const bool boolX = x % 2 == (int)(index % 2);
3270 const bool boolY = y % 2 == (int)((index / 2) % 2);
3272 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3275 if (tcu::hasStencilComponent(format.order)
3276 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3277 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3279 const size_t index = subpassNdx;
3280 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3287 size_t outputComponentCount = 0;
3288 vector<Maybe<bool> > inputs;
3290 DE_ASSERT(posAI.x() < posBI.x());
3291 DE_ASSERT(posAI.y() < posBI.y());
3293 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3295 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3296 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3297 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3298 const int componentCount = tcu::getNumUsedChannels(format.order);
3300 outputComponentCount += (size_t)componentCount;
3303 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3304 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3305 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3307 const Attachment& attachment (renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
3308 const tcu::TextureFormat format (mapVkFormat(attachment.getFormat()));
3310 if (tcu::hasDepthComponent(format.order))
3311 outputComponentCount++;
3314 if (outputComponentCount > 0)
3316 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3317 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3319 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3321 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3322 const VkImageLayout layout = subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
3323 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3324 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3325 const int componentCount = tcu::getNumUsedChannels(format.order);
3327 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3329 if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3330 && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
3332 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3337 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3338 ? ((inputs.size() / outputComponentCount)
3339 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3342 size_t outputValueNdx = 0;
3344 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3346 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3347 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3348 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3349 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3350 const int componentCount = tcu::getNumUsedChannels(format.order);
3352 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3354 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3355 const BoolOp op = boolOpFromIndex(index);
3356 const bool boolX = x % 2 == (int)(index % 2);
3357 const bool boolY = y % 2 == (int)((index / 2) % 2);
3358 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3360 for (size_t i = 0; i < inputsPerOutput; i++)
3364 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3365 output = tcu::nothing<bool>();
3367 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3371 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3373 reference[x + y * targetSize.x()].setUndefined(compNdx);
3376 outputValueNdx += componentCount;
3379 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3380 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3381 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3383 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3384 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3385 const size_t index = subpassNdx + attachmentIndex;
3386 const BoolOp op = boolOpFromIndex(index);
3387 const bool boolX = x % 2 == (int)(index % 2);
3388 const bool boolY = y % 2 == (int)((index / 2) % 2);
3389 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3391 for (size_t i = 0; i < inputsPerOutput; i++)
3395 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3396 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3398 output = tcu::nothing<bool>();
3402 reference[x + y * targetSize.x()].setValue(0, *output);
3404 reference[x + y * targetSize.x()].setUndefined(0);
3411 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3412 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3413 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3415 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3416 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3417 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3418 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3420 if (tcu::hasStencilComponent(format.order))
3422 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3423 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3425 const size_t index = subpassNdx;
3426 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3434 // Mark all attachments that were used but not stored as undefined
3435 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3437 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3438 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3439 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3440 const bool isStencilAttachment = hasStencilComponent(format.order);
3441 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3443 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3445 if (isDepthOrStencilAttachment)
3446 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3448 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3451 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3452 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3456 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3457 const vector<vector<PixelValue> >& referenceValues,
3458 const UVec2& targetSize,
3459 const RenderPass& renderPassInfo,
3460 const DepthValuesArray& depthValues)
3462 referenceImages.resize(referenceValues.size());
3464 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3466 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3467 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3468 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3469 const bool hasDepth = tcu::hasDepthComponent(format.order);
3470 const bool hasStencil = tcu::hasStencilComponent(format.order);
3471 const bool hasDepthOrStencil = hasDepth || hasStencil;
3472 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3474 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3476 if (hasDepthOrStencil)
3480 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3482 for (deUint32 y = 0; y < targetSize.y(); y++)
3483 for (deUint32 x = 0; x < targetSize.x(); x++)
3485 if (reference[x + y * targetSize.x()].getValue(0))
3487 if (*reference[x + y * targetSize.x()].getValue(0))
3488 depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
3490 depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
3492 else // Fill with 3x3 grid
3493 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3499 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3501 for (deUint32 y = 0; y < targetSize.y(); y++)
3502 for (deUint32 x = 0; x < targetSize.x(); x++)
3504 if (reference[x + y * targetSize.x()].getValue(1))
3506 if (*reference[x + y * targetSize.x()].getValue(1))
3507 stencilAccess.setPixStencil(0xFFu, x, y);
3509 stencilAccess.setPixStencil(0x0u, x, y);
3511 else // Fill with 3x3 grid
3512 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3518 for (deUint32 y = 0; y < targetSize.y(); y++)
3519 for (deUint32 x = 0; x < targetSize.x(); x++)
3523 for (int compNdx = 0; compNdx < 4; compNdx++)
3525 if (reference[x + y * targetSize.x()].getValue(compNdx))
3527 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3528 color[compNdx] = 1.0f;
3530 color[compNdx] = 0.0f;
3532 else // Fill with 3x3 grid
3533 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3536 referenceImage.getAccess().setPixel(color, x, y);
3542 bool verifyColorAttachment (const vector<PixelValue>& reference,
3543 const ConstPixelBufferAccess& result,
3544 const PixelBufferAccess& errorImage,
3545 const deBool useFormatCompCount)
3547 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3548 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3551 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3552 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3553 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3555 for (int y = 0; y < result.getHeight(); y++)
3556 for (int x = 0; x < result.getWidth(); x++)
3558 const Vec4 resultColor = result.getPixel(x, y);
3559 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3560 bool pixelOk = true;
3561 const deUint32 componentCount = useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(result.getFormat().order) : 4;
3563 for (deUint32 compNdx = 0; compNdx < componentCount; compNdx++)
3565 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
3569 const bool value = *maybeValue;
3571 if ((value && (resultColor[compNdx] != 1.0f))
3572 || (!value && resultColor[compNdx] != 0.0f))
3579 errorImage.setPixel(red, x, y);
3583 errorImage.setPixel(green, x, y);
3589 // Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
3590 const tcu::Vec4 kDefaultColorForLog {0.0f, 0.0f, 0.0f, 1.0f};
3591 const float kTrueComponent = 1.0f;
3592 const float kFalseComponent = 0.5f;
3593 const float kUnsetComponentLow = 0.0f;
3594 const float kUnsetComponentHigh = 0.25f;
3596 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const ConstPixelBufferAccess& image, int numChannels)
3598 // Same channel order, but using UNORM_INT8 for the color format.
3599 const auto order = image.getFormat().order;
3600 const tcu::TextureFormat loggableFormat {order, tcu::TextureFormat::UNORM_INT8};
3601 const int width = image.getWidth();
3602 const int height = image.getHeight();
3603 std::unique_ptr<tcu::TextureLevel> result {new tcu::TextureLevel{loggableFormat, width, height}};
3604 auto access = result->getAccess();
3605 tcu::Vec4 outColor = kDefaultColorForLog;
3607 for (int x = 0; x < width; ++x)
3608 for (int y = 0; y < height; ++y)
3610 const auto value = image.getPixel(x, y);
3611 for (int c = 0; c < numChannels; ++c)
3613 if (value[c] == 0.0f)
3614 outColor[c] = kFalseComponent;
3615 else if (value[c] == 1.0f)
3616 outColor[c] = kTrueComponent;
3620 access.setPixel(outColor, x, y);
3626 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const vector<PixelValue>& reference, const UVec2& targetSize, int numChannels)
3628 const tcu::TextureFormat loggableFormat {tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
3629 const int width = static_cast<int>(targetSize.x());
3630 const int height = static_cast<int>(targetSize.y());
3631 std::unique_ptr<tcu::TextureLevel> result {new tcu::TextureLevel{loggableFormat, width, height}};
3632 auto access = result->getAccess();
3633 tcu::Vec4 outColor = kDefaultColorForLog;
3635 for (int x = 0; x < width; ++x)
3636 for (int y = 0; y < height; ++y)
3638 const int index = x + y * width;
3639 for (int c = 0; c < numChannels; ++c)
3641 const auto maybeValue = reference[index].getValue(c);
3643 outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
3645 outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
3647 access.setPixel(outColor, x, y);
3653 bool verifyDepthAttachment (const vector<PixelValue>& reference,
3654 const ConstPixelBufferAccess& result,
3655 const PixelBufferAccess& errorImage,
3656 const DepthValuesArray& depthValues,
3659 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3660 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3663 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3664 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3665 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3667 for (int y = 0; y < result.getHeight(); y++)
3668 for (int x = 0; x < result.getWidth(); x++)
3670 bool pixelOk = true;
3672 const float resultDepth = result.getPixDepth(x, y);
3673 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3674 const Maybe<bool> maybeValue = referenceValue.getValue(0);
3678 const bool value = *maybeValue;
3680 if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon))
3681 || (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
3687 errorImage.setPixel(red, x, y);
3691 errorImage.setPixel(green, x, y);
3697 bool verifyStencilAttachment (const vector<PixelValue>& reference,
3698 const ConstPixelBufferAccess& result,
3699 const PixelBufferAccess& errorImage)
3701 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3702 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3705 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3706 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3707 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3709 for (int y = 0; y < result.getHeight(); y++)
3710 for (int x = 0; x < result.getWidth(); x++)
3712 bool pixelOk = true;
3714 const deUint32 resultStencil = result.getPixStencil(x, y);
3715 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3716 const Maybe<bool> maybeValue = referenceValue.getValue(1);
3720 const bool value = *maybeValue;
3722 if ((value && (resultStencil != 0xFFu))
3723 || (!value && resultStencil != 0x0u))
3729 errorImage.setPixel(red, x, y);
3733 errorImage.setPixel(green, x, y);
3739 bool logAndVerifyImages (TestLog& log,
3740 const DeviceInterface& vk,
3742 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3743 const vector<bool>& attachmentIsLazy,
3744 const RenderPass& renderPassInfo,
3745 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3746 const vector<Maybe<VkClearValue> >& imageClearValues,
3747 const vector<SubpassRenderInfo>& subpassRenderInfo,
3748 const UVec2& targetSize,
3749 const TestConfig& config)
3751 vector<vector<PixelValue> > referenceValues;
3752 vector<tcu::TextureLevel> referenceAttachments;
3755 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
3757 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx, config.depthValues);
3758 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo, config.depthValues);
3760 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3762 if (!attachmentIsLazy[attachmentNdx])
3764 bool attachmentOK = true;
3765 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3766 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3768 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3770 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3771 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3773 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3774 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3776 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
3777 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());
3780 bool depthOK = true;
3781 bool stencilOK = true;
3782 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3783 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3784 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3785 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3787 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3788 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
3793 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3794 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
3799 if (!depthOK || !stencilOK)
3801 const auto attachmentNdxStr = de::toString(attachmentNdx);
3804 log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr, "Output depth and stencil attachments " + attachmentNdxStr);
3805 log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth", "Attachment " + attachmentNdxStr + " Depth", depthAccess);
3806 log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil", "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
3807 log << TestLog::EndImageSet;
3809 // Reference images. These will be logged as image sets due to having depth and stencil aspects.
3810 log << TestLog::Image("AttachmentReferences" + attachmentNdxStr, "Reference images " + attachmentNdxStr, referenceAttachments[attachmentNdx].getAccess());
3813 log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
3815 log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr, "Depth Attachment Error " + attachmentNdxStr, depthErrorImage.getAccess());
3817 log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr, "Stencil Attachment Error " + attachmentNdxStr, stencilErrorImage.getAccess());
3818 log << TestLog::EndImageSet;
3820 attachmentOK = false;
3826 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3828 invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
3830 bool depthOK = true;
3831 bool stencilOK = true;
3832 bool colorOK = true;
3833 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3834 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3836 if (tcu::hasDepthComponent(format.order))
3838 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3839 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
3844 else if (tcu::hasStencilComponent(format.order))
3846 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3847 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3854 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3855 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.useFormatCompCount))
3861 if (!depthOK || !stencilOK || !colorOK)
3863 log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
3864 if (!depthOK || !stencilOK)
3866 // Log without conversions.
3867 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3868 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3872 // Convert color images to better reflect test status and output in any format.
3873 const auto numChannels = tcu::getNumUsedChannels(access.getFormat().order);
3874 const auto attachmentForLog = renderColorImageForLog(access, numChannels);
3875 const auto referenceForLog = renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);
3877 log << TestLog::Message << "Check the attachment formats and test data to verify which components affect the test result." << TestLog::EndMessage;
3878 log << TestLog::Message << "In the reference image, unset pixel components are marked with a 3x3 grid storing values 0.0 and 0.25, pixel components set to false are stored as 0.5 and pixel components set to true are stored as 1.0." << TestLog::EndMessage;
3879 log << TestLog::Message << "Output attachment pixel components are always set to 0.5 or 1.0 but may not be taken into account if not set in the reference image." << TestLog::EndMessage;
3881 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), attachmentForLog->getAccess());
3882 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceForLog->getAccess());
3884 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3885 log << TestLog::EndImageSet;
3887 attachmentOK = false;
3899 std::string getInputAttachmentType (VkFormat vkFormat)
3901 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3902 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3904 switch (channelClass)
3906 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3907 return "isubpassInput";
3909 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3910 return "usubpassInput";
3912 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3913 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3914 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3915 return "subpassInput";
3918 DE_FATAL("Unknown channel class");
3923 std::string getAttachmentType (VkFormat vkFormat, deBool useFormatCompCount)
3925 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3926 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3927 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3929 switch (channelClass)
3931 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3932 if (useFormatCompCount)
3933 return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
3937 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3938 if (useFormatCompCount)
3939 return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
3943 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3944 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3945 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3946 if (useFormatCompCount)
3947 return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
3952 DE_FATAL("Unknown channel class");
3957 void createTestShaders (SourceCollections& dst, TestConfig config)
3959 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3961 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3963 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3965 const Subpass& subpass = subpasses[subpassNdx];
3966 deUint32 inputAttachmentBinding = 0;
3967 std::ostringstream vertexShader;
3968 std::ostringstream fragmentShader;
3970 vertexShader << "#version 310 es\n"
3971 << "layout(location = 0) in highp vec2 a_position;\n"
3972 << "void main (void) {\n"
3973 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
3976 fragmentShader << "#version 310 es\n"
3977 << "precision highp float;\n";
3979 bool hasAnyDepthFormats = false;
3981 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3983 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3984 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
3985 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3986 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3987 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3988 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3990 if (isDepthFormat || isStencilFormat)
3992 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3994 hasAnyDepthFormats = true;
3995 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
3996 inputAttachmentBinding++;
3999 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4001 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
4002 inputAttachmentBinding++;
4007 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
4009 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
4010 inputAttachmentBinding++;
4014 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4016 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)].getFormat(), config.useFormatCompCount);
4017 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
4020 if (hasAnyDepthFormats)
4021 fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
4022 << "\treturn abs(a - b) <= epsilon;\n}\n\n";
4024 fragmentShader << "void main (void) {\n";
4026 if (subpass.getInputAttachments().empty())
4028 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4030 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4032 if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4035 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4036 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4037 const size_t componentCount = config.useFormatCompCount ? (size_t)tcu::getNumUsedChannels(format.order) : 4;
4038 const std::string attachmentType = getAttachmentType(attachment.getFormat(), config.useFormatCompCount);
4040 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(" << attachmentType + "(";
4042 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4044 const size_t index = subpassNdx + attachmentIndex + compNdx;
4045 const BoolOp op = boolOpFromIndex(index);
4048 fragmentShader << ",\n\t\t";
4050 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
4051 << ") " << boolOpToString(op) << " ("
4052 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4053 << ") ? 1.0 : 0.0)";
4056 fragmentShader << "));\n";
4059 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4060 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4061 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4063 const size_t index = subpassNdx + 1;
4064 const BoolOp op = boolOpFromIndex(index);
4066 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
4067 << ") " << boolOpToString(op) << " ("
4068 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4069 << ") ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f);\n";
4074 size_t inputComponentCount = 0;
4075 size_t outputComponentCount = 0;
4077 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4079 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4080 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4081 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4082 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4083 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4085 if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4086 inputComponentCount += 1;
4087 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4088 inputComponentCount += 1;
4090 inputComponentCount += componentCount;
4093 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4095 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4096 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4097 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4098 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4100 outputComponentCount += componentCount;
4103 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4104 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4105 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4107 outputComponentCount++;
4110 if (outputComponentCount > 0)
4112 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
4113 ? ((inputComponentCount / outputComponentCount)
4114 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
4117 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
4119 if (outputComponentCount > 0)
4120 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
4122 size_t inputValueNdx = 0;
4124 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4126 const char* const components[] =
4130 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
4131 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4132 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4133 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4134 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4135 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
4136 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
4138 if (isDepthFormat || isStencilFormat)
4140 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4142 fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual(" << deUint32(config.depthValues[1]) <<
4143 ".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), " <<
4144 std::fixed << std::setprecision(12) << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
4148 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4150 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
4156 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4158 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
4164 size_t outputValueNdx = 0;
4166 for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4168 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
4169 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
4170 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
4171 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4172 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
4174 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4176 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
4177 const BoolOp op = boolOpFromIndex(index);
4179 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
4180 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4181 << ") " << boolOpToString(op) << " ("
4182 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4185 for (size_t i = 0; i < inputsPerOutput; i++)
4186 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
4189 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
4191 for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
4194 fragmentShader << ", ";
4196 if (compNdx < componentCount)
4197 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
4199 fragmentShader << "0";
4202 outputValueNdx += componentCount;
4204 fragmentShader << ");\n";
4207 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4208 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4209 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4211 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
4212 const size_t index = subpassNdx + attachmentIndex;
4213 const BoolOp op = boolOpFromIndex(index);
4215 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
4216 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4217 << ") " << boolOpToString(op) << " ("
4218 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4221 for (size_t i = 0; i < inputsPerOutput; i++)
4222 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
4224 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f;\n";
4229 fragmentShader << "}\n";
4231 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
4232 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
4237 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
4239 bool lastAttachmentWasLazy = false;
4241 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4243 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4244 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
4245 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4246 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
4248 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
4250 attachmentIsLazy.push_back(true);
4252 lastAttachmentWasLazy = true;
4254 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
4256 attachmentIsLazy.push_back(false);
4257 lastAttachmentWasLazy = false;
4260 DE_FATAL("Unknown imageMemory");
4263 attachmentIsLazy.push_back(false);
4267 enum AttachmentRefType
4269 ATTACHMENTREFTYPE_COLOR,
4270 ATTACHMENTREFTYPE_DEPTH_STENCIL,
4271 ATTACHMENTREFTYPE_INPUT,
4272 ATTACHMENTREFTYPE_RESOLVE,
4275 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
4279 case VK_IMAGE_LAYOUT_GENERAL:
4280 case VK_IMAGE_LAYOUT_PREINITIALIZED:
4283 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
4284 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4286 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
4287 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
4288 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4290 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
4291 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4293 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4294 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4296 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4297 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4300 DE_FATAL("Unexpected image layout");
4305 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
4307 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
4309 const deUint32 attachment = references[referenceNdx].getAttachment();
4311 if (attachment != VK_ATTACHMENT_UNUSED)
4313 VkImageUsageFlags usage;
4317 case ATTACHMENTREFTYPE_COLOR:
4318 case ATTACHMENTREFTYPE_RESOLVE:
4319 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4322 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
4323 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4326 case ATTACHMENTREFTYPE_INPUT:
4327 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4331 DE_FATAL("Unexpected attachment reference type");
4336 attachmentImageUsage[attachment] |= usage;
4341 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4343 if (!references.empty())
4345 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4349 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4351 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4353 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4355 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4357 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4358 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4359 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4360 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4363 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4365 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4366 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4367 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
4369 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4370 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4372 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4373 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4375 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4376 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4378 if (!attachmentIsLazy[attachmentNdx])
4380 if (clearValues[attachmentNdx])
4381 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4383 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4387 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);
4389 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4390 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4395 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4397 bool lastSubpassWasSecondary = false;
4399 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4401 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4403 subpassIsSecondary.push_back(true);
4404 lastSubpassWasSecondary = true;
4406 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4408 subpassIsSecondary.push_back(false);
4409 lastSubpassWasSecondary = false;
4412 DE_FATAL("Unknown commandBuffer");
4416 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4418 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4420 if (!isLazy[attachmentNdx])
4421 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4423 clearValues.push_back(nothing<VkClearValue>());
4427 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4429 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4431 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4432 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4434 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4437 clearValues.push_back(nothing<VkClearValue>());
4441 void logSubpassRenderInfo (TestLog& log, const SubpassRenderInfo& info, TestConfig config)
4443 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4445 if (info.isSecondary())
4446 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4448 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4450 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4452 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4454 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4455 << ". Offset: " << colorClear.getOffset()
4456 << ", Size: " << colorClear.getSize()
4457 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(), config.useFormatCompCount) << TestLog::EndMessage;
4460 if (info.getDepthStencilClear())
4462 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4464 log << TestLog::Message << "Clearing depth stencil attachment"
4465 << ". Offset: " << depthStencilClear.getOffset()
4466 << ", Size: " << depthStencilClear.getSize()
4467 << ", Depth: " << depthStencilClear.getDepth()
4468 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4471 if (info.getRenderQuad())
4473 const RenderQuad& renderQuad = *info.getRenderQuad();
4475 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4479 void logTestCaseInfo (TestLog& log,
4480 const TestConfig& config,
4481 const vector<bool>& attachmentIsLazy,
4482 const vector<Maybe<VkClearValue> >& imageClearValues,
4483 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4484 const vector<SubpassRenderInfo>& subpassRenderInfo)
4486 const RenderPass& renderPass = config.renderPass;
4488 logRenderPassInfo(log, renderPass);
4490 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4491 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4492 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4494 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4495 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4497 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4499 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4501 if (attachmentIsLazy[attachmentNdx])
4502 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4504 if (imageClearValues[attachmentNdx])
4505 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4506 *imageClearValues[attachmentNdx], config.useFormatCompCount) << " before rendering." << TestLog::EndMessage;
4508 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4509 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4510 *renderPassClearValues[attachmentNdx], config.useFormatCompCount) << " in the beginning of the render pass." << TestLog::EndMessage;
4513 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4515 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4517 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
4521 float roundToViewport (float x, deUint32 offset, deUint32 size)
4523 const float origin = (float)(offset) + ((float(size) / 2.0f));
4524 const float p = (float)(size) / 2.0f;
4525 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4527 return (((float)xi) - origin) / p;
4530 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4532 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4533 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4534 bool lastSubpassWasSecondary = false;
4536 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4538 const Subpass& subpass = subpasses[subpassNdx];
4539 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
4540 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
4541 const bool omitBlendState = subpass.getOmitBlendState();
4542 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
4543 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
4544 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
4546 vector<ColorClear> colorClears;
4547 Maybe<DepthStencilClear> depthStencilClear;
4548 Maybe<RenderQuad> renderQuad;
4550 lastSubpassWasSecondary = subpassIsSecondary;
4552 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
4554 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4556 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4558 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4559 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4560 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4561 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
4562 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
4563 const VkClearColorValue color = randomColorClearValue(attachment, rng, config.useFormatCompCount);
4565 colorClears.push_back(ColorClear(offset, size, color));
4568 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4570 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
4571 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4572 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
4573 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
4574 const VkClearValue value = randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);
4576 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
4580 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4582 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
4583 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
4585 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
4586 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
4588 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
4589 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
4591 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
4594 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary, omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
4598 void checkTextureFormatSupport (TestLog& log,
4599 const InstanceInterface& vk,
4600 VkPhysicalDevice device,
4601 const vector<Attachment>& attachments)
4603 bool supported = true;
4605 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4607 const Attachment& attachment = attachments[attachmentNdx];
4608 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4609 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
4610 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
4611 VkFormatProperties properties;
4613 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
4615 if ((properties.optimalTilingFeatures & flags) != flags)
4618 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
4623 TCU_THROW(NotSupportedError, "Format not supported");
4626 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
4628 const UVec2 targetSize = config.targetSize;
4629 const UVec2 renderPos = config.renderPos;
4630 const UVec2 renderSize = config.renderSize;
4631 const RenderPass& renderPassInfo = config.renderPass;
4633 TestLog& log = context.getTestContext().getLog();
4634 de::Random rng (config.seed);
4636 vector<bool> attachmentIsLazy;
4637 vector<VkImageUsageFlags> attachmentImageUsage;
4638 vector<Maybe<VkClearValue> > imageClearValues;
4639 vector<Maybe<VkClearValue> > renderPassClearValues;
4641 vector<bool> subpassIsSecondary;
4642 vector<SubpassRenderInfo> subpassRenderInfo;
4644 if (config.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
4645 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
4647 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
4649 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
4650 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
4653 if (!renderPassInfo.getInputAspects().empty())
4655 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
4656 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
4660 bool requireDepthStencilLayout = false;
4662 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4664 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4665 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
4666 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4667 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4669 requireDepthStencilLayout = true;
4674 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
4676 const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
4678 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4680 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4681 || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4683 requireDepthStencilLayout = true;
4688 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4690 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4691 || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4693 requireDepthStencilLayout = true;
4698 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
4700 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4701 || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4703 requireDepthStencilLayout = true;
4708 if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
4709 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4711 requireDepthStencilLayout = true;
4716 if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
4717 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
4720 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
4721 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy, config.useFormatCompCount, config.depthValues);
4722 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
4723 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(), config.useFormatCompCount, config.depthValues);
4725 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
4726 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
4728 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
4730 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
4733 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
4735 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
4737 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4739 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
4740 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
4745 const InstanceInterface& vki = context.getInstanceInterface();
4746 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
4747 const VkDevice device = context.getDevice();
4748 const DeviceInterface& vk = context.getDeviceInterface();
4749 const VkQueue queue = context.getUniversalQueue();
4750 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
4751 Allocator& allocator = context.getDefaultAllocator();
4753 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo, config.renderPassType));
4754 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, 0, queueIndex));
4755 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4756 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4757 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4759 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
4760 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
4761 vector<VkImage> attachmentImages;
4762 vector<VkImageView> attachmentViews;
4763 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
4765 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4767 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
4769 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
4770 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
4771 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
4773 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
4776 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4777 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
4778 endCommandBuffer(vk, *initializeImagesCommandBuffer);
4781 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
4783 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4784 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)));
4786 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4787 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes, config.renderPassType);
4788 endCommandBuffer(vk, *renderCommandBuffer);
4790 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4791 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
4792 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
4794 const VkCommandBuffer commandBuffers[] =
4796 *initializeImagesCommandBuffer,
4797 *renderCommandBuffer,
4798 *readImagesToBuffersCommandBuffer
4800 const Unique<VkFence> fence (createFence(vk, device, 0u));
4802 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
4803 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
4807 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
4808 return tcu::TestStatus::pass("Pass");
4810 return tcu::TestStatus::fail("Result verification failed");
4814 static const VkFormat s_coreColorFormats[] =
4816 VK_FORMAT_R5G6B5_UNORM_PACK16,
4821 VK_FORMAT_R8G8_UNORM,
4822 VK_FORMAT_R8G8_SNORM,
4823 VK_FORMAT_R8G8_UINT,
4824 VK_FORMAT_R8G8_SINT,
4825 VK_FORMAT_R8G8B8A8_UNORM,
4826 VK_FORMAT_R8G8B8A8_SNORM,
4827 VK_FORMAT_R8G8B8A8_UINT,
4828 VK_FORMAT_R8G8B8A8_SINT,
4829 VK_FORMAT_R8G8B8A8_SRGB,
4830 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4831 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4832 VK_FORMAT_A8B8G8R8_UINT_PACK32,
4833 VK_FORMAT_A8B8G8R8_SINT_PACK32,
4834 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4835 VK_FORMAT_B8G8R8A8_UNORM,
4836 VK_FORMAT_B8G8R8A8_SRGB,
4837 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4838 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4839 VK_FORMAT_A2B10G10R10_UINT_PACK32,
4840 VK_FORMAT_R16_UNORM,
4841 VK_FORMAT_R16_SNORM,
4844 VK_FORMAT_R16_SFLOAT,
4845 VK_FORMAT_R16G16_UNORM,
4846 VK_FORMAT_R16G16_SNORM,
4847 VK_FORMAT_R16G16_UINT,
4848 VK_FORMAT_R16G16_SINT,
4849 VK_FORMAT_R16G16_SFLOAT,
4850 VK_FORMAT_R16G16B16A16_UNORM,
4851 VK_FORMAT_R16G16B16A16_SNORM,
4852 VK_FORMAT_R16G16B16A16_UINT,
4853 VK_FORMAT_R16G16B16A16_SINT,
4854 VK_FORMAT_R16G16B16A16_SFLOAT,
4857 VK_FORMAT_R32_SFLOAT,
4858 VK_FORMAT_R32G32_UINT,
4859 VK_FORMAT_R32G32_SINT,
4860 VK_FORMAT_R32G32_SFLOAT,
4861 VK_FORMAT_R32G32B32A32_UINT,
4862 VK_FORMAT_R32G32B32A32_SINT,
4863 VK_FORMAT_R32G32B32A32_SFLOAT
4866 static const VkFormat s_coreDepthStencilFormats[] =
4868 VK_FORMAT_D16_UNORM,
4870 VK_FORMAT_X8_D24_UNORM_PACK32,
4871 VK_FORMAT_D32_SFLOAT,
4873 VK_FORMAT_D24_UNORM_S8_UINT,
4874 VK_FORMAT_D32_SFLOAT_S8_UINT
4877 void addAttachmentTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
4879 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
4880 const VkAttachmentLoadOp loadOps[] =
4882 VK_ATTACHMENT_LOAD_OP_LOAD,
4883 VK_ATTACHMENT_LOAD_OP_CLEAR,
4884 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4887 const VkAttachmentStoreOp storeOps[] =
4889 VK_ATTACHMENT_STORE_OP_STORE,
4890 VK_ATTACHMENT_STORE_OP_DONT_CARE
4893 const VkImageLayout initialAndFinalColorLayouts[] =
4895 VK_IMAGE_LAYOUT_GENERAL,
4896 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4897 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4898 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4899 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4902 const VkImageLayout initialAndFinalColorLayoutsLazy[] =
4904 VK_IMAGE_LAYOUT_GENERAL,
4905 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4906 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
4909 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4911 VK_IMAGE_LAYOUT_GENERAL,
4912 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4913 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4914 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4915 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4916 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4919 const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] =
4921 VK_IMAGE_LAYOUT_GENERAL,
4922 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4923 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4924 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
4927 const VkImageLayout subpassLayouts[] =
4929 VK_IMAGE_LAYOUT_GENERAL,
4930 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4933 const VkImageLayout depthStencilLayouts[] =
4935 VK_IMAGE_LAYOUT_GENERAL,
4936 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4939 const TestConfig::RenderTypes renderCommands[] =
4941 TestConfig::RENDERTYPES_NONE,
4942 TestConfig::RENDERTYPES_CLEAR,
4943 TestConfig::RENDERTYPES_DRAW,
4944 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4947 const TestConfig::CommandBufferTypes commandBuffers[] =
4949 TestConfig::COMMANDBUFFERTYPES_INLINE,
4950 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4951 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4954 const TestConfig::ImageMemory imageMemories[] =
4956 TestConfig::IMAGEMEMORY_STRICT,
4957 TestConfig::IMAGEMEMORY_LAZY,
4958 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4961 const UVec2 targetSizes[] =
4967 const UVec2 renderPositions[] =
4973 const UVec2 renderSizes[] =
4979 tcu::TestContext& testCtx = group->getTestContext();
4980 de::Random rng (1433774382u);
4982 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4984 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4985 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4986 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4988 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4990 const bool useDepthStencil = rng.getBool();
4991 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4992 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4993 vector<Attachment> attachments;
4994 vector<AttachmentReference> colorAttachmentReferences;
4996 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4998 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4999 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5000 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5001 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5003 const VkImageLayout initialLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5004 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5005 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5006 const VkImageLayout finalizeLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5007 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5008 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5009 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5011 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5012 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5014 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5015 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5018 if (useDepthStencil)
5020 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5021 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5022 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5023 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5025 const VkImageLayout initialLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5026 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5027 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5028 const VkImageLayout finalizeLayout = (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5029 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5030 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5032 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5033 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5035 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
5036 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5040 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5041 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5042 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>()));
5043 const vector<SubpassDependency> deps;
5045 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
5046 const RenderPass renderPass (attachments, subpasses, deps);
5047 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5048 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5049 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5050 const TestConfig testConfig (renderPass,
5060 testConfigExternal.allocationKind,
5061 testConfigExternal.renderPassType);
5063 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5067 group->addChild(attachmentCountGroup.release());
5071 void addAttachmentWriteMaskTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5073 const deUint32 attachmentCounts[] = { 1, 2, 3, 4, 8 };
5075 const VkFormat attachmentFormats[] =
5077 VK_FORMAT_R8G8B8A8_UINT,
5078 VK_FORMAT_R8G8B8A8_UNORM,
5079 VK_FORMAT_R5G6B5_UNORM_PACK16,
5080 VK_FORMAT_R8G8_UNORM
5083 tcu::TestContext& testCtx = group->getTestContext();
5085 for (deUint32 attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5087 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
5088 const string groupName = "attachment_count_" + de::toString(attachmentCount);
5090 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), de::toString(attachmentCount).c_str()));
5092 for (deUint32 drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
5094 deUint32 formatNdx = 0;
5095 vector<Attachment> attachments;
5096 vector<AttachmentReference> colorAttachmentReferences;
5098 for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5100 const VkFormat format = attachmentFormats[formatNdx];
5101 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5102 const VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
5103 const VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE;
5104 const VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
5105 const VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
5106 const VkImageLayout initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5107 const VkImageLayout finalizeLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5108 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
5110 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5111 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5113 if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
5118 const VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
5119 const vector<Subpass> subpass (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
5120 const vector<SubpassDependency> deps;
5122 const string testCaseName = "start_index_" + de::toString(drawStartNdx);
5123 const RenderPass renderPass (attachments, subpass, deps);
5125 const TestConfig::RenderTypes render = TestConfig::RENDERTYPES_DRAW;
5126 const TestConfig::CommandBufferTypes commandBuffer = TestConfig::COMMANDBUFFERTYPES_INLINE;
5127 const TestConfig::ImageMemory imageMemory = TestConfig::IMAGEMEMORY_LAZY;
5128 const UVec2 targetSize = UVec2(64, 64);
5129 const UVec2 renderPos = UVec2(0, 0);
5130 const UVec2 renderSize = UVec2(64, 64);
5131 const deBool useFormatCompCount = DE_TRUE;
5132 const vector<DeviceCoreFeature> requiredFeatures = {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
5133 const TestConfig testConfig (renderPass,
5143 testConfigExternal.allocationKind,
5144 testConfigExternal.renderPassType,
5147 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), checkSupport, createTestShaders, renderPassTest, testConfig);
5151 group->addChild(attachmentCountGroup.release());
5155 template<typename T>
5156 T chooseRandom (de::Random& rng, const set<T>& values)
5158 size_t ndx = ((size_t)rng.getUint32()) % values.size();
5159 typename set<T>::const_iterator iter = values.begin();
5161 for (; ndx > 0; ndx--)
5167 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5169 const deUint32 attachmentCounts[] = { 4, 8 };
5170 const VkAttachmentLoadOp loadOps[] =
5172 VK_ATTACHMENT_LOAD_OP_LOAD,
5173 VK_ATTACHMENT_LOAD_OP_CLEAR,
5174 VK_ATTACHMENT_LOAD_OP_DONT_CARE
5177 const VkAttachmentStoreOp storeOps[] =
5179 VK_ATTACHMENT_STORE_OP_STORE,
5180 VK_ATTACHMENT_STORE_OP_DONT_CARE
5183 const VkImageLayout initialAndFinalColorLayouts[] =
5185 VK_IMAGE_LAYOUT_GENERAL,
5186 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5187 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5188 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5189 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5192 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5194 VK_IMAGE_LAYOUT_GENERAL,
5195 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5196 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5197 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5198 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5199 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5202 const VkImageLayout subpassLayoutsColor[] =
5204 VK_IMAGE_LAYOUT_GENERAL,
5205 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5208 const VkImageLayout subpassLayoutsDepthStencil[] =
5210 VK_IMAGE_LAYOUT_GENERAL,
5211 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5214 const VkImageLayout subpassLayoutsInput[] =
5216 VK_IMAGE_LAYOUT_GENERAL,
5217 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5222 // Each pass uses one more attachmen than previous one
5223 ALLOCATIONTYPE_GROW,
5224 // Each pass uses one less attachment than previous one
5225 ALLOCATIONTYPE_SHRINK,
5226 // Each pass drops one attachment and picks up new one
5227 ALLOCATIONTYPE_ROLL,
5228 // Start by growing and end by shrinking
5229 ALLOCATIONTYPE_GROW_SHRINK,
5230 // Each subpass has single input and single output attachment
5231 ALLOCATIONTYPE_IO_CHAIN,
5232 // Each subpass has multiple inputs and multiple outputs attachment
5233 ALLOCATIONTYPE_IO_GENERIC
5236 const AllocationType allocationTypes[] =
5238 ALLOCATIONTYPE_GROW,
5239 ALLOCATIONTYPE_SHRINK,
5240 ALLOCATIONTYPE_ROLL,
5241 ALLOCATIONTYPE_GROW_SHRINK,
5242 ALLOCATIONTYPE_IO_CHAIN,
5243 ALLOCATIONTYPE_IO_GENERIC
5246 const char* const allocationTypeStr[] =
5252 "input_output_chain",
5256 const TestConfig::RenderTypes renderCommands[] =
5258 TestConfig::RENDERTYPES_NONE,
5259 TestConfig::RENDERTYPES_CLEAR,
5260 TestConfig::RENDERTYPES_DRAW,
5261 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5264 const TestConfig::CommandBufferTypes commandBuffers[] =
5266 TestConfig::COMMANDBUFFERTYPES_INLINE,
5267 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5268 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5271 const TestConfig::ImageMemory imageMemories[] =
5273 TestConfig::IMAGEMEMORY_STRICT,
5274 TestConfig::IMAGEMEMORY_LAZY,
5275 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
5278 const UVec2 targetSizes[] =
5284 const UVec2 renderPositions[] =
5290 const UVec2 renderSizes[] =
5296 tcu::TestContext& testCtx = group->getTestContext();
5297 de::Random rng (3700649827u);
5299 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
5301 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
5302 const size_t testCaseCount = 100;
5303 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
5305 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
5307 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
5309 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
5310 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
5311 vector<Attachment> attachments;
5313 set<deUint32> definedAttachments;
5315 vector<Subpass> subpasses;
5316 set<deUint32> colorAttachments;
5317 set<deUint32> depthStencilAttachments;
5319 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
5321 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
5322 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5323 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5324 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5326 const VkImageLayout initialLayout = isDepthStencilAttachment
5327 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5328 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5329 const VkImageLayout finalizeLayout = isDepthStencilAttachment
5330 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5331 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5333 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5334 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5336 if (isDepthStencilAttachment)
5338 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5340 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
5341 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
5342 definedAttachments.insert(attachmentIndex);
5344 depthStencilAttachments.insert(attachmentIndex);
5346 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5350 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5352 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
5353 definedAttachments.insert(attachmentIndex);
5355 colorAttachments.insert(attachmentIndex);
5357 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5360 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>());
5361 vector<SubpassDependency> deps;
5363 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
5365 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
5366 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
5367 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
5368 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
5369 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
5370 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
5371 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
5372 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
5373 ? just(chooseRandom(rng, depthStencilAttachments))
5374 : nothing<deUint32>());
5375 std::vector<deUint32> subpassPreserveAttachments;
5377 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
5378 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
5380 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5381 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
5383 if (depthStencilAttachment)
5384 definedAttachments.insert(*depthStencilAttachment);
5387 std::vector<AttachmentReference> inputAttachmentReferences;
5388 std::vector<AttachmentReference> colorAttachmentReferences;
5389 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5391 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5393 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
5395 if (lastUseOfAttachment[colorAttachmentIndex])
5397 deBool foundDuplicate = false;
5399 const deUint32 srcPass = *lastUseOfAttachment[colorAttachmentIndex];
5400 const deUint32 dstPass = subpassIndex;
5401 const VkDependencyFlags dependencyFlags = rng.getBool() ? (VkDependencyFlags) VK_DEPENDENCY_BY_REGION_BIT : 0u;
5403 const SubpassDependency newDependency(srcPass, dstPass,
5404 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5405 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5406 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5407 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5409 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5410 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5411 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5412 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5414 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5415 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5419 for (SubpassDependency& dependency : deps)
5421 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
5423 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
5424 dependency.setDstAccessMask(newDstFlags);
5425 foundDuplicate = true;
5430 if (!foundDuplicate)
5432 deps.push_back(newDependency);
5436 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
5438 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
5441 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
5443 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
5445 if(lastUseOfAttachment[inputAttachmentIndex])
5447 deBool foundDuplicate = false;
5449 const deUint32 srcPass = *lastUseOfAttachment[inputAttachmentIndex];
5450 const deUint32 dstPass = subpassIndex;
5451 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
5453 const SubpassDependency newDependency(srcPass, dstPass,
5454 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5455 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5456 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5457 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5459 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5460 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5461 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5462 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5464 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5465 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5468 for (SubpassDependency& dependency : deps)
5470 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
5472 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
5473 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
5474 dependency.setDstAccessMask(newSrcFlags);
5475 dependency.setDstAccessMask(newDstFlags);
5476 foundDuplicate = true;
5481 if (!foundDuplicate)
5483 deps.push_back(newDependency);
5486 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
5488 VkImageAspectFlags aspect = 0u;
5489 if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
5491 bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
5492 aspect = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
5494 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL, aspect));
5498 if (depthStencilAttachment)
5500 if (lastUseOfAttachment[*depthStencilAttachment])
5502 deBool foundDuplicate = false;
5504 const deUint32 srcPass = *lastUseOfAttachment[*depthStencilAttachment];
5505 const deUint32 dstPass = subpassIndex;
5506 const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
5508 const SubpassDependency newDependency(srcPass, dstPass,
5509 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5510 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5511 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5512 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5514 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5515 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5516 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5517 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5519 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5520 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5523 for (SubpassDependency& dependency : deps)
5525 if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
5527 const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
5528 const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
5529 dependency.setDstAccessMask(newSrcFlags);
5530 dependency.setDstAccessMask(newDstFlags);
5531 foundDuplicate = true;
5536 if (!foundDuplicate)
5538 deps.push_back(newDependency);
5542 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
5544 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
5547 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5549 vector<deUint32> preserveAttachments;
5550 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
5552 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
5553 preserveAttachments.push_back(attachmentIndex);
5556 // Use random image layout when possible
5557 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
5559 bool usedAsInput = false;
5560 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
5561 if (colorAttachmentReferences[colorRefIdx].getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
5565 colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
5567 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
5569 bool usedAsDepthStencil = inputAttachmentReferences[inputRefIdx].getAttachment() == depthStencilAttachmentReference.getAttachment();
5570 bool usedAsColor = false;
5571 for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
5572 if (inputAttachmentReferences[inputRefIdx].getAttachment() == colorAttachmentReferences[colorRefIdx].getAttachment())
5575 if (!usedAsColor && !usedAsDepthStencil)
5576 inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
5579 bool usedAsInput = false;
5580 for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
5581 if (depthStencilAttachmentReference.getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
5585 depthStencilAttachmentReference.setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil), DE_ARRAY_END(subpassLayoutsDepthStencil)));
5588 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5589 inputAttachmentReferences,
5590 colorAttachmentReferences,
5591 vector<AttachmentReference>(),
5592 depthStencilAttachmentReference,
5593 preserveAttachments));
5597 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5598 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5599 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5601 const string testCaseName = de::toString(testCaseNdx);
5602 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5603 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5604 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5606 const RenderPass renderPass (attachments, subpasses, deps);
5607 const TestConfig testConfig (renderPass,
5617 testConfigExternal.allocationKind,
5618 testConfigExternal.renderPassType);
5620 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5625 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
5626 vector<Attachment> attachments;
5627 vector<Subpass> subpasses;
5629 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5631 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5632 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5633 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5634 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5636 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5637 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5639 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5640 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5642 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5645 if (allocationType == ALLOCATIONTYPE_GROW)
5647 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5649 vector<AttachmentReference> colorAttachmentReferences;
5651 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5653 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
5655 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5658 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5659 vector<AttachmentReference>(),
5660 colorAttachmentReferences,
5661 vector<AttachmentReference>(),
5662 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5663 vector<deUint32>()));
5666 else if (allocationType == ALLOCATIONTYPE_SHRINK)
5668 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5670 vector<AttachmentReference> colorAttachmentReferences;
5672 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5674 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
5676 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5679 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5680 vector<AttachmentReference>(),
5681 colorAttachmentReferences,
5682 vector<AttachmentReference>(),
5683 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5684 vector<deUint32>()));
5687 else if (allocationType == ALLOCATIONTYPE_ROLL)
5689 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
5691 vector<AttachmentReference> colorAttachmentReferences;
5693 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
5695 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
5697 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
5700 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5701 vector<AttachmentReference>(),
5702 colorAttachmentReferences,
5703 vector<AttachmentReference>(),
5704 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5705 vector<deUint32>()));
5708 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
5710 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5712 vector<AttachmentReference> colorAttachmentReferences;
5714 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5716 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
5718 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5721 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5722 vector<AttachmentReference>(),
5723 colorAttachmentReferences,
5724 vector<AttachmentReference>(),
5725 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5726 vector<deUint32>()));
5728 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5730 vector<AttachmentReference> colorAttachmentReferences;
5732 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5734 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
5736 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5739 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5740 vector<AttachmentReference>(),
5741 colorAttachmentReferences,
5742 vector<AttachmentReference>(),
5743 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5744 vector<deUint32>()));
5747 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
5749 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5750 vector<AttachmentReference>(),
5751 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
5752 vector<AttachmentReference>(),
5753 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5754 vector<deUint32>()));
5756 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
5758 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2) ? VK_IMAGE_ASPECT_COLOR_BIT : static_cast<VkImageAspectFlagBits>(0);
5759 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5760 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
5761 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
5762 vector<AttachmentReference>(),
5763 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5764 vector<deUint32>()));
5768 DE_FATAL("Unknown allocation type");
5771 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5772 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5773 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5775 const string testCaseName = de::toString(testCaseNdx);
5776 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5777 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5778 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5780 vector<SubpassDependency> deps;
5782 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
5784 const bool byRegion = rng.getBool();
5785 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
5786 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5787 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5788 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5789 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5791 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5792 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5793 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5794 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5796 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5797 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5799 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5802 const RenderPass renderPass (attachments, subpasses, deps);
5803 const TestConfig testConfig (renderPass,
5813 testConfigExternal.allocationKind,
5814 testConfigExternal.renderPassType);
5816 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5820 group->addChild(allocationTypeGroup.release());
5824 void addSimpleTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5826 const UVec2 targetSize (64, 64);
5827 const UVec2 renderPos (0, 0);
5828 const UVec2 renderSize (64, 64);
5832 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5833 VK_SAMPLE_COUNT_1_BIT,
5834 VK_ATTACHMENT_LOAD_OP_CLEAR,
5835 VK_ATTACHMENT_STORE_OP_STORE,
5836 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5837 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5838 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5839 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5840 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5842 vector<AttachmentReference>(),
5843 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5844 vector<AttachmentReference>(),
5845 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5846 vector<deUint32>())),
5847 vector<SubpassDependency>());
5848 const TestConfig testConfig (renderPass,
5849 TestConfig::RENDERTYPES_DRAW,
5850 TestConfig::COMMANDBUFFERTYPES_INLINE,
5851 TestConfig::IMAGEMEMORY_STRICT,
5858 testConfigExternal.allocationKind,
5859 testConfigExternal.renderPassType);
5861 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, testConfig);
5866 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5867 VK_SAMPLE_COUNT_1_BIT,
5868 VK_ATTACHMENT_LOAD_OP_CLEAR,
5869 VK_ATTACHMENT_STORE_OP_STORE,
5870 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5871 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5872 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5873 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5874 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5876 vector<AttachmentReference>(),
5877 vector<AttachmentReference>(),
5878 vector<AttachmentReference>(),
5879 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5880 vector<deUint32>())),
5881 vector<SubpassDependency>());
5882 const TestConfig testConfig (renderPass,
5883 TestConfig::RENDERTYPES_DRAW,
5884 TestConfig::COMMANDBUFFERTYPES_INLINE,
5885 TestConfig::IMAGEMEMORY_STRICT,
5892 testConfigExternal.allocationKind,
5893 testConfigExternal.renderPassType);
5895 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, testConfig);
5900 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
5901 VK_SAMPLE_COUNT_1_BIT,
5902 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5903 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5904 VK_ATTACHMENT_LOAD_OP_CLEAR,
5905 VK_ATTACHMENT_STORE_OP_STORE,
5906 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5907 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5908 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5910 vector<AttachmentReference>(),
5911 vector<AttachmentReference>(),
5912 vector<AttachmentReference>(),
5913 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5914 vector<deUint32>())),
5915 vector<SubpassDependency>());
5916 const TestConfig testConfig (renderPass,
5917 TestConfig::RENDERTYPES_DRAW,
5918 TestConfig::COMMANDBUFFERTYPES_INLINE,
5919 TestConfig::IMAGEMEMORY_STRICT,
5926 testConfigExternal.allocationKind,
5927 testConfigExternal.renderPassType);
5929 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, testConfig);
5934 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5935 VK_SAMPLE_COUNT_1_BIT,
5936 VK_ATTACHMENT_LOAD_OP_CLEAR,
5937 VK_ATTACHMENT_STORE_OP_STORE,
5938 VK_ATTACHMENT_LOAD_OP_CLEAR,
5939 VK_ATTACHMENT_STORE_OP_STORE,
5940 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5941 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5942 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5944 vector<AttachmentReference>(),
5945 vector<AttachmentReference>(),
5946 vector<AttachmentReference>(),
5947 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5948 vector<deUint32>())),
5949 vector<SubpassDependency>());
5950 const TestConfig testConfig (renderPass,
5951 TestConfig::RENDERTYPES_DRAW,
5952 TestConfig::COMMANDBUFFERTYPES_INLINE,
5953 TestConfig::IMAGEMEMORY_STRICT,
5960 testConfigExternal.allocationKind,
5961 testConfigExternal.renderPassType);
5963 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, testConfig);
5968 const Attachment attachments[] =
5970 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5971 VK_SAMPLE_COUNT_1_BIT,
5972 VK_ATTACHMENT_LOAD_OP_CLEAR,
5973 VK_ATTACHMENT_STORE_OP_STORE,
5974 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5975 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5976 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5977 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5978 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5979 VK_SAMPLE_COUNT_1_BIT,
5980 VK_ATTACHMENT_LOAD_OP_CLEAR,
5981 VK_ATTACHMENT_STORE_OP_STORE,
5982 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5983 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5984 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5985 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5988 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5989 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5991 vector<AttachmentReference>(),
5992 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5993 vector<AttachmentReference>(),
5994 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5995 vector<deUint32>())),
5996 vector<SubpassDependency>());
5997 const TestConfig testConfig (renderPass,
5998 TestConfig::RENDERTYPES_DRAW,
5999 TestConfig::COMMANDBUFFERTYPES_INLINE,
6000 TestConfig::IMAGEMEMORY_STRICT,
6007 testConfigExternal.allocationKind,
6008 testConfigExternal.renderPassType);
6010 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, testConfig);
6015 const Attachment attachments[] =
6017 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6018 VK_SAMPLE_COUNT_1_BIT,
6019 VK_ATTACHMENT_LOAD_OP_CLEAR,
6020 VK_ATTACHMENT_STORE_OP_STORE,
6021 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6022 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6023 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6024 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6025 Attachment(VK_FORMAT_S8_UINT,
6026 VK_SAMPLE_COUNT_1_BIT,
6027 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6028 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6029 VK_ATTACHMENT_LOAD_OP_CLEAR,
6030 VK_ATTACHMENT_STORE_OP_STORE,
6031 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6032 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6035 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6036 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6038 vector<AttachmentReference>(),
6039 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6040 vector<AttachmentReference>(),
6041 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6042 vector<deUint32>())),
6043 vector<SubpassDependency>());
6044 const TestConfig testConfig (renderPass,
6045 TestConfig::RENDERTYPES_DRAW,
6046 TestConfig::COMMANDBUFFERTYPES_INLINE,
6047 TestConfig::IMAGEMEMORY_STRICT,
6054 testConfigExternal.allocationKind,
6055 testConfigExternal.renderPassType);
6057 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6060 // color_depth_stencil
6062 const Attachment attachments[] =
6064 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6065 VK_SAMPLE_COUNT_1_BIT,
6066 VK_ATTACHMENT_LOAD_OP_CLEAR,
6067 VK_ATTACHMENT_STORE_OP_STORE,
6068 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6069 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6070 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6071 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6072 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6073 VK_SAMPLE_COUNT_1_BIT,
6074 VK_ATTACHMENT_LOAD_OP_CLEAR,
6075 VK_ATTACHMENT_STORE_OP_STORE,
6076 VK_ATTACHMENT_LOAD_OP_CLEAR,
6077 VK_ATTACHMENT_STORE_OP_STORE,
6078 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6079 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6082 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6083 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6085 vector<AttachmentReference>(),
6086 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6087 vector<AttachmentReference>(),
6088 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6089 vector<deUint32>())),
6090 vector<SubpassDependency>());
6091 const TestConfig testConfig (renderPass,
6092 TestConfig::RENDERTYPES_DRAW,
6093 TestConfig::COMMANDBUFFERTYPES_INLINE,
6094 TestConfig::IMAGEMEMORY_STRICT,
6101 testConfigExternal.allocationKind,
6102 testConfigExternal.renderPassType);
6104 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6109 const RenderPass renderPass (vector<Attachment>(),
6110 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6112 vector<AttachmentReference>(),
6113 vector<AttachmentReference>(),
6114 vector<AttachmentReference>(),
6115 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6116 vector<deUint32>())),
6117 vector<SubpassDependency>());
6118 const TestConfig testConfig (renderPass,
6119 TestConfig::RENDERTYPES_DRAW,
6120 TestConfig::COMMANDBUFFERTYPES_INLINE,
6121 TestConfig::IMAGEMEMORY_STRICT,
6128 testConfigExternal.allocationKind,
6129 testConfigExternal.renderPassType);
6131 addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", "No attachments case.", createTestShaders, renderPassTest, testConfig);
6134 // color_unused_omit_blend_state
6136 vector<Subpass> subpasses;
6138 // First subpass: use color attachment, create pipeline with color blend state
6139 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6141 vector<AttachmentReference>(),
6142 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6143 vector<AttachmentReference>(),
6144 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6148 // Second subpass: don't use color attachment, create pipeline without color blend state
6149 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6151 vector<AttachmentReference>(),
6152 vector<AttachmentReference>(1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6153 vector<AttachmentReference>(),
6154 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6158 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6159 VK_SAMPLE_COUNT_1_BIT,
6160 VK_ATTACHMENT_LOAD_OP_CLEAR,
6161 VK_ATTACHMENT_STORE_OP_STORE,
6162 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6163 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6164 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6165 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6167 vector<SubpassDependency>());
6169 const TestConfig testConfig (renderPass,
6170 TestConfig::RENDERTYPES_DRAW,
6171 TestConfig::COMMANDBUFFERTYPES_INLINE,
6172 TestConfig::IMAGEMEMORY_STRICT,
6179 testConfigExternal.allocationKind,
6180 testConfigExternal.renderPassType);
6181 addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state", "Two unused color attachment case without blend state", createTestShaders, renderPassTest, testConfig);
6185 std::string formatToName (VkFormat format)
6187 const std::string formatStr = de::toString(format);
6188 const std::string prefix = "VK_FORMAT_";
6190 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
6192 return de::toLower(formatStr.substr(prefix.length()));
6195 void addFormatTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6197 tcu::TestContext& testCtx = group->getTestContext();
6199 const UVec2 targetSize (64, 64);
6200 const UVec2 renderPos (0, 0);
6201 const UVec2 renderSize (64, 64);
6205 const char* const str;
6206 const VkAttachmentStoreOp op;
6209 { "store", VK_ATTACHMENT_STORE_OP_STORE },
6210 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
6215 const char* const str;
6216 const VkAttachmentLoadOp op;
6219 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
6220 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
6221 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
6226 const char* const str;
6227 const TestConfig::RenderTypes types;
6230 { "clear", TestConfig::RENDERTYPES_CLEAR },
6231 { "draw", TestConfig::RENDERTYPES_DRAW },
6232 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
6236 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
6238 const VkFormat format = s_coreColorFormats[formatNdx];
6239 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
6241 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6243 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
6244 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6246 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6248 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
6249 VK_SAMPLE_COUNT_1_BIT,
6251 VK_ATTACHMENT_STORE_OP_STORE,
6252 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6253 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6254 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6255 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6256 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6258 vector<AttachmentReference>(),
6259 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6260 vector<AttachmentReference>(),
6261 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6262 vector<deUint32>())),
6263 vector<SubpassDependency>());
6264 const TestConfig testConfig (renderPass,
6265 renderTypes[renderTypeNdx].types,
6266 TestConfig::COMMANDBUFFERTYPES_INLINE,
6267 TestConfig::IMAGEMEMORY_STRICT,
6274 testConfigExternal.allocationKind,
6275 testConfigExternal.renderPassType);
6277 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6280 formatGroup->addChild(loadOpGroup.release());
6284 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
6286 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6288 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
6289 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6291 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
6293 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
6294 ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
6295 : static_cast<VkImageAspectFlags>(0);
6296 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
6297 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
6299 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
6301 const bool useInputAspect = useInputAspectNdx != 0;
6303 if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2 && useInputAspect)
6306 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6309 vector<Attachment> attachments;
6310 vector<Subpass> subpasses;
6311 vector<SubpassDependency> deps;
6312 vector<VkInputAttachmentAspectReference> inputAspects;
6314 attachments.push_back(Attachment(format,
6315 VK_SAMPLE_COUNT_1_BIT,
6318 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6319 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6320 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6321 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6323 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6324 VK_SAMPLE_COUNT_1_BIT,
6325 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6326 VK_ATTACHMENT_STORE_OP_STORE,
6327 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6328 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6329 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6330 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6332 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6334 vector<AttachmentReference>(),
6335 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6336 vector<AttachmentReference>(),
6337 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6338 vector<deUint32>()));
6339 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6341 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6342 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6343 vector<AttachmentReference>(),
6344 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6345 vector<deUint32>()));
6347 deps.push_back(SubpassDependency(0, 1,
6349 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6350 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6352 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6353 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6354 vk::VK_DEPENDENCY_BY_REGION_BIT));
6358 const VkInputAttachmentAspectReference inputAspect =
6362 VK_IMAGE_ASPECT_COLOR_BIT
6365 inputAspects.push_back(inputAspect);
6369 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6370 const TestConfig testConfig (renderPass,
6371 renderTypes[renderTypeNdx].types,
6372 TestConfig::COMMANDBUFFERTYPES_INLINE,
6373 TestConfig::IMAGEMEMORY_STRICT,
6380 testConfigExternal.allocationKind,
6381 testConfigExternal.renderPassType);
6382 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
6384 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6388 vector<Attachment> attachments;
6389 vector<Subpass> subpasses;
6390 vector<SubpassDependency> deps;
6391 vector<VkInputAttachmentAspectReference> inputAspects;
6393 attachments.push_back(Attachment(format,
6394 VK_SAMPLE_COUNT_1_BIT,
6397 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6398 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6399 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6400 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6402 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6404 vector<AttachmentReference>(),
6405 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6406 vector<AttachmentReference>(),
6407 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6408 vector<deUint32>()));
6409 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6411 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
6412 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
6413 vector<AttachmentReference>(),
6414 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6415 vector<deUint32>()));
6417 deps.push_back(SubpassDependency(0, 1,
6418 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6419 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6421 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6422 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6423 vk::VK_DEPENDENCY_BY_REGION_BIT));
6425 deps.push_back(SubpassDependency(1, 1,
6426 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6427 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6429 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6430 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6431 vk::VK_DEPENDENCY_BY_REGION_BIT));
6435 const VkInputAttachmentAspectReference inputAspect =
6439 VK_IMAGE_ASPECT_COLOR_BIT
6442 inputAspects.push_back(inputAspect);
6446 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6447 const TestConfig testConfig (renderPass,
6448 renderTypes[renderTypeNdx].types,
6449 TestConfig::COMMANDBUFFERTYPES_INLINE,
6450 TestConfig::IMAGEMEMORY_STRICT,
6457 testConfigExternal.allocationKind,
6458 testConfigExternal.renderPassType);
6459 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
6461 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6467 loadOpGroup->addChild(storeOpGroup.release());
6470 inputGroup->addChild(loadOpGroup.release());
6473 formatGroup->addChild(inputGroup.release());
6476 group->addChild(formatGroup.release());
6479 // Depth stencil formats
6480 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
6482 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
6483 const tcu::TextureFormat format = mapVkFormat(vkFormat);
6484 const bool isStencilAttachment = hasStencilComponent(format.order);
6485 const bool isDepthAttachment = hasDepthComponent(format.order);
6486 const VkImageAspectFlags formatAspectFlags = (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6487 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
6488 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
6490 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6492 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
6493 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6495 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6498 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
6499 VK_SAMPLE_COUNT_1_BIT,
6500 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6501 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6502 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6503 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6504 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6505 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6506 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6508 vector<AttachmentReference>(),
6509 vector<AttachmentReference>(),
6510 vector<AttachmentReference>(),
6511 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6512 vector<deUint32>())),
6513 vector<SubpassDependency>());
6514 const TestConfig testConfig (renderPass,
6515 renderTypes[renderTypeNdx].types,
6516 TestConfig::COMMANDBUFFERTYPES_INLINE,
6517 TestConfig::IMAGEMEMORY_STRICT,
6524 testConfigExternal.allocationKind,
6525 testConfigExternal.renderPassType);
6527 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6530 if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
6533 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
6534 VK_SAMPLE_COUNT_1_BIT,
6535 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6536 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6537 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6538 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6539 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6540 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6541 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6543 vector<AttachmentReference>(),
6544 vector<AttachmentReference>(),
6545 vector<AttachmentReference>(),
6546 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
6547 vector<deUint32>())),
6548 vector<SubpassDependency>());
6549 const TestConfig testConfig (renderPass,
6550 renderTypes[renderTypeNdx].types,
6551 TestConfig::COMMANDBUFFERTYPES_INLINE,
6552 TestConfig::IMAGEMEMORY_STRICT,
6559 testConfigExternal.allocationKind,
6560 testConfigExternal.renderPassType);
6561 const string testName (string(renderTypes[renderTypeNdx].str) + "_depth_read_only");
6563 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6567 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
6568 VK_SAMPLE_COUNT_1_BIT,
6569 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6570 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6571 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6572 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
6573 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6574 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6575 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6577 vector<AttachmentReference>(),
6578 vector<AttachmentReference>(),
6579 vector<AttachmentReference>(),
6580 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
6581 vector<deUint32>())),
6582 vector<SubpassDependency>());
6583 const TestConfig testConfig (renderPass,
6584 renderTypes[renderTypeNdx].types,
6585 TestConfig::COMMANDBUFFERTYPES_INLINE,
6586 TestConfig::IMAGEMEMORY_STRICT,
6593 testConfigExternal.allocationKind,
6594 testConfigExternal.renderPassType);
6595 const string testName (string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");
6597 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6602 formatGroup->addChild(loadOpGroup.release());
6606 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
6608 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6610 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
6611 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6613 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
6615 const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
6617 : static_cast<VkImageAspectFlags>(0);
6618 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
6619 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
6621 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
6623 const bool useInputAspect = useInputAspectNdx != 0;
6625 if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2 && useInputAspect)
6628 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6631 vector<Attachment> attachments;
6632 vector<Subpass> subpasses;
6633 vector<SubpassDependency> deps;
6634 vector<VkInputAttachmentAspectReference> inputAspects;
6636 attachments.push_back(Attachment(vkFormat,
6637 VK_SAMPLE_COUNT_1_BIT,
6642 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6643 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6645 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6646 VK_SAMPLE_COUNT_1_BIT,
6647 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6648 VK_ATTACHMENT_STORE_OP_STORE,
6649 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6650 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6651 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6652 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6654 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6656 vector<AttachmentReference>(),
6657 vector<AttachmentReference>(),
6658 vector<AttachmentReference>(),
6659 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6660 vector<deUint32>()));
6661 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6663 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6664 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6665 vector<AttachmentReference>(),
6666 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6667 vector<deUint32>()));
6669 deps.push_back(SubpassDependency(0, 1,
6670 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6671 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6673 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6674 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6679 const VkInputAttachmentAspectReference inputAspect =
6683 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6684 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6687 inputAspects.push_back(inputAspect);
6691 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6692 const TestConfig testConfig (renderPass,
6693 renderTypes[renderTypeNdx].types,
6694 TestConfig::COMMANDBUFFERTYPES_INLINE,
6695 TestConfig::IMAGEMEMORY_STRICT,
6702 testConfigExternal.allocationKind,
6703 testConfigExternal.renderPassType);
6704 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
6706 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6710 vector<Attachment> attachments;
6711 vector<Subpass> subpasses;
6712 vector<SubpassDependency> deps;
6713 vector<VkInputAttachmentAspectReference> inputAspects;
6715 attachments.push_back(Attachment(vkFormat,
6716 VK_SAMPLE_COUNT_1_BIT,
6719 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6720 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6721 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6722 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6724 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6726 vector<AttachmentReference>(),
6727 vector<AttachmentReference>(),
6728 vector<AttachmentReference>(),
6729 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6730 vector<deUint32>()));
6731 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6733 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
6734 vector<AttachmentReference>(),
6735 vector<AttachmentReference>(),
6736 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
6737 vector<deUint32>()));
6739 deps.push_back(SubpassDependency(0, 1,
6740 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6741 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6743 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6744 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6745 vk::VK_DEPENDENCY_BY_REGION_BIT));
6747 deps.push_back(SubpassDependency(1, 1,
6748 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6749 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6750 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6751 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6752 vk::VK_DEPENDENCY_BY_REGION_BIT));
6757 const VkInputAttachmentAspectReference inputAspect =
6762 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6763 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6766 inputAspects.push_back(inputAspect);
6770 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6771 const TestConfig testConfig (renderPass,
6772 renderTypes[renderTypeNdx].types,
6773 TestConfig::COMMANDBUFFERTYPES_INLINE,
6774 TestConfig::IMAGEMEMORY_STRICT,
6781 testConfigExternal.allocationKind,
6782 testConfigExternal.renderPassType);
6783 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
6785 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6789 if (isStencilAttachment && isDepthAttachment)
6793 vector<Attachment> attachments;
6794 vector<Subpass> subpasses;
6795 vector<SubpassDependency> deps;
6796 vector<VkInputAttachmentAspectReference> inputAspects;
6798 attachments.push_back(Attachment(vkFormat,
6799 VK_SAMPLE_COUNT_1_BIT,
6804 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6805 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6807 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6808 VK_SAMPLE_COUNT_1_BIT,
6809 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6810 VK_ATTACHMENT_STORE_OP_STORE,
6811 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6812 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6813 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6814 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6816 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6818 vector<AttachmentReference>(),
6819 vector<AttachmentReference>(),
6820 vector<AttachmentReference>(),
6821 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6822 vector<deUint32>()));
6823 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6825 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
6826 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6827 vector<AttachmentReference>(),
6828 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6829 vector<deUint32>()));
6831 deps.push_back(SubpassDependency(0, 1,
6832 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6833 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6835 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6836 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6841 const VkInputAttachmentAspectReference inputAspect =
6846 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6847 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6850 inputAspects.push_back(inputAspect);
6854 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6855 const TestConfig testConfig (renderPass,
6856 renderTypes[renderTypeNdx].types,
6857 TestConfig::COMMANDBUFFERTYPES_INLINE,
6858 TestConfig::IMAGEMEMORY_STRICT,
6865 testConfigExternal.allocationKind,
6866 testConfigExternal.renderPassType);
6867 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
6869 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6873 vector<Attachment> attachments;
6874 vector<Subpass> subpasses;
6875 vector<SubpassDependency> deps;
6876 vector<VkInputAttachmentAspectReference> inputAspects;
6878 attachments.push_back(Attachment(vkFormat,
6879 VK_SAMPLE_COUNT_1_BIT,
6884 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6885 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6887 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6889 vector<AttachmentReference>(),
6890 vector<AttachmentReference>(),
6891 vector<AttachmentReference>(),
6892 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6893 vector<deUint32>()));
6894 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6896 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
6897 vector<AttachmentReference>(),
6898 vector<AttachmentReference>(),
6899 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
6900 vector<deUint32>()));
6902 deps.push_back(SubpassDependency(0, 1,
6903 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6904 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6906 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6907 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6908 vk::VK_DEPENDENCY_BY_REGION_BIT));
6910 deps.push_back(SubpassDependency(1, 1,
6911 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6912 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6914 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6915 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6916 vk::VK_DEPENDENCY_BY_REGION_BIT));
6920 const VkInputAttachmentAspectReference inputAspect =
6925 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6926 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6929 inputAspects.push_back(inputAspect);
6933 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6934 const TestConfig testConfig (renderPass,
6935 renderTypes[renderTypeNdx].types,
6936 TestConfig::COMMANDBUFFERTYPES_INLINE,
6937 TestConfig::IMAGEMEMORY_STRICT,
6944 testConfigExternal.allocationKind,
6945 testConfigExternal.renderPassType);
6946 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
6948 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
6951 // Stencil read only
6953 vector<Attachment> attachments;
6954 vector<Subpass> subpasses;
6955 vector<SubpassDependency> deps;
6956 vector<VkInputAttachmentAspectReference> inputAspects;
6958 attachments.push_back(Attachment(vkFormat,
6959 VK_SAMPLE_COUNT_1_BIT,
6964 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6965 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6967 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6968 VK_SAMPLE_COUNT_1_BIT,
6969 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6970 VK_ATTACHMENT_STORE_OP_STORE,
6971 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6972 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6973 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6974 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6976 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6978 vector<AttachmentReference>(),
6979 vector<AttachmentReference>(),
6980 vector<AttachmentReference>(),
6981 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6982 vector<deUint32>()));
6983 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6985 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6986 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6987 vector<AttachmentReference>(),
6988 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6989 vector<deUint32>()));
6991 deps.push_back(SubpassDependency(0, 1,
6992 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6993 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6995 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6996 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7001 const VkInputAttachmentAspectReference inputAspect =
7006 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7007 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7010 inputAspects.push_back(inputAspect);
7014 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7015 const TestConfig testConfig (renderPass,
7016 renderTypes[renderTypeNdx].types,
7017 TestConfig::COMMANDBUFFERTYPES_INLINE,
7018 TestConfig::IMAGEMEMORY_STRICT,
7025 testConfigExternal.allocationKind,
7026 testConfigExternal.renderPassType);
7027 const string testName (renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7029 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7033 vector<Attachment> attachments;
7034 vector<Subpass> subpasses;
7035 vector<SubpassDependency> deps;
7036 vector<VkInputAttachmentAspectReference> inputAspects;
7038 attachments.push_back(Attachment(vkFormat,
7039 VK_SAMPLE_COUNT_1_BIT,
7044 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7045 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7047 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7049 vector<AttachmentReference>(),
7050 vector<AttachmentReference>(),
7051 vector<AttachmentReference>(),
7052 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7053 vector<deUint32>()));
7054 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7056 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7057 vector<AttachmentReference>(),
7058 vector<AttachmentReference>(),
7059 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7060 vector<deUint32>()));
7062 deps.push_back(SubpassDependency(0, 1,
7063 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7064 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7066 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7067 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7068 vk::VK_DEPENDENCY_BY_REGION_BIT));
7070 deps.push_back(SubpassDependency(1, 1,
7071 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7072 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7074 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7075 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7076 vk::VK_DEPENDENCY_BY_REGION_BIT));
7081 const VkInputAttachmentAspectReference inputAspect =
7086 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7087 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7090 inputAspects.push_back(inputAspect);
7094 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7095 const TestConfig testConfig (renderPass,
7096 renderTypes[renderTypeNdx].types,
7097 TestConfig::COMMANDBUFFERTYPES_INLINE,
7098 TestConfig::IMAGEMEMORY_STRICT,
7105 testConfigExternal.allocationKind,
7106 testConfigExternal.renderPassType);
7107 const string testName (string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7109 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7116 loadOpGroup->addChild(storeOpGroup.release());
7119 inputGroup->addChild(loadOpGroup.release());
7122 formatGroup->addChild(inputGroup.release());
7125 group->addChild(formatGroup.release());
7129 void addRenderPassTests (tcu::TestCaseGroup* group, const AllocationKind allocationKind, const RenderPassType renderPassType)
7131 const TestConfigExternal testConfigExternal (allocationKind, renderPassType);
7133 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, testConfigExternal);
7134 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, testConfigExternal);
7135 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, testConfigExternal);
7136 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, testConfigExternal);
7137 addTestGroup(group, "attachment_write_mask", "Attachment write mask tests", addAttachmentWriteMaskTests, testConfigExternal);
7140 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, RenderPassType renderPassType)
7142 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
7144 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, renderPassType);
7146 return suballocationTestsGroup;
7149 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, RenderPassType renderPassType)
7151 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
7153 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, renderPassType);
7155 return dedicatedAllocationTestsGroup;
7158 tcu::TestCaseGroup* createRenderPassTestsInternal (tcu::TestContext& testCtx, RenderPassType renderPassType)
7160 const char* renderpassTestsGroupName = (renderPassType == RENDERPASS_TYPE_LEGACY) ? "renderpass" :
7161 (renderPassType == RENDERPASS_TYPE_RENDERPASS2) ? "renderpass2" :
7163 const char* renderpassTestsGroupDescription = (renderPassType == RENDERPASS_TYPE_LEGACY) ? "RenderPass Tests" :
7164 (renderPassType == RENDERPASS_TYPE_RENDERPASS2) ? "RenderPass2 Tests" :
7166 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, renderpassTestsGroupName, renderpassTestsGroupDescription));
7167 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx, renderPassType);
7168 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx, renderPassType);
7170 suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassMultisampleTests(testCtx) : createRenderPass2MultisampleTests(testCtx));
7171 suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassMultisampleResolveTests(testCtx) : createRenderPass2MultisampleResolveTests(testCtx));
7172 suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassSubpassDependencyTests(testCtx) : createRenderPass2SubpassDependencyTests(testCtx));
7173 suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassSampleReadTests(testCtx) : createRenderPass2SampleReadTests(testCtx));
7174 suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ? createRenderPassSparseRenderTargetTests(testCtx) : createRenderPass2SparseRenderTargetTests(testCtx));
7175 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderPassType));
7176 suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, renderPassType));
7177 suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderPassType));
7179 renderpassTests->addChild(suballocationTestGroup.release());
7180 renderpassTests->addChild(dedicatedAllocationTestGroup.release());
7181 renderpassTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));
7183 if (renderPassType != RENDERPASS_TYPE_LEGACY)
7185 renderpassTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
7186 renderpassTests->addChild(createFragmentDensityMapTests(testCtx));
7189 return renderpassTests.release();
7194 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
7196 return createRenderPassTestsInternal(testCtx, RENDERPASS_TYPE_LEGACY);
7199 tcu::TestCaseGroup* createRenderPass2Tests (tcu::TestContext& testCtx)
7201 return createRenderPassTestsInternal(testCtx, RENDERPASS_TYPE_RENDERPASS2);