Skip to content

Commit

Permalink
Code for new UV rounding method to grab enough of texture.
Browse files Browse the repository at this point in the history
  • Loading branch information
TJ committed Dec 28, 2024
1 parent 6a0f811 commit bd80cdf
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions pcsx2/GS/GSState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3842,6 +3842,7 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
{
// Optimisation aims to reduce the amount of texture loaded to only the bit which will be read
GSVector4 st = m_vt.m_min.t.xyxy(m_vt.m_max.t);
// TODO: remove this if we use the new method
if (linear)
{
st += GSVector4(-0.5f, 0.5f).xxyy();
Expand All @@ -3856,7 +3857,19 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
// draw will get scissored, adjust UVs to suit
const GSVector2 pos_range(std::max(m_vt.m_max.p.x - m_vt.m_min.p.x, 1.0f), std::max(m_vt.m_max.p.y - m_vt.m_min.p.y, 1.0f));
const GSVector2 uv_range(m_vt.m_max.t.x - m_vt.m_min.t.x, m_vt.m_max.t.y - m_vt.m_min.t.y);

GSVector4 p_min_i = m_vt.m_min.p.ceil();
GSVector4 p_max_i = m_vt.m_max.p.floor();

const GSVector2 grad(uv_range / pos_range);

// Linearly interpolate the UV coordinates at the mimum/maximum pixel centers in the bounding box
GSVector4 t_min = ((m_vt.m_max.p - p_min_i) * m_vt.m_min.t + (p_min_i - m_vt.m_min.p) * m_vt.m_max.t) / (m_vt.m_max.p - m_vt.m_min.p);
GSVector4 t_max = ((m_vt.m_max.p - p_max_i) * m_vt.m_min.t + (p_max_i - m_vt.m_min.p) * m_vt.m_max.t) / (m_vt.m_max.p - m_vt.m_min.p);
// Calculate the min/max UV coordunates for bilinear filtering
// Note: Should we be doing max(GSVector4.zero()) as above? Or will this be handled by the scissor?
t_min = (t_min - 0.5).floor().max(GSVector4.zero());
t_max = (t_max + 0.5).floor() + 1;
// Adjust texture range when sprites get scissor clipped. Since we linearly interpolate, this
// optimization doesn't work when perspective correction is enabled.
if (m_vt.m_primclass == GS_SPRITE_CLASS && PRIM->FST == 1 && m_primitive_covers_without_gaps != NoGapsType::GapsFound)
Expand Down Expand Up @@ -3924,14 +3937,18 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
}
}

const GSVector4i uv = GSVector4i(st.floor());
const GSVector4i uv = GSVector4i(t_min.xyxy(t_max));
uses_border = GSVector4::cast((uv < vr).blend32<0xc>(uv >= vr)).mask();

// Need to make sure we don't oversample, this can cause trouble in grabbing textures.
// This may be inaccurate depending on the draw, but adding 1 all the time is wrong too.
const int inclusive_x_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.x < 1.0f || (grad.x == 1.0f && m_vt.m_max.p.x != floor(m_vt.m_max.p.x)))) ? 1 : 0;
const int inclusive_y_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.y < 1.0f || (grad.y == 1.0f && m_vt.m_max.p.y != floor(m_vt.m_max.p.y)))) ? 1 : 0;

//const int inclusive_x_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.x < 1.0f || (grad.x == 1.0f && m_vt.m_max.p.x != floor(m_vt.m_max.p.x)))) ? 1 : 0;
//const int inclusive_y_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.y < 1.0f || (grad.y == 1.0f && m_vt.m_max.p.y != floor(m_vt.m_max.p.y)))) ? 1 : 0;
// Disable the current inclusive_x/y_req calculation for now
// TODO: Remove if we use the new method
const int inclusive_x_req = 0;
const int inclusive_y_req = 0;

// Roughly cut out the min/max of the read (Clamp)
switch (wms)
{
Expand Down

0 comments on commit bd80cdf

Please sign in to comment.