mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Avoid render pass restarts to turn off RT
Significantly reduces render passes in Sly 2.
This commit is contained in:
parent
430cad48e3
commit
8f68e096d4
|
@ -3205,8 +3205,20 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
|
||||
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
|
||||
if (m_in_render_pass && !hdr_rt && !draw_ds && m_current_depth_target && m_current_render_target == draw_rt &&
|
||||
config.tex != m_current_depth_target && m_current_depth_target->GetSize() == draw_rt->GetSize())
|
||||
if (m_in_render_pass && (m_current_render_target == draw_rt || m_current_depth_target == draw_ds))
|
||||
{
|
||||
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
|
||||
// keep the depth even if doing HDR draws, because the next draw will probably re-enable depth
|
||||
if (!draw_rt && m_current_render_target && config.tex != m_current_render_target &&
|
||||
m_current_render_target->GetSize() == draw_ds->GetSize())
|
||||
{
|
||||
draw_rt = m_current_render_target;
|
||||
m_pipeline_selector.rt = true;
|
||||
m_pipeline_selector.cms.wrgba = 0;
|
||||
}
|
||||
}
|
||||
else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target &&
|
||||
m_current_depth_target->GetSize() == draw_rt->GetSize())
|
||||
{
|
||||
draw_ds = m_current_depth_target;
|
||||
m_pipeline_selector.ds = true;
|
||||
|
|
|
@ -2424,13 +2424,17 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
|
||||
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
|
||||
config.blend.constant_enable, config.blend.constant);
|
||||
OMSetColorMaskState(config.colormask);
|
||||
|
||||
// avoid changing framebuffer just to switch from rt+depth to rt and vice versa
|
||||
GSTexture* draw_rt = hdr_rt ? hdr_rt : config.rt;
|
||||
GSTexture* draw_ds = config.ds;
|
||||
if (!draw_ds && GLState::ds && GLState::rt == draw_rt && config.tex != GLState::ds &&
|
||||
GLState::ds->GetSize() == draw_rt->GetSize())
|
||||
OMColorMaskSelector draw_colormask = config.colormask;
|
||||
if (!draw_rt && GLState::rt && GLState::ds == draw_ds && GLState::rt->GetSize() == draw_ds->GetSize())
|
||||
{
|
||||
draw_rt = GLState::rt;
|
||||
draw_colormask.wrgba = 0;
|
||||
}
|
||||
else if (!draw_ds && GLState::ds && GLState::rt == draw_rt && GLState::ds->GetSize() == draw_rt->GetSize())
|
||||
{
|
||||
// should already be always-pass.
|
||||
draw_ds = GLState::ds;
|
||||
|
@ -2439,6 +2443,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
|
||||
OMSetRenderTargets(draw_rt, draw_ds, &config.scissor);
|
||||
OMSetColorMaskState(draw_colormask);
|
||||
SetupOM(config.depth);
|
||||
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
|
|
@ -2844,7 +2844,12 @@ void GSDeviceVK::ExecuteCommandBufferAndRestartRenderPass(bool wait_for_completi
|
|||
Console.Warning("Vulkan: Executing command buffer due to '%s'", reason);
|
||||
|
||||
const VkRenderPass render_pass = m_current_render_pass;
|
||||
const GSVector4i render_pass_area(m_current_render_pass_area);
|
||||
const GSVector4i render_pass_area = m_current_render_pass_area;
|
||||
const GSVector4i scissor = m_scissor;
|
||||
GSTexture* const current_rt = m_current_render_target;
|
||||
GSTexture* const current_ds = m_current_depth_target;
|
||||
const FeedbackLoopFlag current_feedback_loop = m_current_framebuffer_feedback_loop;
|
||||
|
||||
EndRenderPass();
|
||||
g_vulkan_context->ExecuteCommandBuffer(GetWaitType(wait_for_completion, GSConfig.HWSpinCPUForReadbacks));
|
||||
InvalidateCachedState();
|
||||
|
@ -2852,8 +2857,7 @@ void GSDeviceVK::ExecuteCommandBufferAndRestartRenderPass(bool wait_for_completi
|
|||
if (render_pass != VK_NULL_HANDLE)
|
||||
{
|
||||
// rebind framebuffer
|
||||
ApplyBaseState(m_dirty_flags, g_vulkan_context->GetCurrentCommandBuffer());
|
||||
m_dirty_flags &= ~DIRTY_BASE_STATE;
|
||||
OMSetRenderTargets(current_rt, current_ds, scissor, current_feedback_loop);
|
||||
|
||||
// restart render pass
|
||||
BeginRenderPass(render_pass, render_pass_area);
|
||||
|
@ -2893,6 +2897,7 @@ void GSDeviceVK::InvalidateCachedState()
|
|||
m_current_framebuffer = VK_NULL_HANDLE;
|
||||
m_current_render_target = nullptr;
|
||||
m_current_depth_target = nullptr;
|
||||
m_current_framebuffer_feedback_loop = FeedbackLoopFlag_None;
|
||||
|
||||
m_current_pipeline_layout = PipelineLayout::Undefined;
|
||||
m_tfx_descriptor_sets[1] = VK_NULL_HANDLE;
|
||||
|
@ -3637,13 +3642,19 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
(!hdr_rt && DATE_rp != DATE_RENDER_PASS_STENCIL_ONE && CheckRenderPassArea(render_area));
|
||||
|
||||
// render pass restart optimizations
|
||||
if (render_area_okay)
|
||||
if (render_area_okay && (m_current_render_target == draw_rt || m_current_depth_target == draw_ds))
|
||||
{
|
||||
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
|
||||
if (!draw_ds && m_current_depth_target && m_current_render_target == draw_rt &&
|
||||
config.tex != m_current_depth_target && m_current_depth_target->GetSize() == draw_rt->GetSize() &&
|
||||
((pipe.feedback_loop_flags & FeedbackLoopFlag_ReadAndWriteRT) ==
|
||||
(m_current_framebuffer_feedback_loop & FeedbackLoopFlag_ReadAndWriteRT)))
|
||||
// keep the depth even if doing HDR draws, because the next draw will probably re-enable depth
|
||||
if (!draw_rt && m_current_render_target && config.tex != m_current_render_target &&
|
||||
m_current_render_target->GetSize() == draw_ds->GetSize())
|
||||
{
|
||||
draw_rt = m_current_render_target;
|
||||
m_pipeline_selector.rt = true;
|
||||
m_pipeline_selector.cms.wrgba = 0;
|
||||
}
|
||||
else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target &&
|
||||
m_current_depth_target->GetSize() == draw_rt->GetSize())
|
||||
{
|
||||
draw_ds = m_current_depth_target;
|
||||
m_pipeline_selector.ds = true;
|
||||
|
@ -3652,9 +3663,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
|
||||
// Prefer keeping feedback loop enabled, that way we're not constantly restarting render passes
|
||||
pipe.feedback_loop_flags |= (m_current_render_target == draw_rt && m_current_depth_target == draw_ds) ?
|
||||
m_current_framebuffer_feedback_loop :
|
||||
0;
|
||||
pipe.feedback_loop_flags |= m_current_framebuffer_feedback_loop;
|
||||
}
|
||||
|
||||
// We don't need the very first barrier if this is the first draw after switching to feedback loop,
|
||||
|
@ -3822,7 +3831,8 @@ void GSDeviceVK::UpdateHWPipelineSelector(GSHWDrawConfig& config, PipelineSelect
|
|||
(config.ps.IsFeedbackLoop() || config.require_one_barrier || config.require_full_barrier)) ?
|
||||
FeedbackLoopFlag_ReadAndWriteRT :
|
||||
FeedbackLoopFlag_None;
|
||||
pipe.feedback_loop_flags |= (config.tex == config.ds) ? FeedbackLoopFlag_ReadDS : FeedbackLoopFlag_None;
|
||||
pipe.feedback_loop_flags |=
|
||||
(config.tex && config.tex == config.ds) ? FeedbackLoopFlag_ReadDS : FeedbackLoopFlag_None;
|
||||
|
||||
// enable point size in the vertex shader if we're rendering points regardless of upscaling.
|
||||
pipe.vs.point_size |= (config.topology == GSHWDrawConfig::Topology::Point);
|
||||
|
|
Loading…
Reference in New Issue