mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
VideoBackends: add support to allow rendering to multiple output textures
This commit is contained in:
@ -982,12 +982,13 @@ void VKStagingTexture::Flush()
|
||||
m_needs_flush = false;
|
||||
}
|
||||
|
||||
VKFramebuffer::VKFramebuffer(VKTexture* color_attachment, VKTexture* depth_attachment, u32 width,
|
||||
VKFramebuffer::VKFramebuffer(VKTexture* color_attachment, VKTexture* depth_attachment,
|
||||
std::vector<AbstractTexture*> additional_color_attachments, u32 width,
|
||||
u32 height, u32 layers, u32 samples, VkFramebuffer fb,
|
||||
VkRenderPass load_render_pass, VkRenderPass discard_render_pass,
|
||||
VkRenderPass clear_render_pass)
|
||||
: AbstractFramebuffer(
|
||||
color_attachment, depth_attachment,
|
||||
color_attachment, depth_attachment, std::move(additional_color_attachments),
|
||||
color_attachment ? color_attachment->GetFormat() : AbstractTextureFormat::Undefined,
|
||||
depth_attachment ? depth_attachment->GetFormat() : AbstractTextureFormat::Undefined,
|
||||
width, height, layers, samples),
|
||||
@ -1001,10 +1002,11 @@ VKFramebuffer::~VKFramebuffer()
|
||||
g_command_buffer_mgr->DeferFramebufferDestruction(m_fb);
|
||||
}
|
||||
|
||||
std::unique_ptr<VKFramebuffer> VKFramebuffer::Create(VKTexture* color_attachment,
|
||||
VKTexture* depth_attachment)
|
||||
std::unique_ptr<VKFramebuffer>
|
||||
VKFramebuffer::Create(VKTexture* color_attachment, VKTexture* depth_attachment,
|
||||
std::vector<AbstractTexture*> additional_color_attachments)
|
||||
{
|
||||
if (!ValidateConfig(color_attachment, depth_attachment))
|
||||
if (!ValidateConfig(color_attachment, depth_attachment, additional_color_attachments))
|
||||
return nullptr;
|
||||
|
||||
const VkFormat vk_color_format =
|
||||
@ -1017,21 +1019,27 @@ std::unique_ptr<VKFramebuffer> VKFramebuffer::Create(VKTexture* color_attachment
|
||||
const u32 layers = either_attachment->GetLayers();
|
||||
const u32 samples = either_attachment->GetSamples();
|
||||
|
||||
std::array<VkImageView, 2> attachment_views{};
|
||||
u32 num_attachments = 0;
|
||||
|
||||
std::vector<VkImageView> attachment_views;
|
||||
if (color_attachment)
|
||||
attachment_views[num_attachments++] = color_attachment->GetView();
|
||||
attachment_views.push_back(color_attachment->GetView());
|
||||
|
||||
if (depth_attachment)
|
||||
attachment_views[num_attachments++] = depth_attachment->GetView();
|
||||
attachment_views.push_back(depth_attachment->GetView());
|
||||
|
||||
for (auto* attachment : additional_color_attachments)
|
||||
{
|
||||
attachment_views.push_back(static_cast<VKTexture*>(attachment)->GetView());
|
||||
}
|
||||
|
||||
VkRenderPass load_render_pass = g_object_cache->GetRenderPass(
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_LOAD);
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
static_cast<u8>(additional_color_attachments.size()));
|
||||
VkRenderPass discard_render_pass = g_object_cache->GetRenderPass(
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
static_cast<u8>(additional_color_attachments.size()));
|
||||
VkRenderPass clear_render_pass = g_object_cache->GetRenderPass(
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||
vk_color_format, vk_depth_format, samples, VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
static_cast<u8>(additional_color_attachments.size()));
|
||||
if (load_render_pass == VK_NULL_HANDLE || discard_render_pass == VK_NULL_HANDLE ||
|
||||
clear_render_pass == VK_NULL_HANDLE)
|
||||
{
|
||||
@ -1042,7 +1050,7 @@ std::unique_ptr<VKFramebuffer> VKFramebuffer::Create(VKTexture* color_attachment
|
||||
nullptr,
|
||||
0,
|
||||
load_render_pass,
|
||||
num_attachments,
|
||||
static_cast<uint32_t>(attachment_views.size()),
|
||||
attachment_views.data(),
|
||||
width,
|
||||
height,
|
||||
@ -1057,9 +1065,27 @@ std::unique_ptr<VKFramebuffer> VKFramebuffer::Create(VKTexture* color_attachment
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<VKFramebuffer>(color_attachment, depth_attachment, width, height, layers,
|
||||
samples, fb, load_render_pass, discard_render_pass,
|
||||
clear_render_pass);
|
||||
return std::make_unique<VKFramebuffer>(
|
||||
color_attachment, depth_attachment, std::move(additional_color_attachments), width, height,
|
||||
layers, samples, fb, load_render_pass, discard_render_pass, clear_render_pass);
|
||||
}
|
||||
|
||||
void VKFramebuffer::Unbind()
|
||||
{
|
||||
if (m_color_attachment)
|
||||
{
|
||||
StateTracker::GetInstance()->UnbindTexture(
|
||||
static_cast<VKTexture*>(m_color_attachment)->GetView());
|
||||
}
|
||||
for (auto* attachment : m_additional_color_attachments)
|
||||
{
|
||||
StateTracker::GetInstance()->UnbindTexture(static_cast<VKTexture*>(attachment)->GetView());
|
||||
}
|
||||
if (m_depth_attachment)
|
||||
{
|
||||
StateTracker::GetInstance()->UnbindTexture(
|
||||
static_cast<VKTexture*>(m_depth_attachment)->GetView());
|
||||
}
|
||||
}
|
||||
|
||||
void VKFramebuffer::TransitionForRender()
|
||||
@ -1070,6 +1096,12 @@ void VKFramebuffer::TransitionForRender()
|
||||
->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
for (auto* attachment : m_additional_color_attachments)
|
||||
{
|
||||
static_cast<VKTexture*>(attachment)
|
||||
->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
|
||||
if (m_depth_attachment)
|
||||
{
|
||||
@ -1078,4 +1110,24 @@ void VKFramebuffer::TransitionForRender()
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void VKFramebuffer::SetAndClear(const VkRect2D& rect, const VkClearValue& color_value,
|
||||
const VkClearValue& depth_value)
|
||||
{
|
||||
std::vector<VkClearValue> clear_values;
|
||||
if (GetColorFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
clear_values.push_back(color_value);
|
||||
}
|
||||
if (GetDepthFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
clear_values.push_back(depth_value);
|
||||
}
|
||||
for (std::size_t i = 0; i < m_additional_color_attachments.size(); i++)
|
||||
{
|
||||
clear_values.push_back(color_value);
|
||||
}
|
||||
StateTracker::GetInstance()->BeginClearRenderPass(rect, clear_values.data(),
|
||||
static_cast<u32>(clear_values.size()));
|
||||
}
|
||||
} // namespace Vulkan
|
||||
|
Reference in New Issue
Block a user