Skip to content

Commit 9d08ca3

Browse files
committed
GS/HW: Disable HPO/even sprite position on texture shuffles.
Quad conversion in texture shuffles is already aligned and not intended to interact with upscaling coord fixes.
1 parent 06616ec commit 9d08ca3

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

pcsx2/GS/Renderers/HW/GSRendererHW.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,8 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
861861
const bool bilinear = m_vt.IsRealLinear();
862862

863863
// Copy the attributes from the provoking vertex.
864-
GSVertex v_default = primclass == GS_SPRITE_CLASS ? m_vertex.buff[1] : m_vertex.buff[2];
864+
GSVertex v_default = primclass == GS_SPRITE_CLASS ? m_vertex.buff[m_index.buff[1]] :
865+
m_vertex.buff[m_index.buff[2]];
865866

866867
const auto SetTexCoords = [&](float u, float v, GSVertex& vtx_out) {
867868
if constexpr (fst)
@@ -882,7 +883,10 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
882883
vtx_out.XYZ.Y = xyof.y + static_cast<u32>(y * 16.0f);
883884
};
884885

885-
const auto WriteQuad = [&](const GSVector4& xy, GSVector4 uv, GSVertex*& vout, u16*& iout) {
886+
const auto WriteQuad = [&](const GSVector4i& xyi, const GSVector4i& uvi, GSVertex*& vout, u16*& iout) {
887+
GSVector4 xy(xyi);
888+
GSVector4 uv(uvi);
889+
886890
if (bilinear)
887891
{
888892
// Translate to texel center for bilinear.
@@ -994,6 +998,7 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
994998

995999
if (m_texture_shuffle.real_16_bit_source)
9961000
{
1001+
GL_INS("Real 16 bit source: no tex coord change.");
9971002
half_u = false;
9981003
half_v = false;
9991004
}
@@ -1002,6 +1007,7 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
10021007
m_texture_shuffle.type == TextureShuffleType::TwoPixel ||
10031008
m_texture_shuffle.type == TextureShuffleType::HackShuffle)
10041009
{
1010+
GL_INS("Split shuffle/TwoPixel/HackShuffle: no pos or tex coord change.");
10051011
half_x = false;
10061012
half_y = false;
10071013
half_u = false;
@@ -1012,6 +1018,8 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
10121018
// Currently, this shuffle is done with the NFS CRC hack.
10131019
// It is a split texture shuffle, but the draws are skipped with the hack instead of
10141020
// being combined in the usual way, so we need to adjust the draw rect here.
1021+
GL_INS("GappedSwizzle (NFS Undercover): rewriting rects to use full area.");
1022+
10151023
half_x = false;
10161024
half_y = false;
10171025
half_u = false;
@@ -1020,12 +1028,12 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
10201028
m_r = rt->GetUnscaledRect();
10211029
tex_r = tex->GetUnscaledRect();
10221030
scissor_r = m_r;
1023-
1024-
GL_INS("GappedSwizzle (NFS Undercover): rewriting rects to use full area.");
10251031
}
10261032
else if (m_texture_shuffle.type == TextureShuffleType::Swizzle ||
10271033
m_texture_shuffle.type == TextureShuffleType::SwizzleTex32)
10281034
{
1035+
GL_INS("Swizzle/SwizzleTex32: no tex coord change.");
1036+
10291037
if (m_cached_ctx.FRAME.FBW == rt->m_TEX0.TBW * 2)
10301038
{
10311039
half_y = false;
@@ -1044,6 +1052,7 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
10441052
// No super source of truth here, since the width can get batted around, the valid is probably our best bet.
10451053
// Dogs will reuse the Z in a different size format for a completely unrelated draw with an FBW of 2,
10461054
// then go back to using it in full width.
1055+
GL_INS("Non-recursive draw, complex case.");
10471056

10481057
const bool tex_tbw_is_wrong =
10491058
tex->m_target &&
@@ -1131,6 +1140,7 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
11311140
else
11321141
{
11331142
// Handle recursive draws.
1143+
GL_INS("Recursive draw, complex case.");
11341144

11351145
const GSVector2i& frame_pgs = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs;
11361146

@@ -1227,7 +1237,7 @@ void GSRendererHW::ConvertSpriteTextureShuffleImpl(GSTextureCache::Target* rt, G
12271237
GSVertex* vout = m_vertex.buff;
12281238
u16* iout = m_index.buff;
12291239

1230-
WriteQuad(GSVector4(m_r), GSVector4(tex_r), vout, iout);
1240+
WriteQuad(m_r, tex_r, vout, iout);
12311241

12321242
m_index.tail = iout - m_index.buff;
12331243
m_vertex.head = m_vertex.tail = m_vertex.next = vout - m_vertex.buff;
@@ -1267,7 +1277,8 @@ GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Sou
12671277
{
12681278
if (GSConfig.UserHacks_HalfPixelOffset <= GSHalfPixelOffset::Normal ||
12691279
GSConfig.UserHacks_HalfPixelOffset >= GSHalfPixelOffset::Native ||
1270-
GetUpscaleMultiplier() == 1.0f || m_downscale_source || tex->GetScale() == 1.0f)
1280+
GetUpscaleMultiplier() == 1.0f || m_downscale_source || tex->GetScale() == 1.0f ||
1281+
m_texture_shuffle) // Do not apply HPO on texture shuffles as it already aligns the coordinates.
12711282
{
12721283
return GSVector4(0.0f);
12731284
}
@@ -5359,7 +5370,9 @@ void GSRendererHW::SetupIA(float target_scale, float sx, float sy, bool req_vert
53595370
{
53605371
GL_PUSH("HW: IA");
53615372

5362-
if (GSConfig.UserHacks_ForceEvenSpritePosition && !m_isPackedUV_HackFlag && m_process_texture && PRIM->FST)
5373+
// Do not force even sprite positive for texture shuffles since the coordinates are already aligned.
5374+
if (GSConfig.UserHacks_ForceEvenSpritePosition && !m_isPackedUV_HackFlag && m_process_texture && PRIM->FST &&
5375+
!m_texture_shuffle)
53635376
{
53645377
for (u32 i = 0; i < m_vertex.next; i++)
53655378
m_vertex.buff[i].UV &= 0x3FEF3FEF;
@@ -7520,7 +7533,8 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
75207533

75217534
// Can be seen with the cabin part of the ship in God of War, offsets are required when using FST.
75227535
// ST uses a normalized position so doesn't need an offset here, will break Bionicle Heroes.
7523-
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
7536+
// Do not apply HPO on texture shuffles as it already aligns the coordinates.
7537+
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset && !m_texture_shuffle)
75247538
{
75257539
const u32 psm = rt ? rt->m_TEX0.PSM : ds->m_TEX0.PSM;
75267540
const bool can_offset = m_r.width() > GSLocalMemory::m_psm[psm].pgs.x || m_r.height() > GSLocalMemory::m_psm[psm].pgs.y;

0 commit comments

Comments
 (0)