mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +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(
|
||||
!(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())
|
||||
EndRenderPass();
|
||||
|
||||
m_current_depth_target = static_cast<D3D12Texture*>(ds);
|
||||
if (num_rts > 0)
|
||||
std::memcpy(m_current_render_targets.data(), rts, sizeof(D3D12Texture*) * num_rts);
|
||||
for (u32 i = 0; i < num_rts; i++)
|
||||
{
|
||||
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++)
|
||||
m_current_render_targets[i] = nullptr;
|
||||
m_num_current_render_targets = num_rts;
|
||||
m_num_current_render_targets = Truncate8(num_rts);
|
||||
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 |=
|
||||
((m_current_render_pass_flags ^ flags) & GPUPipeline::BindRenderTargetsAsImages) ? LAYOUT_DEPENDENT_DIRTY_STATE : 0;
|
||||
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);
|
||||
m_current_render_pass_flags = flags;
|
||||
}
|
||||
else if (needs_rt_clear || needs_ds_clear)
|
||||
{
|
||||
if (InRenderPass())
|
||||
EndRenderPass();
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12Device::BeginRenderPass()
|
||||
|
|
|
@ -338,7 +338,7 @@ private:
|
|||
|
||||
D3D12Pipeline* m_current_pipeline = nullptr;
|
||||
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;
|
||||
std::array<D3D12Texture*, MAX_RENDER_TARGETS> m_current_render_targets = {};
|
||||
D3D12Texture* m_current_depth_target = nullptr;
|
||||
|
|
|
@ -3318,10 +3318,9 @@ void VulkanDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUText
|
|||
DIRTY_FLAG_INPUT_ATTACHMENT :
|
||||
0);
|
||||
}
|
||||
|
||||
// TODO: This could use vkCmdClearAttachments() instead.
|
||||
if (needs_rt_clear || needs_ds_clear)
|
||||
else if (needs_rt_clear || needs_ds_clear)
|
||||
{
|
||||
// TODO: This could use vkCmdClearAttachments() instead.
|
||||
if (InRenderPass())
|
||||
EndRenderPass();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue