Compare commits

...

11 Commits

Author SHA1 Message Date
lightningterror
ae8808b86e GS/HW: Backport some tex is fb shaders to dx and opengl. 2025-05-15 20:08:16 +02:00
lightningterror
8d5b827432 GS/HW: Fix texture copies when tex is fb draw.
Fixes an issue with texture copies didn't work properly on tex is fb draw:
Fixes Hitman Blood Money on minimum blend.

DX can't do partial depth copy so do a shader based copy which works.
Fixes a bunch of games that couldn't do partial depth copy on dx.
2025-05-15 20:08:16 +02:00
lightningterror
cb672697e7 FullscreenUI: Fix -Wlogical-op-parentheses warning. 2025-05-15 20:08:16 +02:00
JordanTheToaster
0bae9fc29b Deps: Update SDL3 to 3.2.14 2025-05-15 18:43:45 +02:00
lightningterror
49c8b68700 GS/HW: Enable feedback loop if channel shuffle enabled barriers. 2025-05-15 18:43:35 +02:00
refractionpcsx2
1e2fcd17e0 GS/HW: Fix new target creation width when doing a page copy 2025-05-15 01:45:11 +02:00
refractionpcsx2
468b9d2655 GS/TC: Use frame width on PSMT8H read if target width doesn't match frame on Tex in RT.
Also changed LookupSource/Depth to receive the whole FRAME struct, not just the pointer.
2025-05-15 01:45:11 +02:00
refractionpcsx2
a3305ff791 GS/TC: Used unwrapped end blocks for combine 2025-05-15 01:45:11 +02:00
PCSX2 Bot
814b0d5873 [ci skip] Qt: Update Base Translation. 2025-05-13 20:00:55 +02:00
refractionpcsx2
863f3e82ac GS/HW: Combine target using the drawn area, not valid area (some of this can be garbage) 2025-05-13 19:56:39 +02:00
Ty
529c756458 GitHub: Require PR authors to disclose AI usage
[noci]
2025-05-12 18:12:02 -04:00
16 changed files with 103 additions and 66 deletions

View File

@@ -6,3 +6,9 @@
### Suggested Testing Steps
<!-- If applicable, including examples you've already tested with / recommendations for how to test further is very helpful! -->
### Did you use AI to help find, test, or implement this issue or feature?
<!-- Insert an X in one of the boxes. This is a required field. -->
- [ ] No, I did not use AI.
- [ ] Yes (please explain briefly):

View File

@@ -18,7 +18,7 @@ LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
LIBJPEGTURBO=3.1.0
LIBPNG=1.6.48
LIBWEBP=1.5.0
SDL=SDL3-3.2.12
SDL=SDL3-3.2.14
QT=6.9.0
LZ4=1.10.0
ZSTD=1.5.7
@@ -39,7 +39,7 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
c1800c2ea835801af04a05d4a32321d79a93954ee3ae2172bbeacf13d1f0598c qtbase-everywhere-src-$QT.tar.xz

View File

@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL3-3.2.12.tar.gz",
"sha256": "9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96"
"url": "https://libsdl.org/release/SDL3-3.2.14.tar.gz",
"sha256": "b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f"
}
],
"cleanup": [

View File

@@ -40,7 +40,7 @@ fi
FREETYPE=2.13.3
HARFBUZZ=11.2.0
SDL=SDL3-3.2.12
SDL=SDL3-3.2.14
ZSTD=1.5.7
LZ4=1.10.0
LIBPNG=1.6.48
@@ -79,7 +79,7 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
16c0204704f3ebeed057aba100fe7db18d71035505cb10e595ea33d346457fc8 harfbuzz-$HARFBUZZ.tar.gz
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz

View File

@@ -22,7 +22,7 @@ fi
FREETYPE=2.13.3
HARFBUZZ=11.2.0
SDL=SDL3-3.2.12
SDL=SDL3-3.2.14
ZSTD=1.5.7
LZ4=1.10.0
LIBPNG=1.6.48
@@ -59,7 +59,7 @@ CMAKE_COMMON=(
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
16c0204704f3ebeed057aba100fe7db18d71035505cb10e595ea33d346457fc8 harfbuzz-$HARFBUZZ.tar.gz
9734f308e130c64a2b4df6bca5884c5aca577ee6c7c77ab3379474ea85e51f96 $SDL.tar.gz
b7e7dc05011b88c69170fe18935487b2559276955e49113f8c1b6b72c9b79c1f $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
46fd06ff37db1db64c0dc288d78a3f5efd23ad9ac41561193f983e20937ece03 libpng-$LIBPNG.tar.xz

View File

@@ -46,7 +46,7 @@ set FREETYPE=2.13.3
set HARFBUZZ=11.2.0
set LIBJPEGTURBO=3.1.0
set LIBPNG=1648
set SDL=SDL3-3.2.12
set SDL=SDL3-3.2.14
set QT=6.9.0
set QTMINOR=6.9
set LZ4=1.10.0
@@ -68,7 +68,7 @@ call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuz
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1648.zip 2e5f080360f77376eb2bfa9e2ed773b9c7728159aba47b638ad53ca839379040 || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ebf1efd71527afbca6bdf2b0310caf726d00cc102c0e59ac86c1f8cd201f9593 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 46a17d3ea71fe2580a7f43ca7da286c5b9106dd761e2fd5533bb113e5d86b633 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error

View File

@@ -44,7 +44,7 @@ set FREETYPE=2.13.3
set HARFBUZZ=11.2.0
set LIBJPEGTURBO=3.1.0
set LIBPNG=1648
set SDL=SDL3-3.2.12
set SDL=SDL3-3.2.14
set QT=6.9.0
set QTMINOR=6.9
set LZ4=1.10.0
@@ -66,7 +66,7 @@ call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuz
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1648.zip 2e5f080360f77376eb2bfa9e2ed773b9c7728159aba47b638ad53ca839379040 || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ebf1efd71527afbca6bdf2b0310caf726d00cc102c0e59ac86c1f8cd201f9593 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 46a17d3ea71fe2580a7f43ca7da286c5b9106dd761e2fd5533bb113e5d86b633 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 513df15a6365a40f6230ec9463ad8c71b824e181d4b661dac9707e103b24ae0c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" d428fd17a0d3f92c48a30f1d23806bf20352fbce2e80e5bbee27fa80576480ee || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 54bf06afeb67035f1c6afcd00beec755c0d776626b4cce9ab56992a55215ba69 || goto error

View File

@@ -397,7 +397,11 @@ float4 fetch_raw_color(int2 xy)
float4 fetch_c(int2 uv)
{
#if PS_TEX_IS_FB == 1
return RtTexture.Load(int3(uv, 0));
#else
return Texture.Load(int3(uv, 0));
#endif
}
//////////////////////////////////////////////////////////////////////

View File

@@ -330,7 +330,11 @@ vec4 fetch_raw_color()
vec4 fetch_c(ivec2 uv)
{
#if PS_TEX_IS_FB == 1
return sample_from_rt();
#else
return texelFetch(TextureSampler, ivec2(uv), 0);
#endif
}
//////////////////////////////////////////////////////////////////////

View File

@@ -10786,67 +10786,67 @@ Do you want to load this save and continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="452"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="464"/>
<source>Saving screenshot to &apos;{}&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="464"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="476"/>
<source>Saved screenshot to &apos;{}&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="471"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="483"/>
<source>Failed to save screenshot to &apos;{}&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="542"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="554"/>
<source>Host GPU device encountered an error and was recovered. This may have broken rendering.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="647"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="659"/>
<source>CAS is not available, your graphics driver does not support the required functionality.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="702"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="714"/>
<source>with no compression</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="709"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="721"/>
<source>with LZMA compression</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="716"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="728"/>
<source>with Zstandard compression</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="722"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="734"/>
<source>Saving {0} GS dump {1} to &apos;{2}&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="723"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="735"/>
<source>single frame</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="723"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="735"/>
<source>multi-frame</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="743"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="755"/>
<source>Failed to render/download screenshot.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="754"/>
<location filename="../../pcsx2/GS/Renderers/Common/GSRenderer.cpp" line="766"/>
<source>Saved GS dump to &apos;{}&apos;.</source>
<translation type="unfinished"></translation>
</message>

View File

@@ -372,6 +372,7 @@ struct alignas(16) GSHWDrawConfig
// Others ways to fetch the texture
u32 channel : 3;
u32 channel_fb : 1;
// Dithering
u32 dither : 2;
@@ -410,7 +411,7 @@ struct alignas(16) GSHWDrawConfig
{
const u32 sw_blend_bits = blend_a | blend_b | blend_d;
const bool sw_blend_needs_rt = (sw_blend_bits != 0 && ((sw_blend_bits | blend_c) & 1u)) || ((a_masked & blend_c) != 0);
return tex_is_fb || fbmask || (date > 0 && date != 3) || sw_blend_needs_rt;
return channel_fb || tex_is_fb || fbmask || (date > 0 && date != 3) || sw_blend_needs_rt;
}
/// Disables color output from the pixel shader, this is done when all channels are masked.

View File

@@ -2920,9 +2920,9 @@ void GSRendererHW::Draw()
}
else
{
src = tex_psm.depth ? g_texture_cache->LookupDepthSource(true, TEX0, env.TEXA, MIP_CLAMP, tmm.coverage, possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME.Block(), req_color, req_alpha) :
src = tex_psm.depth ? g_texture_cache->LookupDepthSource(true, TEX0, env.TEXA, MIP_CLAMP, tmm.coverage, possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha) :
g_texture_cache->LookupSource(true, TEX0, env.TEXA, MIP_CLAMP, tmm.coverage, (GSConfig.HWMipmap || GSConfig.TriFilter == TriFiltering::Forced) ? &hash_lod_range : nullptr,
possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME.Block(), req_color, req_alpha);
possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha);
if (!src) [[unlikely]]
{
@@ -3212,7 +3212,7 @@ void GSRendererHW::Draw()
CleanupDraw(true);
return;
}
else if (IsPageCopy() && src->m_from_target && m_cached_ctx.TEX0.TBP0 >= src->m_from_target->m_TEX0.TBP0)
else if (IsPageCopy() && src->m_from_target && m_cached_ctx.TEX0.TBP0 >= src->m_from_target->m_TEX0.TBP0 && m_cached_ctx.FRAME.FBW < ((src->m_from_target->m_TEX0.TBW + 1) >> 1))
{
FRAME_TEX0.TBW = src->m_from_target->m_TEX0.TBW;
}
@@ -3264,8 +3264,6 @@ void GSRendererHW::Draw()
const GSVector4i new_drect = GSVector4i(0, new_offset * rt->m_scale, new_size.x * rt->m_scale, new_size.y * rt->m_scale);
rt->ResizeTexture(new_size.x, new_size.y, true, true, new_drect);
g_texture_cache->CombineAlignedInsideTargets(rt, src);
if (src && src->m_from_target && src->m_from_target == rt && src->m_target_direct)
{
src->m_texture = rt->m_texture;
@@ -3283,6 +3281,8 @@ void GSRendererHW::Draw()
rt->m_drawn_since_read.y += new_offset;
rt->m_drawn_since_read.w += new_offset;
g_texture_cache->CombineAlignedInsideTargets(rt, src);
if (rt->m_dirty.size())
{
for (int i = 0; i < static_cast<int>(rt->m_dirty.size()); i++)
@@ -5030,6 +5030,8 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
// Hitman suffers from this, not sure on the exact scenario at the moment, but we need the barrier.
if (PRIM->ABE && m_context->ALPHA.IsCdInBlend())
{
// Needed to enable IsFeedbackLoop.
m_conf.ps.channel_fb = 1;
// Assume no overlap when it's a channel shuffle, no need for full barriers.
m_conf.require_one_barrier = true;
}
@@ -6507,8 +6509,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
src_copy.reset(src_target->m_texture->IsDepthStencil() ?
g_gs_device->CreateDepthStencil(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), false) :
(m_downscale_source || copied_rt) ? g_gs_device->CreateRenderTarget(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), true, true) :
g_gs_device->CreateTexture(scaled_copy_size.x, scaled_copy_size.y, 1, src_target->m_texture->GetFormat(), true));
g_gs_device->CreateRenderTarget(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), true, true));
if (!src_copy) [[unlikely]]
{
Console.Error("HW: Failed to allocate %dx%d texture for hazard copy", scaled_copy_size.x, scaled_copy_size.y);
@@ -6548,8 +6549,20 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
}
else
{
g_gs_device->CopyRect(
src_target->m_texture, src_copy.get(), scaled_copy_range, scaled_copy_dst_offset.x, scaled_copy_dst_offset.y);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
const GSVector4i offset = copy_range - GSVector4i(copy_dst_offset).xyxy();
// Adjust for bilinear, must be done after calculating offset.
copy_range.x -= 1;
copy_range.y -= 1;
copy_range.z += 1;
copy_range.w += 1;
copy_range = copy_range.rintersect(src_bounds);
const GSVector4 src_rect = GSVector4(copy_range) / GSVector4(src_unscaled_size).xyxy();
const GSVector4 dst_rect = (GSVector4(copy_range) - GSVector4(offset).xyxy()) * scale;
g_gs_device->StretchRect(src_target->m_texture, src_rect, src_copy.get(), dst_rect,
src_target->m_texture->IsDepthStencil() ? ShaderConvert::DEPTH_COPY : ShaderConvert::COPY, false);
}
m_conf.tex = src_copy.get();
}

