mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
D3D12: Avoid redundant render pass restarts
This commit is contained in:
parent
0407f939fc
commit
5e8870ec69
|
@ -1659,22 +1659,45 @@ void D3D12Device::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTextu
|
||||||
{
|
{
|
||||||
DebugAssert(
|
DebugAssert(
|
||||||
!(flags & (GPUPipeline::RenderPassFlag::ColorFeedbackLoop | GPUPipeline::RenderPassFlag::SampleDepthBuffer)));
|
!(flags & (GPUPipeline::RenderPassFlag::ColorFeedbackLoop | GPUPipeline::RenderPassFlag::SampleDepthBuffer)));
|
||||||
|
|
||||||
|
const bool image_bind_changed = ((m_current_render_pass_flags ^ flags) & GPUPipeline::BindRenderTargetsAsImages);
|
||||||
|
bool changed =
|
||||||
|
(m_num_current_render_targets != num_rts || m_current_depth_target != ds || m_current_render_pass_flags != flags);
|
||||||
|
bool needs_ds_clear = (ds && ds->IsClearedOrInvalidated());
|
||||||
|
bool needs_rt_clear = false;
|
||||||
|
|
||||||
if (InRenderPass())
|
if (InRenderPass())
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
m_current_depth_target = static_cast<D3D12Texture*>(ds);
|
m_current_depth_target = static_cast<D3D12Texture*>(ds);
|
||||||
if (num_rts > 0)
|
for (u32 i = 0; i < num_rts; i++)
|
||||||
std::memcpy(m_current_render_targets.data(), rts, sizeof(D3D12Texture*) * num_rts);
|
{
|
||||||
|
D3D12Texture* const RT = static_cast<D3D12Texture*>(rts[i]);
|
||||||
|
changed |= m_current_render_targets[i] != RT;
|
||||||
|
m_current_render_targets[i] = RT;
|
||||||
|
needs_rt_clear |= RT->IsClearedOrInvalidated();
|
||||||
|
}
|
||||||
for (u32 i = num_rts; i < m_num_current_render_targets; i++)
|
for (u32 i = num_rts; i < m_num_current_render_targets; i++)
|
||||||
m_current_render_targets[i] = nullptr;
|
m_current_render_targets[i] = nullptr;
|
||||||
m_num_current_render_targets = num_rts;
|
m_num_current_render_targets = Truncate8(num_rts);
|
||||||
|
|
||||||
// Need a root signature change if switching to UAVs.
|
|
||||||
m_dirty_flags |=
|
|
||||||
((m_current_render_pass_flags ^ flags) & GPUPipeline::BindRenderTargetsAsImages) ? LAYOUT_DEPENDENT_DIRTY_STATE : 0;
|
|
||||||
m_dirty_flags = (flags & GPUPipeline::BindRenderTargetsAsImages) ? (m_dirty_flags | DIRTY_FLAG_RT_UAVS) :
|
|
||||||
(m_dirty_flags & ~DIRTY_FLAG_RT_UAVS);
|
|
||||||
m_current_render_pass_flags = flags;
|
m_current_render_pass_flags = flags;
|
||||||
|
|
||||||
|
// Don't end render pass unless it's necessary.
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (InRenderPass())
|
||||||
|
EndRenderPass();
|
||||||
|
|
||||||
|
// Need a root signature change if switching to UAVs.
|
||||||
|
m_dirty_flags |= image_bind_changed ? LAYOUT_DEPENDENT_DIRTY_STATE : 0;
|
||||||
|
m_dirty_flags = (flags & GPUPipeline::BindRenderTargetsAsImages) ? (m_dirty_flags | DIRTY_FLAG_RT_UAVS) :
|
||||||
|
(m_dirty_flags & ~DIRTY_FLAG_RT_UAVS);
|
||||||
|
}
|
||||||
|
else if (needs_rt_clear || needs_ds_clear)
|
||||||
|
{
|
||||||
|
if (InRenderPass())
|
||||||
|
EndRenderPass();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12Device::BeginRenderPass()
|
void D3D12Device::BeginRenderPass()
|
||||||
|
|
|
@ -338,7 +338,7 @@ private:
|
||||||
|
|
||||||
D3D12Pipeline* m_current_pipeline = nullptr;
|
D3D12Pipeline* m_current_pipeline = nullptr;
|
||||||
D3D12_PRIMITIVE_TOPOLOGY m_current_topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
D3D12_PRIMITIVE_TOPOLOGY m_current_topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
u32 m_num_current_render_targets = 0;
|
u8 m_num_current_render_targets = 0;
|
||||||
GPUPipeline::RenderPassFlag m_current_render_pass_flags = GPUPipeline::NoRenderPassFlags;
|
GPUPipeline::RenderPassFlag m_current_render_pass_flags = GPUPipeline::NoRenderPassFlags;
|
||||||
std::array<D3D12Texture*, MAX_RENDER_TARGETS> m_current_render_targets = {};
|
std::array<D3D12Texture*, MAX_RENDER_TARGETS> m_current_render_targets = {};
|
||||||
D3D12Texture* m_current_depth_target = nullptr;
|
D3D12Texture* m_current_depth_target = nullptr;
|
||||||
|
|
|
@ -3318,10 +3318,9 @@ void VulkanDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUText
|
||||||
DIRTY_FLAG_INPUT_ATTACHMENT :
|
DIRTY_FLAG_INPUT_ATTACHMENT :
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
else if (needs_rt_clear || needs_ds_clear)
|
||||||
// TODO: This could use vkCmdClearAttachments() instead.
|
|
||||||
if (needs_rt_clear || needs_ds_clear)
|
|
||||||
{
|
{
|
||||||
|
// TODO: This could use vkCmdClearAttachments() instead.
|
||||||
if (InRenderPass())
|
if (InRenderPass())
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue