mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 01:34:17 +02:00
GS/DX11: Skip barrier/copy if it's not needed.
It is possible to skip one barrier copy when using draw_ds_as_rt if only one pass needs a barrier, we already have a copy and draw_ds_as_rt doesn't need updating.
This commit is contained in:
@@ -3234,17 +3234,28 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
const bool ds_feedbackloop_pass1 = config.IsFeedbackLoopDepth(config.ps);
|
||||
const bool ds_feedbackloop_pass2 = config.IsFeedbackLoopDepth(config.alpha_second_pass.ps);
|
||||
|
||||
// It is possible to skip one barrier copy when using draw_ds_as_rt if only one pass needs a barrier, we already have a copy and draw_ds_as_rt doesn't need updating.
|
||||
const bool can_skip_ds_barrier = draw_ds_as_rt &&
|
||||
// Pass 1 needs barrier only.
|
||||
((ds_feedbackloop_pass1 && config.require_one_barrier && !ds_feedbackloop_pass2 && !config.alpha_second_pass.require_one_barrier) ||
|
||||
// Pass 2 needs barrier only.
|
||||
(!ds_feedbackloop_pass1 && !config.require_one_barrier && ds_feedbackloop_pass2 && config.alpha_second_pass.require_one_barrier));
|
||||
|
||||
if (draw_ds && !draw_ds_rov && (config.require_one_barrier || (config.require_full_barrier && m_features.multidraw_fb_copy)) &&
|
||||
(ds_feedbackloop_pass1 || ds_feedbackloop_pass2))
|
||||
{
|
||||
// Requires a copy of the DS.
|
||||
draw_ds_clone = CreateTexture(rtsize.x, rtsize.y, 1, (draw_ds_as_rt ? draw_ds_as_rt : draw_ds)->GetFormat(), true);
|
||||
if (can_skip_ds_barrier)
|
||||
draw_ds_clone = CreateFeedbackTarget(rtsize.x, rtsize.y, (draw_ds_as_rt ? draw_ds_as_rt : draw_ds)->GetFormat(), false, true);
|
||||
else
|
||||
draw_ds_clone = CreateTexture(rtsize.x, rtsize.y, 1, (draw_ds_as_rt ? draw_ds_as_rt : draw_ds)->GetFormat(), true);
|
||||
|
||||
if (!draw_ds_clone)
|
||||
Console.Warning("D3D11: Failed to allocate temp texture for DS copy.");
|
||||
}
|
||||
|
||||
OMSetRenderTargets(draw_rt, draw_ds_as_rt, draw_ds, draw_rt_rov, draw_ds_rov, &config.scissor, read_only_dsv);
|
||||
OMSetRenderTargets(draw_rt, can_skip_ds_barrier ? draw_ds_clone : draw_ds_as_rt, draw_ds, draw_rt_rov, draw_ds_rov, &config.scissor, read_only_dsv);
|
||||
SetRenderHWShaderResources(config, primid_texture);
|
||||
SetupOM(config.depth, OMBlendSelector(config.colormask, config.blend), config.blend.constant);
|
||||
|
||||
@@ -3253,7 +3264,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
m_ctx->ClearDepthStencilView(*static_cast<GSTexture11*>(draw_ds), D3D11_CLEAR_STENCIL, 0.0f, 1);
|
||||
|
||||
SendHWDraw(config, rt_feedbackloop_pass1 ? draw_rt_clone : nullptr, draw_rt, ds_feedbackloop_pass1 ? draw_ds_clone : nullptr, draw_ds_as_rt ? draw_ds_as_rt : draw_ds,
|
||||
config.require_one_barrier, config.require_full_barrier, rtsize);
|
||||
config.require_one_barrier, config.require_full_barrier, can_skip_ds_barrier, rtsize);
|
||||
|
||||
if (config.blend_multi_pass.enable)
|
||||
{
|
||||
@@ -3281,7 +3292,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
const bool one_barrier = config.alpha_second_pass.require_one_barrier && m_features.multidraw_fb_copy;
|
||||
SetupOM(config.alpha_second_pass.depth, OMBlendSelector(config.alpha_second_pass.colormask, config.blend), config.blend.constant);
|
||||
SendHWDraw(config, rt_feedbackloop_pass2 ? draw_rt_clone : nullptr, draw_rt, ds_feedbackloop_pass2 ? draw_ds_clone : nullptr, draw_ds_as_rt ? draw_ds_as_rt : draw_ds,
|
||||
one_barrier, config.alpha_second_pass.require_full_barrier, rtsize);
|
||||
one_barrier, config.alpha_second_pass.require_full_barrier, can_skip_ds_barrier, rtsize);
|
||||
}
|
||||
|
||||
if (colclip_rt)
|
||||
@@ -3302,27 +3313,34 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
|
||||
void GSDevice11::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea)
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const bool skip_ds_barrier, const GSVector4i& copyarea)
|
||||
{
|
||||
if (rt_clone)
|
||||
{
|
||||
CopyRect(rt, rt_clone, copyarea, copyarea.left, copyarea.top);
|
||||
PSSetShaderResource(2, rt_clone);
|
||||
PSSetShaderResource(TEXTURE_RT, rt_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_RT)
|
||||
PSSetShaderResource(0, rt_clone);
|
||||
}
|
||||
if (ds_clone)
|
||||
{
|
||||
CopyRect(ds, ds_clone, copyarea, copyarea.left, copyarea.top);
|
||||
PSSetShaderResource(4, ds_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_DEPTH)
|
||||
PSSetShaderResource(0, ds_clone);
|
||||
if (skip_ds_barrier)
|
||||
{
|
||||
PSSetShaderResource(TEXTURE_DEPTH, ds);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyRect(ds, ds_clone, copyarea, copyarea.left, copyarea.top);
|
||||
PSSetShaderResource(TEXTURE_DEPTH, ds_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_DEPTH)
|
||||
PSSetShaderResource(0, ds_clone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Choose the best copy area based on the hazards and whether we need RT and/or DS copies.
|
||||
void GSDevice11::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const bool skip_ds_barrier,
|
||||
const GSVector4i& copyarea, const GSVector4i& samplearea)
|
||||
{
|
||||
const GSVector4i rtsize = (rt ? rt : ds)->GetRect();
|
||||
@@ -3338,24 +3356,24 @@ void GSDevice11::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
// Do an individual copy if the union is larger than the sum of individual areas.
|
||||
if (size_union > size_indiv)
|
||||
{
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, config.drawarea));
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, config.samplearea));
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, skip_ds_barrier, ProcessCopyArea(rtsize, config.drawarea));
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, skip_ds_barrier, ProcessCopyArea(rtsize, config.samplearea));
|
||||
}
|
||||
else
|
||||
{
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, union_rect));
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, skip_ds_barrier, ProcessCopyArea(rtsize, union_rect));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No RT hazards so just need the draw area (or full area for DS).
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, config.drawarea));
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, skip_ds_barrier, ProcessCopyArea(rtsize, config.drawarea));
|
||||
}
|
||||
};
|
||||
|
||||
void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
GSTexture* draw_rt_clone, GSTexture* draw_rt, GSTexture* draw_ds_clone, GSTexture* draw_ds,
|
||||
const bool one_barrier, const bool full_barrier, GSVector2i rtsize)
|
||||
const bool one_barrier, const bool full_barrier, const bool skip_ds_barrier, GSVector2i rtsize)
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if ((one_barrier || full_barrier) && !(config.IsFeedbackLoopRT(config.ps) || config.IsFeedbackLoopDepth(config.ps))) [[unlikely]]
|
||||
@@ -3371,7 +3389,7 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
pxAssert(config.drawlist_bbox && static_cast<u32>(config.drawlist_bbox->size()) == draw_list_size);
|
||||
|
||||
if (config.tex_hazard != config.TEX_HAZARD_NONE)
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.samplearea);
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, skip_ds_barrier, config.samplearea);
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
@@ -3379,7 +3397,7 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
|
||||
const GSVector4i bbox = config.drawlist_bbox->at(n).rintersect(config.drawarea);
|
||||
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox);
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, skip_ds_barrier, bbox);
|
||||
|
||||
Draw(config, p, count);
|
||||
|
||||
@@ -3391,7 +3409,7 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
|
||||
if (one_barrier)
|
||||
{
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.drawarea, config.samplearea);
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, skip_ds_barrier, config.drawarea, config.samplearea);
|
||||
}
|
||||
|
||||
Draw(config);
|
||||
|
||||
@@ -416,13 +416,13 @@ public:
|
||||
void RenderHW(GSHWDrawConfig& config) override;
|
||||
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea);
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const bool skip_ds_barrier, const GSVector4i& copyarea);
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const bool skip_ds_barrier,
|
||||
const GSVector4i& copyarea, const GSVector4i& samplearea);
|
||||
void SendHWDraw(const GSHWDrawConfig& config,
|
||||
GSTexture* draw_rt_clone, GSTexture* draw_rt, GSTexture* draw_ds_clone, GSTexture* draw_ds,
|
||||
const bool one_barrier, const bool full_barrier, GSVector2i rtsize);
|
||||
const bool one_barrier, const bool full_barrier, const bool skip_ds_barrier, GSVector2i rtsize);
|
||||
void SetRenderHWShaderResources(const GSHWDrawConfig& config, GSTexture* primid_texture);
|
||||
|
||||
void ClearSamplerCache() override;
|
||||
|
||||
Reference in New Issue
Block a user