| /* |
| * Copyright (c) 2023-2026 The Khronos Group Inc. |
| * Copyright (c) 2023-2026 Valve Corporation |
| * Copyright (c) 2023-2026 LunarG, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #pragma once |
| |
| #include "layer_validation_tests.h" |
| #include <vector> |
| |
| class RenderPassHelperBase { |
| public: |
| RenderPassHelperBase(VkLayerTest &test, vkt::Device *device = nullptr); |
| ~RenderPassHelperBase() { Destroy(); } |
| |
| const VkRenderPass &Handle() const { return render_pass_.handle(); } |
| operator VkRenderPass() const { return render_pass_; } |
| |
| // Explicit destroy for those tests that need to test render pass lifetime |
| void Destroy() { render_pass_.Destroy(); }; |
| |
| protected: |
| vkt::Device *device_; |
| vkt::RenderPass render_pass_; |
| }; |
| |
| // Helper designed to quickly make a renderPass/framebuffer that only has a single Subpass. |
| // |
| // Common usage: |
| // RenderPassSingleSubpass rp(*this); |
| // rp.AddAttachmentDescription(input_format); // add attachment description 0 |
| // rp.AddAttachmentDescription(color_format); // add attachment description 1 |
| // rp.AddInputAttachment(0, VK_IMAGE_LAYOUT_GENERAL); // input attachment based on attachment description 0 |
| // rp.AddColorAttachment(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // color attachment bazsed on attachment description 1 |
| // rp.CreateRenderPass(); |
| class RenderPassSingleSubpass : public RenderPassHelperBase { |
| public: |
| RenderPassSingleSubpass(VkLayerTest &test, vkt::Device *device = nullptr); |
| |
| VkRenderPassCreateInfo GetCreateInfo(); |
| |
| // Ordered from most likely to be custom vs will use defauly |
| void AddAttachmentDescription(VkFormat format, VkImageLayout initialLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkImageLayout finalLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE); |
| // Overload for setting sampler count |
| void AddAttachmentDescription(VkFormat format, VkSampleCountFlagBits samples, |
| VkImageLayout initialLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkImageLayout finalLayout = VK_IMAGE_LAYOUT_GENERAL); |
| // Use already initialized object |
| void AddAttachmentDescription(const VkAttachmentDescription& attachment_description); |
| |
| // Pass in index to attachment description |
| void AddInputAttachment(uint32_t attachment_index, VkImageLayout layout); |
| void AddColorAttachment(uint32_t attachment_index, VkImageLayout layout); |
| void AddResolveAttachment(uint32_t attachment_index, VkImageLayout layout); |
| void AddDepthStencilAttachment(uint32_t attachment_index, VkImageLayout layout); |
| |
| void AddSubpassDependency(VkSubpassDependency dependency); |
| void AddSubpassSelfDependency(VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VkDependencyFlags dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT); |
| |
| void CreateRenderPass(void *pNext = nullptr, VkRenderPassCreateFlags flags = 0); |
| |
| private: |
| VkRenderPassCreateInfo rp_create_info_; |
| |
| std::vector<VkAttachmentDescription> attachment_descriptions_; |
| std::vector<VkAttachmentReference> input_attachments_; |
| std::vector<VkAttachmentReference> color_attachments_; |
| VkAttachmentReference resolve_attachment_; |
| VkAttachmentReference ds_attachment_; |
| |
| VkSubpassDescription subpass_description_; |
| std::vector<VkSubpassDependency> subpass_dependencies_; |
| }; |
| |
| // Helper for vkCreateRenderPass2 API, works similar to RenderPassSingleSubpass |
| class RenderPass2SingleSubpass : public RenderPassHelperBase { |
| public: |
| RenderPass2SingleSubpass(VkLayerTest &test, vkt::Device *device = nullptr); |
| |
| VkRenderPassCreateInfo2 GetCreateInfo(); |
| |
| // Ordered from most likely to be custom vs will use defauly |
| void AddAttachmentDescription(VkFormat format, VkImageLayout initialLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkImageLayout finalLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, |
| VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE); |
| // Overload for setting sampler count |
| void AddAttachmentDescription(VkFormat format, VkSampleCountFlagBits samples, |
| VkImageLayout initialLayout = VK_IMAGE_LAYOUT_GENERAL, |
| VkImageLayout finalLayout = VK_IMAGE_LAYOUT_GENERAL); |
| |
| // Have a seperate set function to keep AddAttachmentDescription simple (very few things extend the AttachmentDescription) |
| void SetAttachmentDescriptionPNext(uint32_t index, void *pNext); |
| |
| // Pass in index to attachment description |
| void AddInputAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask = 0, |
| void *pNext = nullptr); |
| void AddColorAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask = 0, |
| void *pNext = nullptr); |
| void AddResolveAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask = 0, |
| void *pNext = nullptr); |
| void AddDepthStencilAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask = 0, |
| void *pNext = nullptr); |
| // VK_KHR_depth_stencil_resolve |
| void AddDepthStencilResolveAttachment(uint32_t attachment_index, VkImageLayout layout, VkResolveModeFlagBits depth_resolve_mode, |
| VkResolveModeFlagBits stencil_resolve_mode); |
| // VK_KHR_fragment_shading_rate |
| void AddFragmentShadingRateAttachment(uint32_t attachment_index, VkImageLayout layout, VkExtent2D texel_size); |
| |
| void SetViewMask(uint32_t view_mask) { subpass_description_.viewMask = view_mask; } |
| |
| void AddSubpassDependency(VkSubpassDependency2 dependency); |
| void AddSubpassSelfDependency(VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VkDependencyFlags dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT); |
| |
| void CreateRenderPass(void *pNext = nullptr, VkRenderPassCreateFlags flags = 0); |
| |
| private: |
| VkRenderPassCreateInfo2 rp_create_info_; |
| |
| std::vector<VkAttachmentDescription2> attachment_descriptions_; |
| std::vector<VkAttachmentReference2> input_attachments_; |
| std::vector<VkAttachmentReference2> color_attachments_; |
| VkAttachmentReference2 resolve_attachment_; |
| VkAttachmentReference2 ds_attachment_; |
| |
| VkSubpassDescriptionDepthStencilResolve ds_resolve_; |
| VkAttachmentReference2 ds_resolve_attachment_; |
| |
| VkFragmentShadingRateAttachmentInfoKHR fsr_attachment_info_; |
| VkAttachmentReference2 fsr_attachment_; |
| |
| VkSubpassDescription2 subpass_description_; |
| std::vector<VkSubpassDependency2> subpass_dependencies_; |
| }; |