mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-11 22:49:56 +00:00
GS/DX11/GL: Adapt full barrier multidraw FB copy for sampling RT/DS hazards.
This commit is contained in:
@@ -2616,6 +2616,7 @@ void GSState::FlushPrim()
|
||||
m_quad_check_valid_shuffle = false;
|
||||
m_drawlist.clear();
|
||||
m_drawlist_bbox.clear();
|
||||
m_drawlist_bbox_tex.clear();
|
||||
|
||||
if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
|
||||
{
|
||||
@@ -4725,6 +4726,71 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlist(bool save_drawlist, b
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 primclass, bool fst>
|
||||
void GSState::GetPrimitiveOverlapDrawlistTextureBBoxImpl(float bbox_scale)
|
||||
{
|
||||
pxAssert(m_drawlist_bbox_tex.empty()); // Should only call this once per draw.
|
||||
|
||||
constexpr int n = GSUtil::GetClassVertexCount(primclass);
|
||||
const GSVertex* RESTRICT v = m_vertex->buff;
|
||||
const u16* RESTRICT index = m_index->buff;
|
||||
const u32 count = m_index->tail;
|
||||
|
||||
for (u32 i = 0; i < count; i += n)
|
||||
{
|
||||
const float q = primclass == GS_SPRITE_CLASS ? v[index[i + 1]].RGBAQ.Q : v[index[i]].RGBAQ.Q;
|
||||
GSVector4 bbox = GetTexCoordsImpl<fst>(v[index[i]], q);
|
||||
|
||||
for (u32 j = 1; j < n; j++)
|
||||
{
|
||||
const GSVector4 tex = GetTexCoordsImpl<fst>(v[index[i + j]]);
|
||||
bbox = bbox.min(tex).xyzw(bbox.max(tex));
|
||||
}
|
||||
|
||||
bbox = bbox * bbox_scale; // Account for upscaling.
|
||||
bbox = bbox.floor().xyzw(bbox.ceil()); // Round.
|
||||
bbox += GSVector4(-1.0f, -1.0f, 1.0f, 1.0f); // +1 on all sides for bilinear.
|
||||
|
||||
m_drawlist_bbox_tex.push_back(GSVector4i(bbox));
|
||||
}
|
||||
}
|
||||
|
||||
void GSState::GetPrimitiveOverlapDrawlistTextureBBox(float bbox_scale)
|
||||
{
|
||||
pxAssert(PRIM->TME);
|
||||
|
||||
switch (m_vt.m_primclass)
|
||||
{
|
||||
case GS_POINT_CLASS:
|
||||
if (PRIM->FST)
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_POINT_CLASS, true>(bbox_scale);
|
||||
else
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_POINT_CLASS, false>(bbox_scale);
|
||||
break;
|
||||
case GS_LINE_CLASS:
|
||||
if (PRIM->FST)
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_LINE_CLASS, true>(bbox_scale);
|
||||
else
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_LINE_CLASS, false>(bbox_scale);
|
||||
break;
|
||||
case GS_TRIANGLE_CLASS:
|
||||
if (PRIM->FST)
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_TRIANGLE_CLASS, true>(bbox_scale);
|
||||
else
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_TRIANGLE_CLASS, false>(bbox_scale);
|
||||
break;
|
||||
case GS_SPRITE_CLASS:
|
||||
if (PRIM->FST)
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_SPRITE_CLASS, true>(bbox_scale);
|
||||
else
|
||||
GetPrimitiveOverlapDrawlistTextureBBoxImpl<GS_SPRITE_CLASS, false>(bbox_scale);
|
||||
break;
|
||||
default:
|
||||
pxAssert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GSState::PRIM_OVERLAP GSState::PrimitiveOverlap(bool save_drawlist)
|
||||
{
|
||||
// Assume that 1 triangle, 1 sprite, 1 line, or 3 points can't overlap.
|
||||
|
||||
@@ -392,6 +392,7 @@ public:
|
||||
PRIM_OVERLAP m_prim_overlap = PRIM_OVERLAP_UNKNOW;
|
||||
std::vector<size_t> m_drawlist;
|
||||
std::vector<GSVector4i> m_drawlist_bbox;
|
||||
std::vector<GSVector4i> m_drawlist_bbox_tex;
|
||||
|
||||
struct GSPCRTCRegs
|
||||
{
|
||||
@@ -535,6 +536,9 @@ public:
|
||||
PRIM_OVERLAP GetPrimitiveOverlapDrawlistImpl(bool save_drawlist = false, bool save_bbox = false, float bbox_scale = 1.0f);
|
||||
PRIM_OVERLAP GetPrimitiveOverlapDrawlist(bool save_drawlist = false, bool save_bbox = false, float bbox_scale = 1.0f);
|
||||
PRIM_OVERLAP PrimitiveOverlap(bool save_drawlist = false);
|
||||
template <u32 primclass, bool fst>
|
||||
void GetPrimitiveOverlapDrawlistTextureBBoxImpl(float bbox_scale = 1.0f);
|
||||
void GetPrimitiveOverlapDrawlistTextureBBox(float bbox_scale = 1.0f);
|
||||
bool SpriteDrawWithoutGaps();
|
||||
void CalculatePrimitiveCoversWithoutGaps();
|
||||
GIFRegTEX0 GetTex0Layer(u32 lod);
|
||||
|
||||
@@ -3027,6 +3027,58 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea)
|
||||
{
|
||||
if (rt_clone)
|
||||
{
|
||||
CopyRect(rt, rt_clone, copyarea, copyarea.left, copyarea.top);
|
||||
PSSetShaderResource(2, 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
const GSVector4i& copyarea, const GSVector4i& samplearea)
|
||||
{
|
||||
const GSVector4i rtsize = (rt ? rt : ds)->GetRect();
|
||||
|
||||
// DX11 can't do partial depth copies so only do attempt individual copies for RT hazards.
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_RT)
|
||||
{
|
||||
const GSVector4i union_rect = config.drawarea.runion(config.samplearea);
|
||||
const u32 size_union = union_rect.width() * union_rect.height();
|
||||
const u32 size_indiv = config.drawarea.width() * config.drawarea.height() +
|
||||
config.samplearea.width() * config.samplearea.height();
|
||||
|
||||
// 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));
|
||||
}
|
||||
else
|
||||
{
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, 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));
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
@@ -3036,27 +3088,6 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
Console.Warning("D3D11: Possible unnecessary copy detected.");
|
||||
#endif
|
||||
|
||||
auto CopyAndBind = [&](GSVector4i drawarea) {
|
||||
if (draw_rt_clone)
|
||||
{
|
||||
CopyRect(draw_rt, draw_rt_clone, drawarea, drawarea.left, drawarea.top);
|
||||
if ((one_barrier || full_barrier))
|
||||
PSSetShaderResource(2, draw_rt_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_RT)
|
||||
PSSetShaderResource(0, draw_rt_clone);
|
||||
}
|
||||
if (draw_ds_clone)
|
||||
{
|
||||
CopyRect(draw_ds, draw_ds_clone, drawarea, drawarea.left, drawarea.top);
|
||||
if ((one_barrier || full_barrier))
|
||||
PSSetShaderResource(4, draw_ds_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_DEPTH)
|
||||
PSSetShaderResource(0, draw_ds_clone);
|
||||
}
|
||||
};
|
||||
|
||||
const GSVector4i rtsize(0, 0, (draw_rt ? draw_rt : draw_ds)->GetWidth(), (draw_rt ? draw_rt : draw_ds)->GetHeight());
|
||||
|
||||
if (full_barrier)
|
||||
{
|
||||
const u32 draw_list_size = static_cast<u32>(config.drawlist->size());
|
||||
@@ -3067,10 +3098,13 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const u32 count = (*config.drawlist)[n] * indices_per_prim;
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
|
||||
const GSVector4i original_bbox = (*config.drawlist_bbox)[n].rintersect(config.drawarea);
|
||||
CopyAndBind(ProcessCopyArea(rtsize, original_bbox));
|
||||
const GSVector4i bbox = config.drawlist_bbox->at(n).rintersect(config.drawarea);
|
||||
const GSVector4i bbox_tex = config.drawlist_bbox_tex ?
|
||||
config.drawlist_bbox_tex->at(n).rintersect(config.samplearea) : GSVector4i::zero();
|
||||
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox, bbox_tex);
|
||||
|
||||
Draw(config, p, count);
|
||||
|
||||
@@ -3082,29 +3116,7 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
|
||||
if (one_barrier)
|
||||
{
|
||||
// DX11 can't do partial depth copies.
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_RT)
|
||||
{
|
||||
const GSVector4i union_rect = config.drawarea.runion(config.samplearea);
|
||||
const u32 size_union = union_rect.width() * union_rect.height();
|
||||
const u32 size_indiv = config.drawarea.width() * config.drawarea.height() +
|
||||
config.samplearea.width() * config.samplearea.height();
|
||||
|
||||
// Do an individual copy if the union is larger than the sum of individual areas.
|
||||
if (size_union > size_indiv)
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.drawarea));
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.samplearea));
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, union_rect));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.drawarea));
|
||||
}
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.drawarea, config.samplearea);
|
||||
}
|
||||
|
||||
Draw(config);
|
||||
|
||||
@@ -372,6 +372,12 @@ public:
|
||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8 afix);
|
||||
|
||||
void RenderHW(GSHWDrawConfig& config) override;
|
||||
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea);
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone,
|
||||
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);
|
||||
|
||||
@@ -4585,7 +4585,7 @@ void GSDevice12::SendHWDraw(const PipelineSelector& pipe, const GSHWDrawConfig&
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const u32 count = (*config.drawlist)[n] * indices_per_prim;
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
|
||||
if (feedback_rt)
|
||||
FeedbackBarrier(draw_rt);
|
||||
|
||||
@@ -6161,7 +6161,7 @@ void GSRendererHW::DetermineVSConfig(GSTextureCache::Target* rt, float rtscale,
|
||||
m_conf.vs.iip = !IsFlatShaded();
|
||||
}
|
||||
|
||||
void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt)
|
||||
void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt, GSTextureCache::Source* tex)
|
||||
{
|
||||
const GSDevice::FeatureSupport& features = g_gs_device->Features();
|
||||
|
||||
@@ -6204,6 +6204,16 @@ void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt)
|
||||
ComputeDrawlistGetSize(rt->m_scale);
|
||||
m_conf.drawlist = &m_drawlist;
|
||||
m_conf.drawlist_bbox = &m_drawlist_bbox;
|
||||
|
||||
if (m_conf.tex_hazard != GSHWDrawConfig::TEX_HAZARD_NONE)
|
||||
{
|
||||
GetPrimitiveOverlapDrawlistTextureBBox(tex->GetScale());
|
||||
m_conf.drawlist_bbox_tex = &m_drawlist_bbox_tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_conf.drawlist_bbox_tex = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9027,7 +9037,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
}
|
||||
|
||||
// Barriers must be determined before indices are modified via HandleProvokingVertexFirst/SetupIA.
|
||||
DetermineBarriers(rt);
|
||||
DetermineBarriers(rt, tex);
|
||||
|
||||
// Perform second pass setup here once barriers are determined.
|
||||
EmulateAlphaTestSecondPass();
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
|
||||
void DetermineVSConfig(GSTextureCache::Target* rt, float rtscale, const GSVector2i& rtsize,
|
||||
const GSVector2i& unscaled_size, float& vs_scale_x, float& vs_scale_y);
|
||||
void DetermineBarriers(GSTextureCache::Target* rt);
|
||||
void DetermineBarriers(GSTextureCache::Target* rt, GSTextureCache::Source* tex);
|
||||
|
||||
void SetTCOffset();
|
||||
bool NextDrawColClip() const;
|
||||
|
||||
@@ -2518,7 +2518,7 @@ void GSDeviceMTL::SendHWDraw(GSHWDrawConfig& config, id<MTLRenderCommandEncoder>
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const size_t count = (*config.drawlist)[n] * indices_per_prim;
|
||||
const size_t count = config.drawlist->at(n) * indices_per_prim;
|
||||
textureBarrier(enc);
|
||||
EncodeDraw(enc, topology, count, buffer, off, p);
|
||||
p += count;
|
||||
|
||||
@@ -3033,6 +3033,57 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea)
|
||||
{
|
||||
if (rt_clone)
|
||||
{
|
||||
CopyRect(rt, rt_clone, copyarea, copyarea.left, copyarea.top);
|
||||
PSSetShaderResource(2, 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Choose the best copy area based on the hazards and whether we need RT and/or DS copies.
|
||||
void GSDeviceOGL::FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone,
|
||||
const GSVector4i& copyarea, const GSVector4i& samplearea)
|
||||
{
|
||||
const GSVector4i rtsize = (rt ? rt : ds)->GetRect();
|
||||
|
||||
if (config.tex_hazard != GSHWDrawConfig::TEX_HAZARD_NONE)
|
||||
{
|
||||
const GSVector4i union_rect = config.drawarea.runion(config.samplearea);
|
||||
const u32 size_union = union_rect.width() * union_rect.height();
|
||||
const u32 size_indiv = config.drawarea.width() * config.drawarea.height() +
|
||||
config.samplearea.width() * config.samplearea.height();
|
||||
|
||||
// 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));
|
||||
}
|
||||
else
|
||||
{
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, union_rect));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No RT/DS hazards so just need the draw area.
|
||||
FeedbackCopyAndBind(config, rt, rt_clone, ds, ds_clone, ProcessCopyArea(rtsize, config.drawarea));
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::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)
|
||||
@@ -3042,27 +3093,6 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
Console.Warning("OpenGL: Possible unnecessary barrier detected.");
|
||||
#endif
|
||||
|
||||
auto CopyAndBind = [&](GSVector4i drawarea) {
|
||||
if (draw_rt_clone)
|
||||
{
|
||||
CopyRect(draw_rt, draw_rt_clone, drawarea, drawarea.left, drawarea.top);
|
||||
if ((one_barrier || full_barrier))
|
||||
PSSetShaderResource(2, draw_rt_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_RT)
|
||||
PSSetShaderResource(0, draw_rt_clone);
|
||||
}
|
||||
if (draw_ds_clone)
|
||||
{
|
||||
CopyRect(draw_ds, draw_ds_clone, drawarea, drawarea.left, drawarea.top);
|
||||
if ((one_barrier || full_barrier))
|
||||
PSSetShaderResource(4, draw_ds_clone);
|
||||
if (config.tex_hazard == GSHWDrawConfig::TEX_HAZARD_DEPTH)
|
||||
PSSetShaderResource(0, draw_ds_clone);
|
||||
}
|
||||
};
|
||||
|
||||
const GSVector4i rtsize(0, 0, (draw_rt ? draw_rt : draw_ds)->GetWidth(), (draw_rt ? draw_rt : draw_ds)->GetHeight());
|
||||
|
||||
if (full_barrier)
|
||||
{
|
||||
pxAssert(config.drawlist && !config.drawlist->empty());
|
||||
@@ -3077,7 +3107,7 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const u32 count = (*config.drawlist)[n] * indices_per_prim;
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
|
||||
if (m_features.texture_barrier)
|
||||
{
|
||||
@@ -3085,8 +3115,10 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
}
|
||||
else
|
||||
{
|
||||
const GSVector4i original_bbox = (*config.drawlist_bbox)[n].rintersect(config.drawarea);
|
||||
CopyAndBind(ProcessCopyArea(rtsize, original_bbox));
|
||||
const GSVector4i bbox = config.drawlist_bbox->at(n).rintersect(config.drawarea);
|
||||
const GSVector4i bbox_tex = config.drawlist_bbox_tex ?
|
||||
config.drawlist_bbox_tex->at(n).rintersect(config.samplearea) : GSVector4i::zero();
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox, bbox_tex);
|
||||
}
|
||||
|
||||
Draw(config, p, count);
|
||||
@@ -3106,28 +3138,7 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
else
|
||||
{
|
||||
// Optimization: For alpha second pass we can reuse the copy snapshot from the first pass.
|
||||
if (config.tex_hazard)
|
||||
{
|
||||
const GSVector4i union_rect = config.drawarea.runion(config.samplearea);
|
||||
const u32 size_union = union_rect.width() * union_rect.height();
|
||||
const u32 size_indiv = config.drawarea.width() * config.drawarea.height() +
|
||||
config.samplearea.width() * config.samplearea.height();
|
||||
|
||||
// Do an individual copy if the union is larger than the sum of individual areas.
|
||||
if (size_union > size_indiv)
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.drawarea));
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.samplearea));
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, union_rect));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyAndBind(ProcessCopyArea(rtsize, config.drawarea));
|
||||
}
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.drawarea, config.samplearea);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,6 +352,11 @@ public:
|
||||
void DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, const GSVector2& ds);
|
||||
|
||||
void RenderHW(GSHWDrawConfig& config) override;
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone, const GSVector4i& copyarea);
|
||||
void FeedbackCopyAndBind(const GSHWDrawConfig& config,
|
||||
GSTexture* rt, GSTexture* rt_clone, GSTexture* ds, GSTexture* ds_clone,
|
||||
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);
|
||||
|
||||
@@ -6370,7 +6370,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt,
|
||||
{
|
||||
IssueBarriers();
|
||||
|
||||
const u32 count = (*config.drawlist)[n] * indices_per_prim;
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
Draw(config, p, count);
|
||||
p += count;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user