View File

@@ -998,7 +998,7 @@ __ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, cons
return nullptr;
}
GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const u32 frame_fbp, bool req_color, bool req_alpha, bool palette)
GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color, bool req_alpha, bool palette)
{
if (GSConfig.UserHacks_DisableDepthSupport)
{
@@ -1183,7 +1183,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
else
{
// This is a bit of a worry, since it could load junk from local memory... but it's better than skipping the draw.
return is_depth ? LookupSource(false, TEX0, TEXA, CLAMP, r, nullptr, possible_shuffle, linear, frame_fbp, req_color, req_alpha) : nullptr;
return is_depth ? LookupSource(false, TEX0, TEXA, CLAMP, r, nullptr, possible_shuffle, linear, frame, req_color, req_alpha) : nullptr;
}
pxAssert(src->m_texture);
@@ -1192,7 +1192,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
return src;
}
GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const u32 frame_fbp, bool req_color, bool req_alpha)
GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color, bool req_alpha)
{
GL_CACHE("TC: Lookup Source <%d,%d => %d,%d> (0x%x, %s, BW: %u, CBP: 0x%x, TW: %d, TH: %d)", r.x, r.y, r.z, r.w, TEX0.TBP0, psm_str(TEX0.PSM), TEX0.TBW, TEX0.CBP, 1 << TEX0.TW, 1 << TEX0.TH);
@@ -1456,7 +1456,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
else
{
rect_clean = t->m_dirty.empty();
if (!possible_shuffle && frame_fbp != t->m_TEX0.TBP0 && rect_clean && bp == t->m_TEX0.TBP0 && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && width_match && real_fmt_match)
if (!possible_shuffle && frame.Block() != t->m_TEX0.TBP0 && rect_clean && bp == t->m_TEX0.TBP0 && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && width_match && real_fmt_match)
{
if (!tex_merge_rt && t->Overlaps(bp, bw, psm, req_rect))
{
@@ -1485,7 +1485,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
}
if (t->m_TEX0.TBP0 != frame_fbp && !possible_shuffle && bp > t->m_TEX0.TBP0 && t->Overlaps(bp, bw, psm, req_rect) && GSUtil::GetChannelMask(psm) == GSUtil::GetChannelMask(t->m_TEX0.PSM) && !width_match)
if (t->m_TEX0.TBP0 != frame.Block() && !possible_shuffle && bp > t->m_TEX0.TBP0 && t->Overlaps(bp, bw, psm, req_rect) && GSUtil::GetChannelMask(psm) == GSUtil::GetChannelMask(t->m_TEX0.PSM) && !width_match)
{
GSVector4i new_rect = req_rect;
@@ -1710,11 +1710,12 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
GSVector4i new_rect = (GSLocalMemory::m_psm[color_psm].bpp != GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp && (psm & 0x7) != PSMCT16) ? block_boundary_rect : rect;
// Check if it is possible to hit with valid <x,y> offset on the given Target.
// Fixes Jak eyes rendering.
// Fixes Xenosaga 3 last dungeon graphic bug.
// Fixes Pause menu in The Getaway.
const bool can_translate = CanTranslate(bp, bw, src_psm, new_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW);
// If the sizing is completely wrong on the frame vs the source when reading from alpha then it's likely the target has 2 different sizes for rgb and alpha.
// This is just changing the target width for the rect translation, it has no bearing on the actual source read or the target itself.
// Hitman Blood Money is an example of this in the theatre.
const u32 rt_tbw = (possible_shuffle || bw == 1 || GSUtil::GetChannelMask(psm) != 0x8 || frame.FBW <= bw || frame.FBW == t->m_TEX0.TBW) ? t->m_TEX0.TBW : frame.FBW;
const bool can_translate = CanTranslate(bp, bw, src_psm, new_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, rt_tbw);
if (can_translate)
{
const bool swizzle_match = GSLocalMemory::m_psm[src_psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
@@ -1724,7 +1725,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
if (swizzle_match)
{
rect = TranslateAlignedRectByPage(t, bp, src_psm, bw, new_rect);
rect = TranslateAlignedRectByPage(t->m_TEX0.TBP0, t->m_end_block, rt_tbw, t->m_TEX0.PSM, bp, src_psm, bw, new_rect);
rect.x -= new_rect.x;
rect.y -= new_rect.y;
}
@@ -1773,7 +1774,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
dst = t;
tex_merge_rt = false;
found_t = true;
if (dst->m_TEX0.TBP0 == frame_fbp && possible_shuffle)
if (dst->m_TEX0.TBP0 == frame.Block() && possible_shuffle)
break;
else
continue;
@@ -1799,7 +1800,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
tex_merge_rt = false;
found_t = true;
// Keep looking, just in case there is an exact match (Situation: Target frame drawn inside target frame, current makes a separate texture)
if (dst->m_TEX0.TBP0 == frame_fbp && possible_shuffle)
if (dst->m_TEX0.TBP0 == frame.Block() && possible_shuffle)
break;
else
continue;
@@ -1856,7 +1857,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
break;
}
if (dst->m_TEX0.TBP0 == frame_fbp && possible_shuffle)
if (dst->m_TEX0.TBP0 == frame.Block() && possible_shuffle)
break;
else
continue;
@@ -1873,7 +1874,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
// Prefer a target inside over a target outside.
found_t = false;
if (dst->m_TEX0.TBP0 == frame_fbp && possible_shuffle)
if (dst->m_TEX0.TBP0 == frame.Block() && possible_shuffle)
break;
else
continue;
@@ -1934,7 +1935,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
GIFRegTEX0 depth_TEX0;
depth_TEX0.U32[0] = TEX0.U32[0] | (0x30u << 20u);
depth_TEX0.U32[1] = TEX0.U32[1];
src = LookupDepthSource(false, depth_TEX0, TEXA, CLAMP, block_boundary_rect, possible_shuffle, linear, frame_fbp, req_color, req_alpha);
src = LookupDepthSource(false, depth_TEX0, TEXA, CLAMP, block_boundary_rect, possible_shuffle, linear, frame, req_color, req_alpha);
if (src != nullptr)
{
@@ -1956,7 +1957,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
else
{
src = LookupDepthSource(false, TEX0, TEXA, CLAMP, block_boundary_rect, possible_shuffle, linear, frame_fbp, req_color, req_alpha, true);
src = LookupDepthSource(false, TEX0, TEXA, CLAMP, block_boundary_rect, possible_shuffle, linear, frame, req_color, req_alpha, true);
if (src != nullptr)
{
@@ -2096,7 +2097,7 @@ void GSTextureCache::CombineAlignedInsideTargets(Target* target, GSTextureCache:
if (t != target)
{
// Target not contained, skip it.
if (t->m_TEX0.TBP0 < target->m_TEX0.TBP0 || t->m_end_block > target->m_end_block)
if (t->m_TEX0.TBP0 < target->m_TEX0.TBP0 || t->UnwrappedEndBlock() > target->UnwrappedEndBlock())
{
i++;
continue;
@@ -2112,16 +2113,24 @@ void GSTextureCache::CombineAlignedInsideTargets(Target* target, GSTextureCache:
{
if (t->m_last_draw > target->m_last_draw || t->m_valid.rintersect(target->m_valid).rempty())
{
t->Update();
const u32 vertical_offset = (((t->m_TEX0.TBP0 - target->m_TEX0.TBP0) >> 5) / std::max(1U, t->m_TEX0.TBW)) * t_psm.pgs.y;
const u32 horizontal_offset = page_offset * t_psm.pgs.x;
const GSVector4i target_drect_unscaled = t->m_valid + GSVector4i(horizontal_offset, vertical_offset).xyxy();
const GSVector4 target_drect = GSVector4(target_drect_unscaled) * target->m_scale;
const bool valid_color = t->m_valid_rgb;
const bool valid_alpha = (t->m_valid_alpha_high | t->m_valid_alpha_low) && (GSUtil::GetChannelMask(t->m_TEX0.PSM) & 0x8);
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1), target->m_texture, target_drect, valid_color, valid_color, valid_color, valid_alpha, (target->m_type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY);
if (!t->m_drawn_since_read.rempty())
{
t->Update();
target->UpdateValidity(target_drect_unscaled);
const u32 vertical_offset = (((t->m_TEX0.TBP0 - target->m_TEX0.TBP0) >> 5) / std::max(1U, t->m_TEX0.TBW)) * t_psm.pgs.y;
const u32 horizontal_offset = page_offset * t_psm.pgs.x;
const GSVector4i target_drect_unscaled = t->m_drawn_since_read + GSVector4i(horizontal_offset, vertical_offset).xyxy();
const GSVector4 source_rect = GSVector4(t->m_drawn_since_read) / (GSVector4(t->m_unscaled_size) * t->GetScale());
const GSVector4 target_drect = GSVector4(target_drect_unscaled) * target->m_scale;
const bool valid_color = t->m_valid_rgb;
const bool valid_alpha = (t->m_valid_alpha_high | t->m_valid_alpha_low) && (GSUtil::GetChannelMask(t->m_TEX0.PSM) & 0x8);
g_gs_device->StretchRect(t->m_texture, source_rect, target->m_texture, target_drect, valid_color, valid_color, valid_color, valid_alpha, (target->m_type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY);
target->UpdateValidity(target_drect_unscaled);
}
}
if (src && src->m_from_target == t)

View File

@@ -494,8 +494,8 @@ public:
GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size);
std::shared_ptr<Palette> LookupPaletteObject(const u32* clut, u16 pal, bool need_gs_texture);
Source* LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const u32 frame_fbp = 0xFFFFFFFF, bool req_color = true, bool req_alpha = true);
Source* LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const u32 frame_fbp = 0xFFFFFFFF, bool req_color = true, bool req_alpha = true, bool palette = false);
Source* LookupSource(const bool is_color, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const GSVector2i* lod, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color = true, bool req_alpha = true);
Source* LookupDepthSource(const bool is_depth, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GIFRegCLAMP& CLAMP, const GSVector4i& r, const bool possible_shuffle, const bool linear, const GIFRegFRAME& frame, bool req_color = true, bool req_alpha = true, bool palette = false);
Target* FindTargetOverlap(Target* target, int type, int psm);
void CombineAlignedInsideTargets(Target* target, GSTextureCache::Source* src = nullptr);

View File

@@ -613,7 +613,7 @@ void FullscreenUI::ApplyLayoutSettings(const SettingsInterface* bsi)
const InputLayout layout = ImGuiFullscreen::GetGamepadLayout();
if (sdl2_nintendo_mode == "true" || (sdl2_nintendo_mode == "auto") && layout == InputLayout::Nintendo)
if ((sdl2_nintendo_mode == "true" || sdl2_nintendo_mode == "auto") && layout == InputLayout::Nintendo)
{
// Apply
ImGuiManager::SwapGamepadNorthWest(true);

View File

@@ -3,4 +3,4 @@
/// Version number for GS and other shaders. Increment whenever any of the contents of the
/// shaders change, to invalidate the cache.
static constexpr u32 SHADER_CACHE_VERSION = 64;
static constexpr u32 SHADER_CACHE_VERSION = 65;