mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-11 22:49:56 +00:00
GS/DX11/GL: Fix sample area calculation for RT/DS sampling hazard.
This commit is contained in:
@@ -2615,7 +2615,6 @@ 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()))
|
||||
{
|
||||
@@ -4750,71 +4749,6 @@ 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,7 +392,6 @@ 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
|
||||
{
|
||||
@@ -538,9 +537,6 @@ public:
|
||||
PRIM_OVERLAP GetPrimitiveOverlapDrawlist(bool save_drawlist = false, bool save_bbox = false,
|
||||
float bbox_scale = 1.0f, u32* max_size = nullptr);
|
||||
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);
|
||||
|
||||
@@ -1226,18 +1226,17 @@ struct alignas(16) GSHWDrawConfig
|
||||
EarlyResolve = 4
|
||||
};
|
||||
|
||||
GSTexture* rt; ///< Render target
|
||||
GSTexture* ds; ///< Depth stencil
|
||||
GSTexture* tex; ///< Source texture
|
||||
GSTexture* pal; ///< Palette texture
|
||||
const GSVertex* verts;///< Vertices to draw
|
||||
const u16* indices; ///< Indices to draw
|
||||
u32 nverts; ///< Number of vertices
|
||||
u32 nindices; ///< Number of indices
|
||||
u32 indices_per_prim; ///< Number of indices that make up one primitive
|
||||
const std::vector<size_t>* drawlist; ///< For reducing barriers on sprites
|
||||
const std::vector<GSVector4i>* drawlist_bbox; ///< For RT copy when barriers not available.
|
||||
const std::vector<GSVector4i>* drawlist_bbox_tex; ///< Additionally if we need to sample not from the same pixel of the RT.
|
||||
GSTexture* rt; ///< Render target
|
||||
GSTexture* ds; ///< Depth stencil
|
||||
GSTexture* tex; ///< Source texture
|
||||
GSTexture* pal; ///< Palette texture
|
||||
const GSVertex* verts; ///< Vertices to draw
|
||||
const u16* indices; ///< Indices to draw
|
||||
u32 nverts; ///< Number of vertices
|
||||
u32 nindices; ///< Number of indices
|
||||
u32 indices_per_prim; ///< Number of indices that make up one primitive
|
||||
const std::vector<size_t>* drawlist; ///< For reducing barriers on sprites
|
||||
const std::vector<GSVector4i>* drawlist_bbox; ///< For RT copy when barriers not available.
|
||||
GSVector4i scissor; ///< Scissor rect
|
||||
GSVector4i drawarea; ///< Area in the framebuffer which will be modified.
|
||||
GSVector4i samplearea; ///< Area in the texture which will be sampled.
|
||||
|
||||
@@ -3230,15 +3230,16 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config,
|
||||
pxAssert(config.drawlist && !config.drawlist->empty());
|
||||
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);
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
|
||||
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);
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox);
|
||||
|
||||
Draw(config, p, count);
|
||||
|
||||
|
||||
@@ -1358,10 +1358,10 @@ GSVector4i GSRendererHW::ComputeBoundingBoxRT(const GSVector2i& rtsize, float rt
|
||||
return GSVector4i(box * GSVector4(rtscale)).rintersect(GSVector4i(0, 0, rtsize.x, rtsize.y));
|
||||
}
|
||||
|
||||
GSVector4i GSRendererHW::ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& region, float texscale)
|
||||
GSVector4i GSRendererHW::ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& coverage, const GSVector4i& region, float texscale)
|
||||
{
|
||||
const GSVector4 offset = GSVector4(region.xyxy()) + GSVector4(-1.0f, -1.0f, 1.0f, 1.0f); // Region offset + round value
|
||||
const GSVector4 box = m_vt.m_min.t.upld(m_vt.m_max.t) + offset;
|
||||
const GSVector4 box = GSVector4(coverage) + offset;
|
||||
return GSVector4i(box * GSVector4(texscale)).rintersect(GSVector4i(0, 0, texsize.x, texsize.y));
|
||||
}
|
||||
|
||||
@@ -6206,16 +6206,6 @@ void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt, GSTextureCache:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9462,7 +9452,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
|
||||
const GSVector4i tex_region = tex ? tex->GetRegionRect() : GSVector4i::zero();
|
||||
m_conf.samplearea = m_channel_shuffle ? scissor :
|
||||
GSVector4i::loadh(texsize).rintersect(ComputeBoundingBoxTex(texsize, tex_region, texscale));
|
||||
GSVector4i::loadh(texsize).rintersect(ComputeBoundingBoxTex(texsize, tmm.coverage, tex_region, texscale));
|
||||
|
||||
m_conf.scissor = (date_options.enabled && !date_options.barrier) ? m_conf.drawarea : scissor;
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ public:
|
||||
void ExpandLineIndices();
|
||||
GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex);
|
||||
GSVector4i ComputeBoundingBoxRT(const GSVector2i& rtsize, float rtscale);
|
||||
GSVector4i ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& region, float texscale);
|
||||
GSVector4i ComputeBoundingBoxTex(const GSVector2i& texsize, const GSVector4i& coverage, const GSVector4i& region, float texscale);
|
||||
void MergeSprite(GSTextureCache::Source* tex);
|
||||
float GetTextureScaleFactor() override;
|
||||
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr, const bool is_shuffle = false);
|
||||
|
||||
@@ -3172,6 +3172,9 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
else
|
||||
pxAssert(config.drawlist_bbox && static_cast<u32>(config.drawlist_bbox->size()) == draw_list_size);
|
||||
|
||||
if (!m_features.texture_barrier && config.tex_hazard != config.TEX_HAZARD_NONE)
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, config.samplearea);
|
||||
|
||||
for (u32 n = 0, p = 0; n < draw_list_size; n++)
|
||||
{
|
||||
const u32 count = config.drawlist->at(n) * indices_per_prim;
|
||||
@@ -3183,9 +3186,7 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config,
|
||||
else
|
||||
{
|
||||
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);
|
||||
FeedbackCopyAndBind(config, draw_rt, draw_rt_clone, draw_ds, draw_ds_clone, bbox);
|
||||
}
|
||||
|
||||
Draw(config, p, count);
|
||||
|
||||
Reference in New Issue
Block a user