mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Detect shuffles reshaping the target
This commit is contained in:
parent
e9ac262cd3
commit
d6e3eccf45
|
@ -444,35 +444,46 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
|
||||||
// If a game does the texture and frame doubling differently, they can burn in hell.
|
// If a game does the texture and frame doubling differently, they can burn in hell.
|
||||||
if (!m_copy_16bit_to_target_shuffle && m_cached_ctx.TEX0.TBP0 != m_cached_ctx.FRAME.Block())
|
if (!m_copy_16bit_to_target_shuffle && m_cached_ctx.TEX0.TBP0 != m_cached_ctx.FRAME.Block())
|
||||||
{
|
{
|
||||||
unsigned int max_tex_draw_width = std::min(static_cast<int>(m_vt.m_max.t.x + (!process_ba ? 8 : 0)), 1 << m_cached_ctx.TEX0.TW);
|
|
||||||
const unsigned int clamp_minu = m_context->CLAMP.MINU;
|
|
||||||
const unsigned int clamp_maxu = m_context->CLAMP.MAXU;
|
|
||||||
|
|
||||||
switch (m_context->CLAMP.WMS)
|
|
||||||
{
|
|
||||||
case CLAMP_REGION_CLAMP:
|
|
||||||
max_tex_draw_width = std::min(max_tex_draw_width, clamp_maxu);
|
|
||||||
break;
|
|
||||||
case CLAMP_REGION_REPEAT:
|
|
||||||
max_tex_draw_width = std::min(max_tex_draw_width, (clamp_maxu | clamp_minu));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No super source of truth here, since the width can get batted around, the valid is probably our best bet.
|
// No super source of truth here, since the width can get batted around, the valid is probably our best bet.
|
||||||
// Dogs will reuse the Z in a different size format for a completely unrelated draw with an FBW of 2, then go back to using it in full width
|
// Dogs will reuse the Z in a different size format for a completely unrelated draw with an FBW of 2, then go back to using it in full width
|
||||||
const bool size_is_wrong = tex->m_target ? (static_cast<int>(tex->m_from_target_TEX0.TBW * 64) < tex->m_from_target->m_valid.z / 2) : false;
|
const bool size_is_wrong = tex->m_target ? (static_cast<int>(tex->m_from_target_TEX0.TBW * 64) < tex->m_from_target->m_valid.z / 2) : false;
|
||||||
const int tex_width = tex->m_target ? std::min(tex->m_from_target->m_valid.z, size_is_wrong ? tex->m_from_target->m_valid.z : static_cast<int>(tex->m_from_target_TEX0.TBW * 64)) : max_tex_draw_width;
|
const u32 draw_page_width = std::max(static_cast<int>(m_vt.m_max.p.x + (!(process_ba & SHUFFLE_WRITE) ? 8.9f : 0.9f)) / 64, 1);
|
||||||
const int tex_tbw = tex->m_target ? tex->m_from_target_TEX0.TBW : tex->m_TEX0.TBW;
|
if (size_is_wrong || (rt && (rt->m_TEX0.TBW % draw_page_width) == 0))
|
||||||
|
|
||||||
if (static_cast<int>(m_cached_ctx.TEX0.TBW * 64) >= (tex_width * 2) && tex_tbw != m_cached_ctx.TEX0.TBW)
|
|
||||||
{
|
{
|
||||||
half_bottom_uv = false;
|
unsigned int max_tex_draw_width = std::min(static_cast<int>(floor(m_vt.m_max.t.x + (!(process_ba & SHUFFLE_READ) ? 8.9f : 0.9f))), 1 << m_cached_ctx.TEX0.TW);
|
||||||
half_bottom_vert = false;
|
const unsigned int clamp_minu = m_context->CLAMP.MINU;
|
||||||
|
const unsigned int clamp_maxu = m_context->CLAMP.MAXU;
|
||||||
|
|
||||||
|
switch (m_context->CLAMP.WMS)
|
||||||
|
{
|
||||||
|
case CLAMP_REGION_CLAMP:
|
||||||
|
max_tex_draw_width = std::min(max_tex_draw_width, clamp_maxu);
|
||||||
|
break;
|
||||||
|
case CLAMP_REGION_REPEAT:
|
||||||
|
max_tex_draw_width = std::min(max_tex_draw_width, (clamp_maxu | clamp_minu));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int tex_width = tex->m_target ? std::min(tex->m_from_target->m_valid.z, size_is_wrong ? tex->m_from_target->m_valid.z : static_cast<int>(tex->m_from_target_TEX0.TBW * 64)) : max_tex_draw_width;
|
||||||
|
const int tex_tbw = tex->m_target ? tex->m_from_target_TEX0.TBW : tex->m_TEX0.TBW;
|
||||||
|
|
||||||
|
if (static_cast<int>(m_cached_ctx.TEX0.TBW * 64) >= (tex_width * 2) && tex_tbw != m_cached_ctx.TEX0.TBW)
|
||||||
|
{
|
||||||
|
half_bottom_uv = false;
|
||||||
|
half_bottom_vert = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
half_right_uv = false;
|
||||||
|
half_right_vert = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
half_bottom_uv = false;
|
||||||
|
half_bottom_vert = false;
|
||||||
half_right_uv = false;
|
half_right_uv = false;
|
||||||
half_right_vert = false;
|
half_right_vert = false;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +634,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
|
||||||
|
|
||||||
if (!m_same_group_texture_shuffle)
|
if (!m_same_group_texture_shuffle)
|
||||||
{
|
{
|
||||||
if (process_ba & SHUFFLE_WRITE)
|
if (process_ba & SHUFFLE_READ)
|
||||||
m_vt.m_min.t.x -= 8.0f;
|
m_vt.m_min.t.x -= 8.0f;
|
||||||
else
|
else
|
||||||
m_vt.m_max.t.x += 8.0f;
|
m_vt.m_max.t.x += 8.0f;
|
||||||
|
@ -633,30 +644,31 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
|
||||||
if (half_right_vert)
|
if (half_right_vert)
|
||||||
{
|
{
|
||||||
m_vt.m_min.p.x /= 2.0f;
|
m_vt.m_min.p.x /= 2.0f;
|
||||||
m_vt.m_max.p.x /= 2.0f;
|
m_vt.m_max.p.x = floor(m_vt.m_max.p.x + 1.9f) / 2.0f;
|
||||||
m_context->scissor.in.x = m_vt.m_min.p.x;
|
|
||||||
m_context->scissor.in.z = m_vt.m_max.p.x + 8.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (half_bottom_vert)
|
if (half_bottom_vert)
|
||||||
{
|
{
|
||||||
m_vt.m_min.p.y /= 2.0f;
|
m_vt.m_min.p.y /= 2.0f;
|
||||||
m_vt.m_max.p.y /= 2.0f;
|
m_vt.m_max.p.y = floor(m_vt.m_max.p.y + 1.9f) / 2.0f;
|
||||||
m_context->scissor.in.y = m_vt.m_min.p.y;
|
|
||||||
m_context->scissor.in.w = m_vt.m_max.p.y + 8.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_context->scissor.in.x = m_vt.m_min.p.x;
|
||||||
|
m_context->scissor.in.z = m_vt.m_max.p.x + 0.9f;
|
||||||
|
m_context->scissor.in.y = m_vt.m_min.p.y;
|
||||||
|
m_context->scissor.in.w = m_vt.m_max.p.y + 0.9f;
|
||||||
|
|
||||||
// Only do this is the source is being interpreted as 16bit
|
// Only do this is the source is being interpreted as 16bit
|
||||||
if (half_bottom_uv)
|
if (half_bottom_uv)
|
||||||
{
|
{
|
||||||
m_vt.m_min.t.y /= 2.0f;
|
m_vt.m_min.t.y /= 2.0f;
|
||||||
m_vt.m_max.t.y /= 2.0f;
|
m_vt.m_max.t.y = (m_vt.m_max.t.y + 1.9f) / 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (half_right_uv)
|
if (half_right_uv)
|
||||||
{
|
{
|
||||||
m_vt.m_min.t.x /= 2.0f;
|
m_vt.m_min.t.x /= 2.0f;
|
||||||
m_vt.m_max.t.x /= 2.0f;
|
m_vt.m_max.t.x = (m_vt.m_max.t.x + 1.9f) / 2.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue