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:
@ -88,11 +88,13 @@ std::unique_ptr<AbstractPipeline> VKGfx::CreatePipeline(const AbstractPipelineCo
|
||||
return VKPipeline::Create(config);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractFramebuffer> VKGfx::CreateFramebuffer(AbstractTexture* color_attachment,
|
||||
AbstractTexture* depth_attachment)
|
||||
std::unique_ptr<AbstractFramebuffer>
|
||||
VKGfx::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment,
|
||||
std::vector<AbstractTexture*> additional_color_attachments)
|
||||
{
|
||||
return VKFramebuffer::Create(static_cast<VKTexture*>(color_attachment),
|
||||
static_cast<VKTexture*>(depth_attachment));
|
||||
static_cast<VKTexture*>(depth_attachment),
|
||||
std::move(additional_color_attachments));
|
||||
}
|
||||
|
||||
void VKGfx::SetPipeline(const AbstractPipeline* pipeline)
|
||||
@ -138,12 +140,12 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
|
||||
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLEAR_LOADOP_RENDERPASS))
|
||||
use_clear_render_pass = false;
|
||||
|
||||
auto* vk_frame_buffer = static_cast<VKFramebuffer*>(m_current_framebuffer);
|
||||
|
||||
// Fastest path: Use a render pass to clear the buffers.
|
||||
if (use_clear_render_pass)
|
||||
{
|
||||
const std::array<VkClearValue, 2> clear_values = {{clear_color_value, clear_depth_value}};
|
||||
StateTracker::GetInstance()->BeginClearRenderPass(target_vk_rc, clear_values.data(),
|
||||
static_cast<u32>(clear_values.size()));
|
||||
vk_frame_buffer->SetAndClear(target_vk_rc, clear_color_value, clear_depth_value);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -151,26 +153,40 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
|
||||
// We can't use this when preserving alpha but clearing color.
|
||||
if (use_clear_attachments)
|
||||
{
|
||||
VkClearAttachment clear_attachments[2];
|
||||
uint32_t num_clear_attachments = 0;
|
||||
std::vector<VkClearAttachment> clear_attachments;
|
||||
bool has_color = false;
|
||||
if (color_enable && alpha_enable)
|
||||
{
|
||||
clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
clear_attachments[num_clear_attachments].colorAttachment = 0;
|
||||
clear_attachments[num_clear_attachments].clearValue = clear_color_value;
|
||||
num_clear_attachments++;
|
||||
VkClearAttachment clear_attachment;
|
||||
clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
clear_attachment.colorAttachment = 0;
|
||||
clear_attachment.clearValue = clear_color_value;
|
||||
clear_attachments.push_back(std::move(clear_attachment));
|
||||
color_enable = false;
|
||||
alpha_enable = false;
|
||||
has_color = true;
|
||||
}
|
||||
if (z_enable)
|
||||
{
|
||||
clear_attachments[num_clear_attachments].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
clear_attachments[num_clear_attachments].colorAttachment = 0;
|
||||
clear_attachments[num_clear_attachments].clearValue = clear_depth_value;
|
||||
num_clear_attachments++;
|
||||
VkClearAttachment clear_attachment;
|
||||
clear_attachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
clear_attachment.colorAttachment = 0;
|
||||
clear_attachment.clearValue = clear_depth_value;
|
||||
clear_attachments.push_back(std::move(clear_attachment));
|
||||
z_enable = false;
|
||||
}
|
||||
if (num_clear_attachments > 0)
|
||||
if (has_color)
|
||||
{
|
||||
for (std::size_t i = 0; i < vk_frame_buffer->GetNumberOfAdditonalAttachments(); i++)
|
||||
{
|
||||
VkClearAttachment clear_attachment;
|
||||
clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
clear_attachment.colorAttachment = 0;
|
||||
clear_attachment.clearValue = clear_color_value;
|
||||
clear_attachments.push_back(std::move(clear_attachment));
|
||||
}
|
||||
}
|
||||
if (!clear_attachments.empty())
|
||||
{
|
||||
VkClearRect vk_rect = {target_vk_rc, 0, g_framebuffer_manager->GetEFBLayers()};
|
||||
if (!StateTracker::GetInstance()->IsWithinRenderArea(
|
||||
@ -181,8 +197,9 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
|
||||
}
|
||||
StateTracker::GetInstance()->BeginRenderPass();
|
||||
|
||||
vkCmdClearAttachments(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_clear_attachments,
|
||||
clear_attachments, 1, &vk_rect);
|
||||
vkCmdClearAttachments(g_command_buffer_mgr->GetCurrentCommandBuffer(),
|
||||
static_cast<uint32_t>(clear_attachments.size()),
|
||||
clear_attachments.data(), 1, &vk_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,16 +422,7 @@ void VKGfx::BindFramebuffer(VKFramebuffer* fb)
|
||||
StateTracker::GetInstance()->EndRenderPass();
|
||||
|
||||
// Shouldn't be bound as a texture.
|
||||
if (fb->GetColorAttachment())
|
||||
{
|
||||
StateTracker::GetInstance()->UnbindTexture(
|
||||
static_cast<VKTexture*>(fb->GetColorAttachment())->GetView());
|
||||
}
|
||||
if (fb->GetDepthAttachment())
|
||||
{
|
||||
StateTracker::GetInstance()->UnbindTexture(
|
||||
static_cast<VKTexture*>(fb->GetDepthAttachment())->GetView());
|
||||
}
|
||||
fb->Unbind();
|
||||
|
||||
fb->TransitionForRender();
|
||||
StateTracker::GetInstance()->SetFramebuffer(fb);
|
||||
@ -449,22 +457,13 @@ void VKGfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const Clear
|
||||
VKFramebuffer* vkfb = static_cast<VKFramebuffer*>(framebuffer);
|
||||
BindFramebuffer(vkfb);
|
||||
|
||||
std::array<VkClearValue, 2> clear_values;
|
||||
u32 num_clear_values = 0;
|
||||
if (vkfb->GetColorFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
std::memcpy(clear_values[num_clear_values].color.float32, color_value.data(),
|
||||
sizeof(clear_values[num_clear_values].color.float32));
|
||||
num_clear_values++;
|
||||
}
|
||||
if (vkfb->GetDepthFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
clear_values[num_clear_values].depthStencil.depth = depth_value;
|
||||
clear_values[num_clear_values].depthStencil.stencil = 0;
|
||||
num_clear_values++;
|
||||
}
|
||||
StateTracker::GetInstance()->BeginClearRenderPass(vkfb->GetRect(), clear_values.data(),
|
||||
num_clear_values);
|
||||
VkClearValue clear_color_value;
|
||||
std::memcpy(clear_color_value.color.float32, color_value.data(),
|
||||
sizeof(clear_color_value.color.float32));
|
||||
VkClearValue clear_depth_value;
|
||||
clear_depth_value.depthStencil.depth = depth_value;
|
||||
clear_depth_value.depthStencil.stencil = 0;
|
||||
vkfb->SetAndClear(vkfb->GetRect(), clear_color_value, clear_depth_value);
|
||||
}
|
||||
|
||||
void VKGfx::SetTexture(u32 index, const AbstractTexture* texture)
|
||||
|
Reference in New Issue
Block a user