mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Fixes for Tex in RT and shuffle detection
This commit is contained in:
parent
4d37a9721f
commit
80e50b87f7
|
@ -1080,7 +1080,8 @@ bool GSHwHack::OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds,
|
|||
const GSVector2i copy_size(std::min(rt_size.x, src_size.x), std::min(rt_size.y, src_size.y));
|
||||
|
||||
const GSVector4 sRect(0.0f, 0.0f, static_cast<float>(copy_size.x) / static_cast<float>(src_size.x), static_cast<float>(copy_size.y) / static_cast<float>(src_size.y));
|
||||
const GSVector4 dRect(0, 0, copy_size.x, copy_size.y);
|
||||
// This is kind of a bodge because the game confuses everything since the source is really 16bit and it assumes it's really drawing 16bit on the copy back, resizing the target.
|
||||
const GSVector4 dRect(0, 0, copy_size.x, copy_size.y * (src->m_32_bits_fmt ? 1 : 2));
|
||||
|
||||
g_gs_device->StretchRect(src->m_texture, sRect, rt, dRect, true, true, true, false);
|
||||
|
||||
|
|
|
@ -2597,14 +2597,16 @@ void GSRendererHW::Draw()
|
|||
// offset coordinates swap around RG/BA. (Ace Combat)
|
||||
const u32 minv = m_cached_ctx.CLAMP.MINV;
|
||||
const u32 minu = m_cached_ctx.CLAMP.MINU;
|
||||
const bool rgba_shuffle = ((m_cached_ctx.CLAMP.WMS == m_cached_ctx.CLAMP.WMT && m_cached_ctx.CLAMP.WMS == CLAMP_REGION_REPEAT) && (minu && minv));
|
||||
// Make sure minu or minv are actually a mask on some bits, false positives of games setting 512 (0x1ff) are not masks used for shuffles.
|
||||
const bool rgba_shuffle = ((m_cached_ctx.CLAMP.WMS == m_cached_ctx.CLAMP.WMT && m_cached_ctx.CLAMP.WMS == CLAMP_REGION_REPEAT) && (minu && minv && ((minu + 1 & minu) || (minv + 1 & minv))));
|
||||
const bool shuffle_coords = ((first_x ^ first_u) & 0xF) == 8 || rgba_shuffle;
|
||||
|
||||
// Round up half of second coord, it can sometimes be slightly under.
|
||||
const int draw_width = std::abs(v[1].XYZ.X + 9 - v[0].XYZ.X) >> 4;
|
||||
const int read_width = std::abs(second_u - first_u);
|
||||
|
||||
shuffle_target = shuffle_coords && (draw_width & 7) == 0 && std::abs(draw_width - read_width) <= 1;
|
||||
// m_skip check is just mainly for NFS Undercover, but should hopefully pick up any other games which rewrite shuffles.
|
||||
shuffle_target = shuffle_coords && (((draw_width & 7) == 0 && std::abs(draw_width - read_width) <= 1) || m_skip > 50);
|
||||
}
|
||||
|
||||
if (!shuffle_target)
|
||||
|
@ -2651,7 +2653,7 @@ void GSRendererHW::Draw()
|
|||
return;
|
||||
}
|
||||
|
||||
possible_shuffle &= src && (src->m_from_target != nullptr);
|
||||
possible_shuffle &= src && (src->m_from_target != nullptr && (src->m_from_target->m_32_bits_fmt) || (m_skip && possible_shuffle));
|
||||
// We don't know the alpha range of direct sources when we first tried to optimize the alpha test.
|
||||
// Moving the texture lookup before the ATST optimization complicates things a lot, so instead,
|
||||
// recompute it, and everything derived from it again if it changes.
|
||||
|
@ -2693,7 +2695,7 @@ void GSRendererHW::Draw()
|
|||
// Urban Reign trolls by scissoring a draw to a target at 0x0-0x117F to 378x449 which ends up the size being rounded up to 640x480
|
||||
// causing the buffer to expand to around 0x1400, which makes a later framebuffer at 0x1180 to fail to be created correctly.
|
||||
// We can cheese this by checking if the Z is masked and the resultant colour is going to be black anyway.
|
||||
const bool output_black = PRIM->ABE && ((m_context->ALPHA.A == 1 || m_context->ALPHA.IsBlack()) && m_context->ALPHA.D != 1) && m_draw_env->COLCLAMP.CLAMP == 1;
|
||||
const bool output_black = PRIM->ABE && ((m_context->ALPHA.A == 1 && m_context->ALPHA.D > 1) || (m_context->ALPHA.IsBlack() && m_context->ALPHA.D != 1)) && m_draw_env->COLCLAMP.CLAMP == 1;
|
||||
const bool can_expand = !(m_cached_ctx.ZBUF.ZMSK && output_black);
|
||||
|
||||
// Estimate size based on the scissor rectangle and height cache.
|
||||
|
@ -7662,7 +7664,9 @@ void GSRendererHW::ClearGSLocalMemory(const GSOffset& off, const GSVector4i& r,
|
|||
|
||||
bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Source* tex, const GSVector4i& r_draw)
|
||||
{
|
||||
/*if (r_draw.w > 1024 && (m_vt.m_primclass == GS_SPRITE_CLASS) && (m_vertex.next == 2) && m_process_texture && !PRIM->ABE && tex && !tex->m_target && m_cached_ctx.TEX0.TBW > 0)
|
||||
// Not required when using Tex in RT
|
||||
if (r_draw.w > 1024 && (m_vt.m_primclass == GS_SPRITE_CLASS) && (m_vertex.next == 2) && m_process_texture && !PRIM->ABE &&
|
||||
tex && !tex->m_target && m_cached_ctx.TEX0.TBW > 0 && GSConfig.UserHacks_TextureInsideRt == GSTextureInRtMode::Disabled)
|
||||
{
|
||||
GL_PUSH("OI_BlitFMV");
|
||||
|
||||
|
@ -7716,7 +7720,7 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc
|
|||
g_texture_cache->InvalidateVideoMemSubTarget(_rt);
|
||||
|
||||
return false; // skip current draw
|
||||
}*/
|
||||
}
|
||||
|
||||
// Nothing to see keep going
|
||||
return true;
|
||||
|
|
|
@ -336,22 +336,8 @@ GSVector4i GSTextureCache::TranslateAlignedRectByPage(u32 tbp, u32 tebp, u32 tbw
|
|||
// Results won't be square, if it's not invalidation, it's a texture, which is problematic to translate, so let's not (FIFA 2005).
|
||||
if (!is_invalidation)
|
||||
{
|
||||
if (sbp != tbp)
|
||||
{
|
||||
// Just take the start page, as this is likely tex in rt, and that's all we care about.
|
||||
const u32 start_page = (in_rect.y / src_page_size.y) + (in_rect.x / src_page_size.x);
|
||||
in_rect.x = (start_page % dst_pgw) * dst_page_size.x;
|
||||
in_rect.y = (start_page / dst_pgw) * dst_page_size.y;
|
||||
in_rect.z = in_rect.x + dst_page_size.x;
|
||||
in_rect.w = in_rect.y + dst_page_size.y;
|
||||
|
||||
return in_rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
DevCon.Warning("Uneven pages mess up sbp %x dbp %x spgw %d dpgw %d", sbp, tbp, src_pgw, dst_pgw);
|
||||
return GSVector4i::zero();
|
||||
}
|
||||
DevCon.Warning("Uneven pages mess up sbp %x dbp %x spgw %d dpgw %d", sbp, tbp, src_pgw, dst_pgw);
|
||||
return GSVector4i::zero();
|
||||
}
|
||||
|
||||
//TODO: Maybe control dirty blocks directly and add them page at a time for better granularity.
|
||||
|
@ -1146,7 +1132,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||
// Try to make sure the target has available what we need, be careful of self referencing frames with font in the alpha.
|
||||
// Also is we have already found a target which we had to offset in to by using a region or exact address,
|
||||
// it's probable that's more correct than being inside (Tomb Raider Legends + Project Snowblind)
|
||||
if (!overlaps || (found_t && dst->m_TEX0.TBP0 >= bp && (GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw)))
|
||||
// Vakyrie Profile 2 also has some in draws which get done on a different target due to a slight offset, so we need to make sure we have the newer one.
|
||||
if (!overlaps || (found_t && (GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw)))
|
||||
continue;
|
||||
|
||||
const bool width_match = (std::max(64U, bw * 64U) >> GSLocalMemory::m_psm[psm].info.pageShiftX()) ==
|
||||
|
@ -1487,8 +1474,9 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||
DevCon.Warning("BP %x - 16bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
continue;
|
||||
}
|
||||
else if (!possible_shuffle && (GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32 && bw != 1 &&
|
||||
!((t->m_TEX0.TBW == (bw / 2)) || (t->m_TEX0.TBW >= (bw / 2) && (block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y)))))
|
||||
// Keep note that 2 bw is basically 1 normal page, as bw is in 64 pixels, and 8bit pages are 128 pixels wide, aka 2 bw.
|
||||
else if (!possible_shuffle && (GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32 &&
|
||||
!((t->m_TEX0.TBW == (bw / 2)) || (((bw + 1) / 2) <= t->m_TEX0.TBW && (block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y)))))
|
||||
{
|
||||
DevCon.Warning("BP %x - 8bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
continue;
|
||||
|
@ -1566,7 +1554,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|||
|
||||
//rect = rect.rintersect(t->m_valid);
|
||||
|
||||
if (rect.rempty())
|
||||
if (rect.rintersect(t->m_valid).rempty())
|
||||
continue;
|
||||
|
||||
if (!t->m_dirty.empty())
|
||||
|
|
Loading…
Reference in New Issue