blob: 55a9a4454405b9c9269c4ffe3765d98b47075703 [file] [edit]
/*
* 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
*/
#include "render_pass_helper.h"
RenderPassHelperBase::RenderPassHelperBase(VkLayerTest& test, vkt::Device* device) {
// default VkDevice, can be overwritten if multi-device tests
device_ = device ? device : test.DeviceObj();
}
RenderPassSingleSubpass::RenderPassSingleSubpass(VkLayerTest& test, vkt::Device* device) : RenderPassHelperBase(test, device) {
subpass_description_ = {};
subpass_description_.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
rp_create_info_ = vku::InitStructHelper();
rp_create_info_.subpassCount = 1;
rp_create_info_.pSubpasses = &subpass_description_;
}
VkRenderPassCreateInfo RenderPassSingleSubpass::GetCreateInfo() {
rp_create_info_.attachmentCount = attachment_descriptions_.size();
rp_create_info_.pAttachments = attachment_descriptions_.data();
rp_create_info_.pDependencies = subpass_dependencies_.data();
return rp_create_info_;
}
void RenderPassSingleSubpass::AddAttachmentDescription(VkFormat format, VkImageLayout initialLayout, VkImageLayout finalLayout,
VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp) {
attachment_descriptions_.emplace_back(VkAttachmentDescription{0, format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout, finalLayout});
}
void RenderPassSingleSubpass::AddAttachmentDescription(VkFormat format, VkSampleCountFlagBits samples, VkImageLayout initialLayout,
VkImageLayout finalLayout) {
attachment_descriptions_.emplace_back(VkAttachmentDescription{0, format, samples, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE, initialLayout, finalLayout});
}
void RenderPassSingleSubpass::AddAttachmentDescription(const VkAttachmentDescription& attachment_description) {
attachment_descriptions_.emplace_back(attachment_description);
}
void RenderPassSingleSubpass::AddInputAttachment(uint32_t attachment_index, VkImageLayout layout) {
input_attachments_.push_back({attachment_index, layout});
subpass_description_.inputAttachmentCount = uint32_t(input_attachments_.size());
subpass_description_.pInputAttachments = input_attachments_.data();
}
void RenderPassSingleSubpass::AddColorAttachment(uint32_t attachment_index, VkImageLayout layout) {
color_attachments_.push_back({attachment_index, layout});
subpass_description_.colorAttachmentCount = uint32_t(color_attachments_.size());
subpass_description_.pColorAttachments = color_attachments_.data();
}
void RenderPassSingleSubpass::AddResolveAttachment(uint32_t attachment_index, VkImageLayout layout) {
resolve_attachment_ = {attachment_index, layout};
subpass_description_.pResolveAttachments = &resolve_attachment_;
}
void RenderPassSingleSubpass::AddDepthStencilAttachment(uint32_t attachment_index, VkImageLayout layout) {
ds_attachment_ = {attachment_index, layout};
subpass_description_.pDepthStencilAttachment = &ds_attachment_;
}
void RenderPassSingleSubpass::AddSubpassDependency(VkSubpassDependency dependency) {
subpass_dependencies_.push_back(dependency);
rp_create_info_.dependencyCount = (uint32_t)subpass_dependencies_.size();
}
void RenderPassSingleSubpass::AddSubpassSelfDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
VkDependencyFlags dependencyFlags) {
VkSubpassDependency subpass_dependency{};
subpass_dependency.srcSubpass = 0;
subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = srcStageMask;
subpass_dependency.srcStageMask = srcStageMask;
subpass_dependency.dstStageMask = dstStageMask;
subpass_dependency.srcAccessMask = srcAccessMask;
subpass_dependency.dstAccessMask = dstAccessMask;
subpass_dependency.dependencyFlags = dependencyFlags;
AddSubpassDependency(subpass_dependency);
}
void RenderPassSingleSubpass::CreateRenderPass(void* pNext, VkRenderPassCreateFlags flags) {
VkRenderPassCreateInfo rp_create_info = GetCreateInfo();
rp_create_info.pNext = pNext;
rp_create_info.flags = flags;
render_pass_.Init(*device_, rp_create_info);
}
RenderPass2SingleSubpass::RenderPass2SingleSubpass(VkLayerTest& test, vkt::Device* device) : RenderPassHelperBase(test, device) {
subpass_description_ = vku::InitStructHelper();
subpass_description_.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
rp_create_info_ = vku::InitStructHelper();
rp_create_info_.subpassCount = 1;
rp_create_info_.pSubpasses = &subpass_description_;
}
VkRenderPassCreateInfo2 RenderPass2SingleSubpass::GetCreateInfo() {
rp_create_info_.attachmentCount = attachment_descriptions_.size();
rp_create_info_.pAttachments = attachment_descriptions_.data();
rp_create_info_.pDependencies = subpass_dependencies_.data();
return rp_create_info_;
}
void RenderPass2SingleSubpass::AddAttachmentDescription(VkFormat format, VkImageLayout initialLayout, VkImageLayout finalLayout,
VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp) {
attachment_descriptions_.push_back(vku::InitStruct<VkAttachmentDescription2>(
nullptr, 0u, format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE, initialLayout, finalLayout));
}
void RenderPass2SingleSubpass::AddAttachmentDescription(VkFormat format, VkSampleCountFlagBits samples, VkImageLayout initialLayout,
VkImageLayout finalLayout) {
attachment_descriptions_.push_back(vku::InitStruct<VkAttachmentDescription2>(
nullptr, 0u, format, samples, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, initialLayout, finalLayout));
}
void RenderPass2SingleSubpass::SetAttachmentDescriptionPNext(uint32_t index, void* pNext) {
attachment_descriptions_[index].pNext = pNext;
}
void RenderPass2SingleSubpass::AddInputAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask,
void* pNext) {
VkAttachmentReference2 attachment_ref = vku::InitStructHelper(pNext);
attachment_ref.attachment = attachment_index;
attachment_ref.layout = layout;
attachment_ref.aspectMask = aspect_mask;
input_attachments_.push_back(attachment_ref);
subpass_description_.inputAttachmentCount = input_attachments_.size();
subpass_description_.pInputAttachments = input_attachments_.data();
}
void RenderPass2SingleSubpass::AddColorAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask,
void* pNext) {
VkAttachmentReference2 attachment_ref = vku::InitStructHelper(pNext);
attachment_ref.attachment = attachment_index;
attachment_ref.layout = layout;
attachment_ref.aspectMask = aspect_mask;
color_attachments_.push_back(attachment_ref);
subpass_description_.colorAttachmentCount = color_attachments_.size();
subpass_description_.pColorAttachments = color_attachments_.data();
}
void RenderPass2SingleSubpass::AddResolveAttachment(uint32_t attachment_index, VkImageLayout layout, VkImageAspectFlags aspect_mask,
void* pNext) {
resolve_attachment_ = vku::InitStructHelper(pNext);
resolve_attachment_.attachment = attachment_index;
resolve_attachment_.layout = layout;
resolve_attachment_.aspectMask = aspect_mask;
subpass_description_.pResolveAttachments = &resolve_attachment_;
}
void RenderPass2SingleSubpass::AddDepthStencilAttachment(uint32_t attachment_index, VkImageLayout layout,
VkImageAspectFlags aspect_mask, void* pNext) {
ds_attachment_ = vku::InitStructHelper(pNext);
ds_attachment_.attachment = attachment_index;
ds_attachment_.layout = layout;
ds_attachment_.aspectMask = aspect_mask;
subpass_description_.pDepthStencilAttachment = &ds_attachment_;
}
void RenderPass2SingleSubpass::AddDepthStencilResolveAttachment(uint32_t attachment_index, VkImageLayout layout,
VkResolveModeFlagBits depth_resolve_mode,
VkResolveModeFlagBits stencil_resolve_mode) {
ds_resolve_attachment_ = vku::InitStructHelper();
ds_resolve_attachment_.attachment = attachment_index;
ds_resolve_attachment_.layout = layout;
ds_resolve_ = vku::InitStructHelper();
ds_resolve_.pDepthStencilResolveAttachment = &ds_resolve_attachment_;
ds_resolve_.depthResolveMode = depth_resolve_mode;
ds_resolve_.stencilResolveMode = stencil_resolve_mode;
subpass_description_.pNext = &ds_resolve_;
}
void RenderPass2SingleSubpass::AddFragmentShadingRateAttachment(uint32_t attachment_index, VkImageLayout layout,
VkExtent2D texel_size) {
fsr_attachment_ = vku::InitStructHelper();
fsr_attachment_.attachment = attachment_index;
fsr_attachment_.layout = layout;
fsr_attachment_info_ = vku::InitStructHelper();
fsr_attachment_info_.pFragmentShadingRateAttachment = &fsr_attachment_;
fsr_attachment_info_.shadingRateAttachmentTexelSize = texel_size;
subpass_description_.pNext = &fsr_attachment_info_;
}
void RenderPass2SingleSubpass::AddSubpassDependency(VkSubpassDependency2 dependency) {
subpass_dependencies_.push_back(dependency);
rp_create_info_.dependencyCount = (uint32_t)subpass_dependencies_.size();
}
void RenderPass2SingleSubpass::AddSubpassSelfDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
VkDependencyFlags dependencyFlags) {
VkSubpassDependency2 subpass_dependency = vku::InitStructHelper();
subpass_dependency.srcSubpass = 0;
subpass_dependency.dstSubpass = 0;
subpass_dependency.srcStageMask = srcStageMask;
subpass_dependency.srcStageMask = srcStageMask;
subpass_dependency.dstStageMask = dstStageMask;
subpass_dependency.srcAccessMask = srcAccessMask;
subpass_dependency.dstAccessMask = dstAccessMask;
subpass_dependency.dependencyFlags = dependencyFlags;
AddSubpassDependency(subpass_dependency);
}
void RenderPass2SingleSubpass::CreateRenderPass(void* pNext, VkRenderPassCreateFlags flags) {
VkRenderPassCreateInfo2 rp_create_info = GetCreateInfo();
rp_create_info.pNext = pNext;
rp_create_info.flags = flags;
render_pass_.Init(*device_, rp_create_info);
}