VideoBackends: add support to allow rendering to multiple output textures

This commit is contained in:
iwubcode
2023-05-28 20:59:02 -05:00
parent 252d3f353a
commit 834f8f7b5c
43 changed files with 713 additions and 327 deletions

View File

@ -59,11 +59,13 @@ std::unique_ptr<AbstractStagingTexture> Gfx::CreateStagingTexture(StagingTexture
return DXStagingTexture::Create(type, config);
}
std::unique_ptr<AbstractFramebuffer> Gfx::CreateFramebuffer(AbstractTexture* color_attachment,
AbstractTexture* depth_attachment)
std::unique_ptr<AbstractFramebuffer>
Gfx::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment,
std::vector<AbstractTexture*> additional_color_attachments)
{
return DXFramebuffer::Create(static_cast<DXTexture*>(color_attachment),
static_cast<DXTexture*>(depth_attachment));
static_cast<DXTexture*>(depth_attachment),
std::move(additional_color_attachments));
}
std::unique_ptr<AbstractShader>
@ -109,20 +111,18 @@ void Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_enab
if (fast_color_clear || z_enable)
{
const D3D12_RECT d3d_clear_rc{target_rc.left, target_rc.top, target_rc.right, target_rc.bottom};
auto* d3d_frame_buffer = static_cast<const DXFramebuffer*>(m_current_framebuffer);
if (fast_color_clear)
{
static_cast<DXTexture*>(m_current_framebuffer->GetColorAttachment())
->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
d3d_frame_buffer->TransitionRenderTargets();
const std::array<float, 4> clear_color = {
{static_cast<float>((color >> 16) & 0xFF) / 255.0f,
static_cast<float>((color >> 8) & 0xFF) / 255.0f,
static_cast<float>((color >> 0) & 0xFF) / 255.0f,
static_cast<float>((color >> 24) & 0xFF) / 255.0f}};
g_dx_context->GetCommandList()->ClearRenderTargetView(
static_cast<const DXFramebuffer*>(m_current_framebuffer)->GetRTVDescriptor().cpu_handle,
clear_color.data(), 1, &d3d_clear_rc);
d3d_frame_buffer->ClearRenderTargets(clear_color, &d3d_clear_rc);
color_enable = false;
alpha_enable = false;
}
@ -134,9 +134,7 @@ void Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_enab
// D3D does not support reversed depth ranges.
const float clear_depth = 1.0f - static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
g_dx_context->GetCommandList()->ClearDepthStencilView(
static_cast<const DXFramebuffer*>(m_current_framebuffer)->GetDSVDescriptor().cpu_handle,
D3D12_CLEAR_FLAG_DEPTH, clear_depth, 0, 1, &d3d_clear_rc);
d3d_frame_buffer->ClearDepth(clear_depth, &d3d_clear_rc);
z_enable = false;
}
}
@ -180,11 +178,7 @@ void Gfx::SetPipeline(const AbstractPipeline* pipeline)
void Gfx::BindFramebuffer(DXFramebuffer* fb)
{
if (fb->HasColorBuffer())
{
static_cast<DXTexture*>(fb->GetColorAttachment())
->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
}
fb->TransitionRenderTargets();
if (fb->HasDepthBuffer())
{
static_cast<DXTexture*>(fb->GetDepthAttachment())
@ -212,19 +206,14 @@ void Gfx::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
{
SetFramebuffer(framebuffer);
static const D3D12_DISCARD_REGION dr = {0, nullptr, 0, 1};
if (framebuffer->HasColorBuffer())
DXFramebuffer* d3d_frame_buffer = static_cast<DXFramebuffer*>(framebuffer);
d3d_frame_buffer->TransitionRenderTargets();
if (d3d_frame_buffer->HasDepthBuffer())
{
DXTexture* color_attachment = static_cast<DXTexture*>(framebuffer->GetColorAttachment());
color_attachment->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
g_dx_context->GetCommandList()->DiscardResource(color_attachment->GetResource(), &dr);
}
if (framebuffer->HasDepthBuffer())
{
DXTexture* depth_attachment = static_cast<DXTexture*>(framebuffer->GetDepthAttachment());
depth_attachment->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
g_dx_context->GetCommandList()->DiscardResource(depth_attachment->GetResource(), &dr);
static_cast<DXTexture*>(d3d_frame_buffer->GetDepthAttachment())
->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
}
d3d_frame_buffer->Unbind();
}
void Gfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const ClearColor& color_value,
@ -233,17 +222,8 @@ void Gfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const ClearCo
DXFramebuffer* dxfb = static_cast<DXFramebuffer*>(framebuffer);
BindFramebuffer(dxfb);
static const D3D12_DISCARD_REGION dr = {0, nullptr, 0, 1};
if (framebuffer->HasColorBuffer())
{
g_dx_context->GetCommandList()->ClearRenderTargetView(dxfb->GetRTVDescriptor().cpu_handle,
color_value.data(), 0, nullptr);
}
if (framebuffer->HasDepthBuffer())
{
g_dx_context->GetCommandList()->ClearDepthStencilView(
dxfb->GetDSVDescriptor().cpu_handle, D3D12_CLEAR_FLAG_DEPTH, depth_value, 0, 0, nullptr);
}
dxfb->ClearRenderTargets(color_value, nullptr);
dxfb->ClearDepth(depth_value, nullptr);
}
void Gfx::SetScissorRect(const MathUtil::Rectangle<int>& rc)