Compare commits

...

38 Commits

Author SHA1 Message Date
refractionpcsx2
7cdf5eefc9 GS/TC: On clear delete overlapping depth targets 2025-05-24 05:03:48 +02:00
refractionpcsx2
c7ee72647d GS/HW: Improve texture shuffle/copy detection 2025-05-23 20:33:30 +02:00
Imre Eilertsen
5434af348e GameDB: Add listings for PSX Update Disc. 2025-05-23 13:31:40 +02:00
GovanifY
169cea0f01 docs: update in order to redirect from the GH wiki to our website 2025-05-22 17:43:42 +02:00
lightningterror
a8f3ec8184 GSClut: Get rid of m_read.dirty assert in GetAlphaMinMax32.
Replace it with a log.
2025-05-21 03:40:22 +02:00
lightningterror
7796b2a12b GS/HW: Add sanity/hazard checks for DATE and Texture barriers.
When checking for full barrier, also check if texture barriers
are supported.

Get rid of preprocessSel in DX11, turn off full barrier and related
stuff when not supported in rendererhw instead.

Check if StencilDate types are actually enabled, don't want to turn
it on for any others.
2025-05-21 03:40:22 +02:00
RedDevilus
d9cffd58ba GameDB: Add missing variants + fixes
Some games are missing some gamefixes or other type of fixes. Also added comment for like Energy Airforce where a legacy code never had a comment and removed mtvu for some variant + need to check in future to amend properly. Also missing entry SLPS-25875:
  name: "xxxHolic - Shigatsu Tsuitachi no Izayoi Sowa [Best Collection]"
2025-05-21 00:56:32 +02:00
refractionpcsx2
e566386240 GS/TC: only kill old misaligned targets on preload from previous frames. 2025-05-20 20:21:05 +02:00
refractionpcsx2
45af1e172f GS/HW: Improve shuffle pre-detection 2025-05-20 20:21:05 +02:00
refractionpcsx2
768b2e52a6 GS/TC: Don't allow Tex in RT 32bit target use as 16bit if not a shuffle 2025-05-20 20:21:05 +02:00
Ziemas
7abd2009b0 debugger: fix thread view row lookup 2025-05-20 11:57:11 -04:00
chaoticgd
46f075e891 DebugTools: Fix uninitialized variable in breakpoint code 2025-05-19 22:17:54 -04:00
lightningterror
832c381ac4 GS/HW: Allow partial depth copy on dx12. 2025-05-19 22:10:42 +02:00
SquishyLeaf
e021282264 CI: Fix script building universal dependencies on macOS
- Skip arm64 binaries when looking for x86_64 binaries to merge

- Change Qt download link to archive

- Build universal binaries for libjpegturbo, PlutoVG and PlutoSVG
2025-05-19 14:21:14 -04:00
PCSX2 Bot
2a60d385c6 [ci skip] PAD: Update to latest controller database. 2025-05-19 18:42:36 +02:00
refractionpcsx2
4d37e35675 GS/TC: Delete dirty rt's in src lookup + usert in rt on 3 draw old rt's 2025-05-18 11:13:35 +02:00
refractionpcsx2
df3868a280 GS/HW: Avoid target height mistakes on shuffles + Update new src == rt 2025-05-18 11:13:35 +02:00
lightningterror
0799bb8cf1 GS/DX: DX requires a copy to sample the depth buffer. 2025-05-17 22:54:04 +02:00
lightningterror
69048dede4 GS/DX11: Merge CloneTexture with CopyRect.
Unified between renderers, easier to make shared changes.
2025-05-17 22:54:04 +02:00
lightningterror
76df6d1f43 GS/GL: Check for texture creation hazard for fb copy. 2025-05-17 22:54:04 +02:00
refractionpcsx2
2d03b21f2b Formatting: Clean up some if spaces 2025-05-17 22:47:38 +02:00
refractionpcsx2
62cbd44933 GS/HW: Fix up offset Z behaviour + work even when RT isn't offset. 2025-05-17 22:47:38 +02:00
refractionpcsx2
44c8f6d8b0 GS/HW: Correct valid area for depth when taking alpha from rt. Add Tex in RT to Area 51 2025-05-17 22:47:38 +02:00
refractionpcsx2
f3fc1dd59c GS/HW: Fix some regressions relating to overlapping targets and valid rect + rgb 2025-05-17 22:47:38 +02:00
lightningterror
708931e48b GS/HW: Clean up HandleTextureHazards.
Warnings, initializations, dereferencing null pointers.
2025-05-17 22:46:37 +02:00
TheLastRar
81800d2883 CMake: Support more package configurations to import with a Devel build 2025-05-17 09:39:56 -04:00
TellowKrinkle
d0411d7ddf Core:macOS: Initialize all address variables passed to vm_map 2025-05-16 12:41:09 +02:00
Ty
70e232cab3 GitHub: Make authors disclose whether they used AI or not.
Using checkboxes implicitly made it a task list that cluttered up the PR list.

[ci skip]
2025-05-16 12:27:15 +02:00
refractionpcsx2
f90396bda4 GS/DX12: Fix command list not flushing when in surfaceless mode. 2025-05-16 12:25:16 +02:00
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
60 changed files with 822 additions and 490 deletions

View File

@@ -1,54 +0,0 @@
# So you want to contribute to PCSX2? Great
As a first step, please review these links as they'll help you understand how the development of PCSX2 works.
* [Just Starting Out](#just-starting-out)
* [Issue Reporting](#issue-reporting)
* [Pull Request Guidelines](#pull-request-guidelines)
* [General Documentation And Coding Strategies](#general-documentation-and-coding-strategies)
* [Tasks](#tasks)
## Just Starting Out
* If you're unfamilar with git, check out this [brief introduction to Git](https://github.com/PCSX2/pcsx2/wiki/07-Git-survival-guide)
* [How to build PCSX2 for Windows](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
* [How to build PCSX2 for Linux](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
## Issue Reporting
* [How to write a useful issue](https://github.com/PCSX2/pcsx2/wiki/How-to-create-useful-and-valid-issues)
## Pull Request Guidelines
The following is a list of *general* style recommendations that will make reviewing and merging easier:
* Commit Messages
* Please try to prefix your commit message, indicating what area of the project was modified.
* For example `gs: message...`.
* Looking at the project's commit history will help with keeping prefixes consistent overtime, *there is no strictly enforced list*.
* Try to keep messages brief and informative
* Remove unnecessary commits and squash commits together when appropriate.
* If you are not familiar with rebasing with git, check out the following resources:
* CLI - https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history
* GUI (SourceTree) - https://www.atlassian.com/blog/sourcetree/interactive-rebase-sourcetree
* Code Styling and Formatting
* [Consult the style guide](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
* Run `clang-format` using the configuration file in the root of the repository
* Visual Studio Setup - https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/
* IMPORTANT - if you are running `clang-format` on unrelated changes (ie. formatting an entire file), please do so in a separate commit.
* If you cannot scope your `clang-format` to just your changes and do not want to format unrelated code. Try your best to stick with the existing formatting already established in the file in question.
## General Documentation And Coding Strategies
* [Commenting Etiquette](https://github.com/PCSX2/pcsx2/wiki/06-Commenting-Etiquette)
* [Coding style](https://github.com/PCSX2/pcsx2/wiki/Code-Formatting-Guidelines)
* [More comprehensive style-guide (Currently in Draft)](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
## Tasks
* [Issues](https://github.com/PCSX2/pcsx2/issues)

View File

@@ -66,6 +66,10 @@ body:
Performance issues as a result of not meeting our hardware requirements are not valid.
Please read our troubleshooting pages and our issue reporting guide.
- [Troubleshooting page](https://pcsx2.net/docs/category/troubleshooting).
- [Issue reporting guide](https://pcsx2.net/docs/troubleshooting/identify).
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
- type: input
id: rev

View File

@@ -8,7 +8,4 @@
<!-- 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):
<!-- Answer yes or no. If you answer yes, please provide a brief explanation how. -->

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

@@ -11,7 +11,7 @@ merge_binaries() {
"
pushd "$X86DIR"
for X86BIN in $(find . -type f \( -name '*.dylib' -o -name '*.a' -o -perm +111 \)); do
if file "$X86DIR/$X86BIN" | grep "Mach-O " >/dev/null; then
if file "$X86DIR/$X86BIN" | grep "Mach-O.*x86_64" >/dev/null; then
ARMBIN="${ARMDIR}/${X86BIN}"
echo "Merge $ARMBIN to $X86BIN..."
lipo -create "$X86BIN" "$ARMBIN" -o "$X86BIN"
@@ -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
@@ -112,11 +112,11 @@ curl -C - -L \
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
@@ -213,8 +213,11 @@ echo "Installing libjpegturbo..."
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
cd "libjpeg-turbo-$LIBJPEGTURBO"
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build
make -C build "-j$NPROCS"
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
make -C build-arm64 "-j$NPROCS"
merge_binaries $(realpath build) $(realpath build-arm64)
make -C build install
cd ..
@@ -380,7 +383,7 @@ echo "Building PlutoVG..."
rm -fr "plutovg-$PLUTOVG"
tar xf "plutovg-$PLUTOVG.tar.gz"
cd "plutovg-$PLUTOVG"
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
make -C build "-j$NPROCS"
make -C build install
cd ..
@@ -389,7 +392,7 @@ echo "Building PlutoSVG..."
rm -fr "plutosvg-$PLUTOSVG"
tar xf "plutosvg-$PLUTOSVG.tar.gz"
cd "plutosvg-$PLUTOSVG"
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
make -C build "-j$NPROCS"
make -C build install
cd ..

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

@@ -66,7 +66,7 @@ const embed = new MessageEmbed()
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
.addFields(
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
{ name: 'Installation Steps', value: '[See Here](https://pcsx2.net/docs/category/setup)', inline: true },
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
);
console.log(embed);

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

@@ -24,4 +24,4 @@ Please note that a BIOS dump from a legitimately-owned PS2 console is required t
PCSX2 supports translation into other languages using [Crowdin](https://crowdin.com/project/pcsx2-emulator).
See the [Contributing Guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md) or visit the [GitHub Wiki](https://github.com/PCSX2/pcsx2/wiki) for more info on how to contribute.
See the [Contribution Guide](https://pcsx2.net/docs/contributing/) for more info on how to contribute.

View File

@@ -818,6 +818,10 @@ PCPX-96310:
name-sort: "えくすとりーむ れーしんぐ SSX [たいけんばん]"
name-en: "X-treme Racing SSX [Trial]"
region: "NTSC-J"
roundModes:
eeRoundMode: 0 # Fixes riders vanishing into the floor.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes missing lighting.
PCPX-96311:
name: "GRAN TURISMO 3 [店頭試遊ディスク Vol.1]"
name-sort: "ぐらんつーりすも 3 てんとうしゆうでぃすくVol.1"
@@ -1215,6 +1219,26 @@ PKP2-00702:
region: "NTSC-J"
gameFixes:
- SoftwareRendererFMVHack # Vertical and horizontal lines in FMV.
PSXC-00201:
name: "DESR-7000/DESR-5000 専用:PSXアップデートディスク Version 1.10"
name-sort: "でえする-7000/でえする-5000 せんよう:PSXあっぷでーとでぃす うえるしぉん 1.10"
name-en: "PSX Update Disc Version 1.10"
region: "NTSC-J"
PSXC-00202:
name: "DESR-7000/DESR-5000 専用:PSXアップデートディスク Version 1.20"
name-sort: "でえする-7000/でえする-5000 せんよう:PSXあっぷでーとでぃす うえるしぉん 1.20"
name-en: "PSX Update Disc Version 1.20"
region: "NTSC-J"
PSXC-00203:
name: "DESR-7000/DESR-5000 専用:PSXアップデートディスク Version 1.31"
name-sort: "でえする-7000/でえする-5000 せんよう:PSXあっぷでーとでぃす うえるしぉん 1.31"
name-en: "PSX Update Disc Version 1.31"
region: "NTSC-J"
PSXC-00204:
name: "DESR-7000/DESR-5000 専用:PSXアップデートディスク Version 2.11"
name-sort: "でえする-7000/でえする-5000 せんよう:PSXあっぷでーとでぃす うえるしぉん 2.11"
name-en: "PSX Update Disc Version 2.11"
region: "NTSC-J"
PUPX-93033:
name: "PlayStation Seizou Kensa-you Disc 3 CD-ROM US-ban Ver1.1"
region: "NTSC-U"
@@ -1291,6 +1315,8 @@ SCAJ-20001:
SCAJ-20002:
name: "Gallop Racer 6 - Revolution"
region: "NTSC-Unk"
gsHWFixes:
recommendedBlendingLevel: 2 # Improves lighting, maximum blending is needed for full accuracy.
SCAJ-20003:
name: "アルゴスの戦士"
name-sort: "あるごすのせんし"
@@ -1441,7 +1467,7 @@ SCAJ-20025:
name: "Grand Prix Challenge"
region: "NTSC-Unk"
gameFixes:
- VIFFIFOHack
- VIFFIFOHack # TODO check what this fixes.
SCAJ-20026:
name: "Generation of Chaos 3"
region: "NTSC-Unk"
@@ -1500,8 +1526,10 @@ SCAJ-20040:
SCAJ-20041:
name: "Energy Airforce - Aim Strike!"
region: "NTSC-Unk"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SCAJ-20043:
name: "Chain Dive"
@@ -10390,6 +10418,11 @@ SCPS-55044:
name-sort: "えなじーえあふぉーす [Asiaばん]"
name-en: "Energy Airforce [Asia Version]"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SCPS-55045:
name: "ポイニーポイン"
name-sort: "ぽいにーぽいん"
@@ -13656,6 +13689,7 @@ SLED-53440:
name: "Area 51"
region: "PAL-Unk"
gsHWFixes:
textureInsideRT: 1 # Fixes shadows in some scenarios.
halfPixelOffset: 2 # Fixes misaligned lighting and other effects, needs Special otherwise lights flicker.
nativeScaling: 2 # Fixes lights.
SLED-53442:
@@ -17181,7 +17215,7 @@ SLES-51296:
region: "PAL-M5"
compat: 5
gameFixes:
- VIFFIFOHack
- VIFFIFOHack # TODO check what this fixes.
SLES-51298:
name: "Jimmy Neutron - Boy Genius"
region: "PAL-E"
@@ -17856,9 +17890,19 @@ SLES-51646:
name: "Energy Airforce"
region: "PAL-M4"
compat: 5
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-51647:
name: "Energy Airforce"
region: "PAL-I"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-51649:
name: "Judge Dredd - Dredd vs. Death"
region: "PAL-M4"
@@ -19362,20 +19406,26 @@ SLES-52259:
SLES-52265:
name: "Energy Airforce - Aim Strike!"
region: "PAL-E"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-52266:
name: "Energy Airforce - Aim Strike!"
region: "PAL-F"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-52267:
name: "Energy Airforce - Aim Strike!"
region: "PAL-I"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-52275:
name: "Way of the Samurai 2"
@@ -19520,6 +19570,11 @@ SLES-52309:
SLES-52310:
name: "Energy Airforce"
region: "PAL-E"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLES-52312:
name: "World Championship Rugby"
region: "PAL-E-F"
@@ -20228,6 +20283,7 @@ SLES-52570:
region: "PAL-M5"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes shadows in some scenarios.
halfPixelOffset: 2 # Fixes misaligned lighting and other effects, needs Special otherwise lights flicker.
nativeScaling: 2 # Fixes lights.
SLES-52571:
@@ -21857,6 +21913,7 @@ SLES-53075:
name: "Area 51"
region: "PAL-M5"
gsHWFixes:
textureInsideRT: 1 # Fixes shadows in some scenarios.
halfPixelOffset: 2 # Fixes misaligned lighting and other effects, needs Special otherwise lights flicker.
nativeScaling: 2 # Fixes lights.
SLES-53076:
@@ -21870,7 +21927,7 @@ SLES-53079:
name: "Ys - The Ark of Napishtim"
region: "PAL-M5"
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLES-53080:
name: "Extreme Sprint 3010"
region: "PAL-E"
@@ -28944,6 +29001,7 @@ SLES-55349:
region: "PAL-E"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -28966,6 +29024,7 @@ SLES-55350:
region: "PAL-F-G"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -28988,6 +29047,7 @@ SLES-55351:
region: "PAL-I-S"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -29011,6 +29071,7 @@ SLES-55352:
compat: 5
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -29033,6 +29094,7 @@ SLES-55353:
region: "PAL-M6"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -30310,6 +30372,11 @@ SLKA-25001:
SLKA-25002:
name: "Energy Airforce"
region: "NTSC-K"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLKA-25003:
name: "Herdy Gerdy"
region: "NTSC-K"
@@ -30492,6 +30559,8 @@ SLKA-25053:
SLKA-25054:
name: "Grand Prix Challenge"
region: "NTSC-K"
gameFixes:
- VIFFIFOHack # TODO check what this fixes.
SLKA-25055:
name: "Hitman 2 - Silent Assassin"
region: "NTSC-K"
@@ -30988,8 +31057,10 @@ SLKA-25180:
SLKA-25181:
name: "Energy Airforce Aim Strike!"
region: "NTSC-K"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLKA-25182:
name: "Hajime no Ippo2 Victorious Road"
@@ -31087,6 +31158,9 @@ SLKA-25204:
SLKA-25205:
name: "Dragon Ball Z 3"
region: "NTSC-K"
gsHWFixes:
halfPixelOffset: 4 # Aligns post effects.
nativeScaling: 2 # Fixes post processing and lighting smoothness and position.
SLKA-25206:
name: "Burnout 3 - Takedown"
region: "NTSC-K"
@@ -31300,7 +31374,7 @@ SLKA-25249:
name: "Ys - The Ark of Napishtim [with Guide Book]"
region: "NTSC-K"
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLKA-25250:
name: "GoldenEye - Rogue Agent"
region: "NTSC-K"
@@ -32190,6 +32264,7 @@ SLKA-25446:
region: "NTSC-K"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
getSkipCount: "GSC_NFSUndercover"
memcardFilters:
@@ -33055,6 +33130,7 @@ SLPM-55127:
region: "NTSC-J"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -33653,6 +33729,7 @@ SLPM-55244:
region: "NTSC-J"
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -34279,6 +34356,11 @@ SLPM-60183:
name-sort: "えなじーえあふぉーす TRIAL VERSION [たいけんばん]"
name-en: "Energy Airforce TRIAL VERSION [Trial]"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLPM-60184:
name: "GUNGRAVE [体験版]"
name-sort: "がんぐれいぶ [たいけんばん]"
@@ -35278,6 +35360,9 @@ SLPM-61111:
name-sort: "どらごんぼーるZ3 [たいけんばん]"
name-en: "Dragon Ball Z 3 [Trial]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 4 # Aligns post effects.
nativeScaling: 2 # Fixes post processing and lighting smoothness and position.
SLPM-61112:
name: "天星 ソード オブ デスティニー [体験版]"
name-sort: "てんせい そーど おぶ ですてぃにー [たいけんばん]"
@@ -40679,6 +40764,11 @@ SLPM-65177:
name-en: "Energy Airforce"
region: "NTSC-J"
compat: 5
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLPM-65178:
name: "Ferrari F355 challenge"
name-sort: "ふぇらーり F355 ちゃれんじ"
@@ -41322,7 +41412,7 @@ SLPM-65276:
name-en: "Grand Prix Challenge"
region: "NTSC-J"
gameFixes:
- VIFFIFOHack
- VIFFIFOHack # TODO check what this fixes.
SLPM-65277:
name: "DDRMAX2 Dance Dance Revolution 7th Mix"
name-sort: "だんすだんすれぼりゅーしょん まっくす2 Dance Dance Revolution 7th Mix"
@@ -41858,10 +41948,9 @@ SLPM-65374:
name-en: "Energy Airforce - Aim Strike!"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame.
mtvu: 0
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLPM-65375:
name: "真・三國無双3 & 真・三國無双3 猛将伝 [ディスク 1] [プレミアムパック]"
@@ -44451,14 +44540,14 @@ SLPM-65829:
name-en: "Ys - The Ark of Napishtim [Limited Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLPM-65830:
name: "イース ~ナピシュテムの匣~ [初回生産版]"
name-sort: "いーす6 なぴしゅてむのはこ [しょかいせいさんばん]"
name-en: "Ys - The Ark of Napishtim [Limited Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLPM-65831:
name: "ハローキティのピコピコ大作戦!"
name-sort: "はろーきてぃのぴこぴこだいさくせん!"
@@ -44490,7 +44579,7 @@ SLPM-65836:
name-en: "Ys - The Ark of Napishtim"
region: "NTSC-J"
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLPM-65837:
name: "ターミネーター3: ザ・レデンプション"
name-sort: "たーみねーたー 3: ざ れでんぷしょん"
@@ -47545,6 +47634,8 @@ SLPM-66326:
name-sort: "いーす なぴしゅてむのはこ [KONAMI The BEST]"
name-en: "Ys - The Ark of Napishtim [KONAMI The BEST]"
region: "NTSC-J"
gameFixes:
- EETimingHack # TODO check what this fixes.
SLPM-66327:
name: "ウォレスとグルミット野菜畑で大ピンチ!"
name-sort: "うぉれすとぐるみっとやさいはたけでだいぴんち!"
@@ -48415,6 +48506,7 @@ SLPM-66468:
name-en: "Area 51"
region: "NTSC-J"
gsHWFixes:
textureInsideRT: 1 # Fixes shadows in some scenarios.
halfPixelOffset: 2 # Fixes misaligned lighting and other effects, needs Special otherwise lights flicker.
nativeScaling: 2 # Fixes lights.
SLPM-66469:
@@ -50330,6 +50422,11 @@ SLPM-66774:
name-sort: "えなじーえあーふぉーす [Eternal Hits]"
name-en: "Energy Airforce [Eternal Hits]"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLPM-66775:
name: "タイトーメモリーズ 上巻 [Eternal Hits]"
name-sort: "たいとーめもりーず 01 じょうかん [Eternal Hits]"
@@ -52869,6 +52966,11 @@ SLPM-74414:
name-sort: "えなじーえあーふぉーす [PlayStation2 The Best]"
name-en: "Energy Airforce [PlayStation2 The Best]"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
SLPM-74415:
name: "忍 -Shinobi- [PlayStation2 the Best]"
name-sort: "しのび [PlayStation2 the Best]"
@@ -58206,6 +58308,9 @@ SLPS-25460:
name-sort: "どらごんぼーるZ3"
name-en: "Dragon Ball Z 3"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 4 # Aligns post effects.
nativeScaling: 2 # Fixes post processing and lighting smoothness and position.
SLPS-25461:
name: "アーマード・コア フォーミュラフロント"
name-sort: "あーまーどこあ ふぉーみゅらふろんと"
@@ -59024,6 +59129,8 @@ SLPS-25602:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 2 ぼんばーぱわふる&ゆめゆめわーるどDX"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 2 - Bomber Powerfull & Yume Yume World DX"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25603:
name: "天星 SWORDS OF DESTINY Best Collection"
name-sort: "てんせい SWORDS OF DESTINY Best Collection"
@@ -59122,6 +59229,8 @@ SLPS-25620:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 3 CRまりりん・もんろー"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 3 - CR Marilyn Monroe"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25621:
name: "かしまし ~ガールミーツガール~「初めての夏物語。」限定版"
name-sort: "かしまし がーるみーつがーる「はじめてのなつものがたり」げんていばん"
@@ -59310,6 +59419,8 @@ SLPS-25648:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 5 CRしんせいきえゔぁんげりおん せかんどいんぱくと&ぱちすろしんせいきえゔぁんげりおん"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 5 - CR Shinseiki Evangelion Second Impact & Pachisuro Shinseiki Evangelion"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25649:
name: "宇宙刑事魂"
name-sort: "うちゅうけいじたましい"
@@ -59492,6 +59603,8 @@ SLPS-25672:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 6 7Cafe けいしきめいぼんばーぱわふる2"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 6 7Cafe - Katashiki Mei Bomber Powerfull 2"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25673:
name: "ラスト・エスコート~黒蝶スペシャルナイト~"
name-sort: "らすと・えすこーと くろちょうすぺしゃるないと"
@@ -59647,6 +59760,8 @@ SLPS-25699:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 8 CRまつうらあや"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 8 CR Matsuura Aya"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25700:
name: "蒼い海のトリスティア ~ナノカ・フランカ発明工房記~ The Best Price"
name-sort: "あおいうみのとりすてぃあ なのかふらんかはつめいこうぼうき The Best Price"
@@ -59919,11 +60034,15 @@ SLPS-25745:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 1 CRしんせいきえゔぁんげりおん [すぺしゃるぷらいすばん]"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 1 - CR Shinseiki Evangelion [Special Price Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25746:
name: "必勝パチンコ★パチスロ攻略シリーズ Vol.9 CRフィーバー キャプテンハーロック"
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 9 CRふぃーばー きゃぷてんはーろっく"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol. 9 CR Fever Captain Harlock"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25747:
name: "餓狼伝 Breakblow Fist or Twist"
name-sort: "がろうでん Breakblow Fist or Twist"
@@ -60264,6 +60383,8 @@ SLPS-25806:
name-en: "Katekyoo Hitman Reborn! Dream Hyper Battle - Shinuki no Honoo to Kuroki Kioku"
region: "NTSC-J"
compat: 5
gsHWFixes:
roundSprite: 2 # Reduces font artifacts but characters still have major artifacts.
SLPS-25807:
name: "セイント・ビースト ~螺旋の章~ [限定版]"
name-sort: "せいんと びーすと らせんのしょう [げんていばん]"
@@ -60299,6 +60420,8 @@ SLPS-25813:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.11 しんせいきえゔぁんげりおん まごころをきみに"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.11 - Shinseiki Evangelion - Magokoro o, Kimi ni"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25814:
name: "新世紀GPX サイバーフォーミュラ Road To The INFINITY 4"
name-sort: "しんせいきGPX さいばーふぉーみゅら Road To The INFINITY 4"
@@ -60606,11 +60729,15 @@ SLPS-25861:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.10 CRしんせいきえゔぁんげりおん きせきのかちは [すぺしゃるぷらいすばん]"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.10 CR Neon Genesis Evangelion Kiseki no Kachi wa [Special Price Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25862:
name: "必勝パチンコ★パチスロ攻略シリーズ Vol.5 CR新世紀エヴァンゲリオンセカンドインパクト [スペシャルプライス版]"
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol. 5 CRしんせいきえゔぁんげりおん せかんどいんぱくと [すぺしゃるぷらいすばん]"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.5 - CR Neon Genesis Evangelion Sekandoinpakuto & Pachislot Neon Genesis Evangelion [Special Price Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25863:
name: "NEOGEOオンラインコレクション THE BEST 餓狼伝説 バトルアーカイブズ1"
name-sort: "ねおじおおんらいんこれくしょん THE BEST がろうでんせつ ばとるあーかいぶず1"
@@ -60646,6 +60773,8 @@ SLPS-25869:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.12 CRしんせいきえゔぁんげりおん しと ふたたび"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.12 CR Shinseiki Evangelion - Shito, Futatabi"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25871:
name: "ドラスティックキラー"
name-sort: "どらすてぃっくきらー"
@@ -60661,6 +60790,11 @@ SLPS-25874:
name-sort: "しんぷる2000しりーず Vol.123 THEおふぃすらぶじけんぼ れいじょうたんてい"
name-en: "Simple 2000 Series Vol. 123 - The Office Love Jikenbo - Reijou Tantei"
region: "NTSC-J"
SLPS-25875:
name: "xxxHolic - Shigatsu Tsuitachi no Izayoi Sowa [Best Collection]"
name-sort: "ほりっく わたぬきのいざよいそうわ [Best Collection]"
name-en: "xxxHolic - Shigatsu Tsuitachi no Izayoi Sowa [Best Collection]"
region: "NTSC-J"
SLPS-25876:
name: "新牧場物語 ピュア イノセントライフ [Best Collection]"
name-sort: "しんぼくじょうものがたり ぴゅあ いのせんとらいふ [Best Collection]"
@@ -60853,6 +60987,8 @@ SLPS-25904:
name-sort: "かてきょーひっとまんりぼーん! きんだんのやみのでるた"
name-en: "Katekyoo Hitman Reborn! Dream Hyper Battle - Kindan no Yami no Delta"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Reduces font artifacts but characters still have major artifacts.
SLPS-25905:
name: "ドラゴンボールZ インフィニットワールド"
name-sort: "どらごんぼーるZ いんふぃにっとわーるど"
@@ -60882,16 +61018,22 @@ SLPS-25909:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.13 しんせいきえヴぁんげりおん~やくそくのとき~"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.13 - Shin Seiki Evangelion - Yakusoku no Toki"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25910:
name: "家庭教師ヒットマンREBORNドリームハイパーバトル死ぬ気の炎と黒き記憶 [Best Collection]"
name-sort: "かてきょーひっとまんりぼーん! どりーむはいぱーばとる!しぬきのほのおとくろききおく [Best Collection]"
name-en: "Katekyoo Hitman Reborn! Dream Hyper Battle - Shinuki no Honoo to Kuroki Kioku [Best Collection]"
region: "NTSC-J"
gsHWFixes:
roundSprite: 2 # Reduces font artifacts but characters still have major artifacts.
SLPS-25911:
name: "必勝パチンコ★パチスロ攻略シリーズ Vol.11 新世紀エヴァンゲリオン~まごころを、君に~ [スペシャルプライス版]"
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.11 しんせいきえゔぁんげりおん まごころを、きみに [すぺしゃるぷらいすばん]"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.11 - Shinseiki Evangelion - Magokoro wo, Kimi ni [Special Price Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25912:
name: "ソウルイーター バトルレゾナンス"
name-sort: "そうるいーたー ばとるれぞなんす"
@@ -61064,11 +61206,15 @@ SLPS-25942:
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.14 しんせいきえゔぁんげりおん さいごのししゃ"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.14 - CR Shinseiki Evangelion - Saigo no Shisha"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25943:
name: "必勝パチンコ★パチスロ攻略シリーズ Vol.14 CR新世紀エヴァンゲリオン最後のシ者 [限定版]"
name-sort: "ひっしょうぱちんこぱちすろこうりゃくしりーず Vol.14 しんせいきえゔぁんげりおん さいごのししゃ [げんていばん]"
name-en: "Hisshou Pachinko Pachi-Slot Kouryaku Series Vol.14 - CR Shinseiki Evangelion - Saigo no Shisha [Limited Edition]"
region: "NTSC-J"
gameFixes:
- EETimingHack # Fixes FMV hanging.
SLPS-25944:
name: "仮面ライダー クライマックスヒーローズ"
name-sort: "かめんらいだー くらいまっくすひーろーず"
@@ -62036,6 +62182,9 @@ SLPS-73259:
name-sort: "どっとはっく G.U. Vol.1 さいたん [PlayStation2 the Best]"
name-en: ".hack//G.U. Vol.1 - Rebirth [PlayStation2 the Best]"
region: "NTSC-J"
gsHWFixes:
halfPixelOffset: 2 # Sharpens world in far distances.
roundSprite: 1 # Corrects proportions of some letters in HUD.
SLPS-73263:
name: "アルトネリコ2 世界に響く少女たちの創造詩 [PlayStation2 the Best]"
name-sort: "あるとねりこ2 せかいにひびくしょうじょたちのそうぞうし [PlayStation2 the Best]"
@@ -65100,6 +65249,7 @@ SLUS-20595:
region: "NTSC-U"
compat: 5
gsHWFixes:
textureInsideRT: 1 # Fixes shadows in some scenarios.
halfPixelOffset: 2 # Fixes misaligned lighting and other effects, needs Special otherwise lights flicker.
nativeScaling: 2 # Fixes lights.
SLUS-20596:
@@ -65275,7 +65425,7 @@ SLUS-20630:
region: "NTSC-U"
compat: 5
gameFixes:
- VIFFIFOHack
- VIFFIFOHack # TODO check what this fixes.
SLUS-20631:
name: "NFL Blitz Pro"
region: "NTSC-U"
@@ -67266,7 +67416,7 @@ SLUS-20980:
region: "NTSC-U"
compat: 5
gameFixes:
- EETimingHack
- EETimingHack # TODO check what this fixes.
SLUS-20981:
name: "Teenage Mutant Ninja Turtles 2 - Battle Nexus"
region: "NTSC-U"
@@ -70537,6 +70687,9 @@ SLUS-21480:
- "SLUS-21488"
- "SLUS-21489"
- "SLUS-21480"
gsHWFixes:
halfPixelOffset: 2 # Sharpens world in far distances.
roundSprite: 1 # Corrects proportions of some letters in HUD.
SLUS-21481:
name: "NCAA March Madness 07"
region: "NTSC-U"
@@ -72218,6 +72371,7 @@ SLUS-21801:
compat: 5
gsHWFixes:
recommendedBlendingLevel: 3 # Improves car reflections.
textureInsideRT: 1 # Fixes sun glare.
halfPixelOffset: 2 # Fixes blurriness.
bilinearUpscale: 2 # Fixes sun glare textures.
gpuTargetCLUT: 1 # Fixes sun penetration.
@@ -74106,10 +74260,9 @@ TCPS-10073:
name-en: "Energy Airforce - Aim Strike! [TAITO 2002]"
region: "NTSC-J"
speedHacks:
instantVU1: 0 # Fixes hanging while going ingame.
mtvu: 0
instantVU1: 0 # Fixes hanging while going ingame easiest test is making a replay and load the replay once or more which gives you blackscreen and 100% EE with low performance.
gsHWFixes:
recommendedBlendingLevel: 5 # Alleviates color banding.
recommendedBlendingLevel: 5 # Alleviates color banding also the cockpit and missile shadows are darker if enabled.
autoFlush: 2 # Corrects post-processing effect on jet exhausts.
TCPS-10074:
name: "スペースインベーダー アニバーサリー [筐体型コントローラ同梱セット]"

View File

@@ -1100,6 +1100,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4~,start:b8,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000104000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000c6240000045d000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -1766,6 +1767,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000dd02000003020000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,

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

@@ -64,7 +64,8 @@ set(CMAKE_SHARED_LINKER_FLAGS_DEVEL "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}
CACHE STRING "Flags used for linking shared libraries during development builds" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_DEVEL "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used for linking executables during development builds" FORCE)
set(CMAKE_MAP_IMPORTED_CONFIG_DEVEL "RelWithDebInfo" "Release" ""
# Exclude Debug from the configurations we can import from
set(CMAKE_MAP_IMPORTED_CONFIG_DEVEL "RelWithDebInfo" "Release" "MinSizeRel" "None" "NoConfig" ""
CACHE STRING "Configurations used when importing packages for development builds" FORCE)
if(CMAKE_CONFIGURATION_TYPES)
list(INSERT CMAKE_CONFIGURATION_TYPES 0 Devel)

View File

@@ -437,7 +437,7 @@ std::unique_ptr<SharedMemoryMappingArea> SharedMemoryMappingArea::Create(size_t
{
pxAssertRel(Common::IsAlignedPow2(size, __pagesize), "Size is page aligned");
mach_vm_address_t alloc;
mach_vm_address_t alloc = 0;
const kern_return_t res =
mach_vm_map(mach_task_self(), &alloc, size, 0, VM_FLAGS_ANYWHERE,
MEMORY_OBJECT_NULL, 0, false, VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_NONE);

View File

@@ -65,16 +65,17 @@ void ThreadView::openContextMenu(QPoint pos)
void ThreadView::onDoubleClick(const QModelIndex& index)
{
auto real_index = m_proxy_model->mapToSource(index);
switch (index.column())
{
case ThreadModel::ThreadColumns::ENTRY:
{
goToInMemoryView(m_model->data(index, Qt::UserRole).toUInt(), true);
goToInDisassembler(m_model->data(real_index, Qt::UserRole).toUInt(), true);
break;
}
default: // Default to PC
{
QModelIndex pc_index = m_model->index(index.row(), ThreadModel::ThreadColumns::PC);
QModelIndex pc_index = m_model->index(real_index.row(), ThreadModel::ThreadColumns::PC);
goToInDisassembler(m_model->data(pc_index, Qt::UserRole).toUInt(), true);
break;
}

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

@@ -1455,7 +1455,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode, bool transition_t
}
isSeeking = true;
}
else if(!drive_speed_change_cycles)
else if (!drive_speed_change_cycles)
{
CDVD_LOG("CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta);

View File

@@ -222,7 +222,7 @@ bool IOCtlSrc::ReadDVDInfo()
{
Console.Warning("IOCTL_DVD_READ_STRUCTURE not supported");
}
else if(GetLastError() != ERROR_UNRECOGNIZED_MEDIA) // ERROR_UNRECOGNIZED_MEDIA means probably a CD or no disc
else if (GetLastError() != ERROR_UNRECOGNIZED_MEDIA) // ERROR_UNRECOGNIZED_MEDIA means probably a CD or no disc
{
Console.Warning("IOCTL Unknown Error %d", GetLastError());
}

View File

@@ -33,7 +33,7 @@ struct BreakPoint
bool temporary = false;
bool stepping = false;
bool hasCond;
bool hasCond = false;
BreakPointCond cond;
BreakPointCpu cpu;

View File

@@ -236,7 +236,7 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
cpuClearInt( 10 );
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
}
else if(channel == 2)
else if (channel == 2)
{
cpuClearInt( 11 );
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
@@ -274,7 +274,7 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
{
func();
}
else if(reg.chcr.STR)
else if (reg.chcr.STR)
{
//DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem));
QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted

View File

@@ -20,7 +20,11 @@ There are a number of ways to help the project, whether it be bug reporting, gam
* Want to make changes to emulator code? [Check out the issue tracker](https://github.com/PCSX2/pcsx2/issues), or [fork the PCSX2 repository and work on your own ideas](https://github.com/PCSX2/pcsx2).
* Want to patch games? [Check out the cheats and patches forum thread for inspiration](https://forums.pcsx2.net/Thread-Post-your-PCSX2-cheats-patches-here). There are other threads to find as well, [such as those dedicated to 60 FPS patches](https://forums.pcsx2.net/Thread-60-fps-codes) or [widescreen patches](https://forums.pcsx2.net/Thread-PCSX2-Widescreen-Game-Patches).
<<<<<<< HEAD
* Want to report bugs you have discovered in your games? Head over to [the Bug Reporting section of the PCSX2 forums](https://forums.pcsx2.net/Forum-Bug-reporting), to [the PCSX2 Discord](https://pcsx2.net/discord), or to [the GitHub issues section](https://github.com/PCSX2/pcsx2/issues).
=======
* Want to report bugs you have discovered in your games? [Head over to the Bug Reporting section of the PCSX2 forums](https://forums.pcsx2.net/Forum-Bug-reporting). Also check out our [Issue reporting guide](https://pcsx2.net/docs/troubleshooting/identify) for info on how to better report to us issues.
>>>>>>> 091a4ee5a (docs: update in order to redirect from the GH wiki to our website)
* Want to update us on the compatibility of your games? [Take a look at the Public Compatibility List on the PCSX2 forums](https://forums.pcsx2.net/Forum-Public-compatibility-list)
* Want to improve the PCSX2 wiki? [Here is how to contribute](https://wiki.pcsx2.net/How_to_contribute)
@@ -120,9 +124,7 @@ If you are using a disc:
Fast Boot, enabled by default, will directly mount and launch the game without first launching the PS2 BIOS. You may disable this in Settings > BIOS > Fast Boot if you wish to see the BIOS startup animation or if Fast Boot is causing an issue.
### Question 18: How do I build the PCSX2 source code?
* [Windows build guide](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
* [Linux build guide](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
* [macOS build guide](https://github.com/PCSX2/pcsx2/wiki/11-Building-on-MacOS)
Have a nice [building guide](https://pcsx2.net/docs/advanced/building) :) .
### Question 19: When will the next version be released?
It will be released when it is ready. Please don't waste your time and ours asking when.

View File

@@ -339,7 +339,7 @@ void GSClut::Read(const GIFRegTEX0& TEX0)
break;
}
}
else if(TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S)
else if (TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S)
{
switch(TEX0.PSM)
{
@@ -462,7 +462,8 @@ void GSClut::GetAlphaMinMax32(int& amin_out, int& amax_out)
{
// call only after Read32
pxAssert(!m_read.dirty);
if (m_read.dirty)
GL_INS("GSClut: GetAlphaMinMax32 m_read.dirty");
if (m_read.adirty)
{

View File

@@ -2260,7 +2260,7 @@ void GSState::Move()
vm[doff] = (vm[doff] & 0xff000000) | (vm[soff] & 0x00ffffff);
});
}
else // if(spsm.trbpp == 16)
else // if (spsm.trbpp == 16)
{
u16* vm = m_mem.vm16();
copy(dpo.assertSizesMatch(GSLocalMemory::swizzle16), spo.assertSizesMatch(GSLocalMemory::swizzle16), [vm](u32 doff, u32 soff)

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

@@ -1236,36 +1236,18 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
D3D11_BOX box = {(UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U};
D3D11_BOX box = {static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0U, static_cast<UINT>(r.right), static_cast<UINT>(r.bottom), 1U};
// DX api isn't happy if we pass a box for depth copy
// It complains that depth/multisample must be a full copy
// and asks us to use a NULL for the box
// DX11 doesn't support partial depth copy so we need to
// either pass a nullptr D3D11_BOX for a full depth copy or use CopyResource instead.
// Alternatively use shader copy StretchRect, or full depth copy with
// adjusting the scissor and UVs in the shader.
const bool depth = (sTex->GetType() == GSTexture::Type::DepthStencil);
auto pBox = depth ? nullptr : &box;
const u32 x = depth ? 0 : destX;
const u32 y = depth ? 0 : destY;
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, destX, destY, 0, *(GSTexture11*)sTex, 0, pBox);
}
void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect)
{
pxAssertMsg(src->GetType() == GSTexture::Type::DepthStencil || src->GetType() == GSTexture::Type::RenderTarget, "Source is RT or DS.");
CommitClear(src);
const int w = src->GetWidth();
const int h = src->GetHeight();
if (src->GetType() == GSTexture::Type::DepthStencil)
{
// DX11 requires that you copy the entire depth buffer.
*dest = CreateDepthStencil(w, h, src->GetFormat(), false);
CopyRect(src, *dest, GSVector4i(0, 0, w, h), 0, 0);
}
else
{
*dest = CreateRenderTarget(w, h, src->GetFormat(), false);
CopyRect(src, *dest, rect, rect.left, rect.top);
}
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, x, y, 0, *(GSTexture11*)sTex, 0, pBox);
}
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
@@ -2495,20 +2477,9 @@ D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr()
return (D3D_SHADER_MACRO*)mout.data();
}
/// Checks that we weren't sent things we declared we don't support
/// Clears things we don't support that can be quietly disabled
static void preprocessSel(GSDevice11::PSSelector& sel)
{
pxAssert(sel.write_rg == 0); // Not supported, shouldn't be sent
}
void GSDevice11::RenderHW(GSHWDrawConfig& config)
{
pxAssert(!config.require_full_barrier); // We always specify no support so it shouldn't request this
preprocessSel(config.ps);
GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
const GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
GSTexture* colclip_rt = g_gs_device->GetColorClipTexture();
if (colclip_rt)
@@ -2560,7 +2531,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
}
else if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
{
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy();
const GSVector4 dst = src * 2.0f - 1.0f;
@@ -2630,20 +2602,33 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
PSSetShaderResource(1, config.pal);
}
GSTexture* rt_copy = nullptr;
if (config.require_one_barrier || (config.tex && config.tex == config.rt)) // Used as "bind rt" flag when texture barrier is unsupported.
GSTexture* draw_rt_clone = nullptr;
if (config.require_one_barrier || (config.tex && config.tex == config.rt))
{
// Bind the RT.This way special effect can use it.
// Do not always bind the rt when it's not needed,
// only bind it when effects use it such as fbmask emulation currently
// because we copy the frame buffer and it is quite slow.
CloneTexture(colclip_rt ? colclip_rt : config.rt, &rt_copy, config.drawarea);
if (rt_copy)
// Requires a copy of the RT.
// Used as "bind rt" flag when texture barrier is unsupported for tex is fb.
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true);
if (draw_rt_clone)
{
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
if (config.require_one_barrier)
PSSetShaderResource(2, rt_copy);
PSSetShaderResource(2, draw_rt_clone);
if (config.tex && config.tex == config.rt)
PSSetShaderResource(0, rt_copy);
PSSetShaderResource(0, draw_rt_clone);
}
}
GSTexture* draw_ds_clone = nullptr;
if (config.tex && config.tex == config.ds)
{
// DX requires a copy when sampling the depth buffer.
draw_ds_clone = CreateDepthStencil(rtsize.x, rtsize.y, config.ds->GetFormat(), false);
if (draw_ds_clone)
{
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
PSSetShaderResource(0, draw_ds_clone);
}
}
@@ -2681,7 +2666,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
if (config.alpha_second_pass.enable)
{
preprocessSel(config.alpha_second_pass.ps);
if (config.cb_ps.FogColor_AREF.a != config.alpha_second_pass.ps_aref)
{
config.cb_ps.FogColor_AREF.a = config.alpha_second_pass.ps_aref;
@@ -2697,8 +2681,12 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
DrawIndexedPrimitive();
}
if (rt_copy)
Recycle(rt_copy);
if (draw_rt_clone)
Recycle(draw_rt_clone);
if (draw_ds_clone)
Recycle(draw_ds_clone);
if (primid_tex)
Recycle(primid_tex);

View File

@@ -291,7 +291,6 @@ public:
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
void CommitClear(GSTexture* t);
void CloneTexture(GSTexture* src, GSTexture** dest, const GSVector4i& rect);
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;

View File

@@ -1087,7 +1087,14 @@ GSDevice::PresentResult GSDevice12::BeginPresent(bool frame_skip)
return PresentResult::DeviceLost;
if (frame_skip || !m_swap_chain)
{
if (!m_swap_chain)
{
ExecuteCommandList(WaitType::None);
InvalidateCachedState();
}
return PresentResult::FrameSkipped;
}
// Check if we lost exclusive fullscreen. If so, notify the host, so it can switch to windowed mode.
// This might get called repeatedly if it takes a while to switch back, that's the host's problem.
@@ -3821,6 +3828,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
GSTexture12* draw_rt = static_cast<GSTexture12*>(config.rt);
GSTexture12* draw_ds = static_cast<GSTexture12*>(config.ds);
GSTexture12* draw_rt_clone = nullptr;
GSTexture12* draw_ds_clone = nullptr;
// Align the render area to 128x128, hopefully avoiding render pass restarts for small render area changes (e.g. Ratchet and Clank).
const GSVector2i rtsize(config.rt ? config.rt->GetSize() : config.ds->GetSize());
@@ -3876,7 +3884,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// bind textures before checking the render pass, in case we need to transition them
if (config.tex)
{
PSSetShaderResource(0, config.tex, config.tex != config.rt);
PSSetShaderResource(0, config.tex, config.tex != config.rt && config.tex != config.ds);
PSSetSampler(config.sampler);
}
if (config.pal)
@@ -3900,15 +3908,16 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
}
}
if (config.require_one_barrier || (config.tex && config.tex == config.rt)) // Used as "bind rt" flag when texture barrier is unsupported.
if (config.require_one_barrier || (config.tex && config.tex == config.rt))
{
// requires a copy of the RT
// Requires a copy of the RT.
// Used as "bind rt" flag when texture barrier is unsupported for tex is fb.
draw_rt_clone = static_cast<GSTexture12*>(CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true));
if (draw_rt_clone)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
GL_PUSH("Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
draw_rt_clone->SetState(GSTexture::State::Invalidated);
@@ -3920,6 +3929,23 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
}
}
if (config.tex && config.tex == config.ds)
{
// DX requires a copy when sampling the depth buffer.
draw_ds_clone = static_cast<GSTexture12*>(CreateDepthStencil(rtsize.x, rtsize.y, config.ds->GetFormat(), false));
if (draw_ds_clone)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
draw_ds_clone->SetState(GSTexture::State::Invalidated);
CopyRect(config.ds, draw_ds_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
PSSetShaderResource(0, draw_ds_clone, true);
}
}
// Switch to colclip target for colclip hw rendering
if (pipe.ps.colclip_hw)
{
@@ -4066,6 +4092,9 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
if (draw_rt_clone)
Recycle(draw_rt_clone);
if (draw_ds_clone)
Recycle(draw_ds_clone);
if (date_image)
Recycle(date_image);

View File

@@ -1037,7 +1037,7 @@ float GSRendererHW::GetTextureScaleFactor()
return GetUpscaleMultiplier();
}
GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex, const bool is_shuffle)
{
// Don't blindly expand out to the scissor size if we're not drawing to it.
// e.g. Burnout 3, God of War II, etc.
@@ -1088,10 +1088,9 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
// Early detection of texture shuffles. These double the input height because they're interpreting 64x32 C32 pages as 64x64 C16.
// Why? Well, we don't want to be doubling the heights of targets, but also we don't want to align C32 targets to 64 instead of 32.
// Yumeria's text breaks, and GOW goes to 512x448 instead of 512x416 if we don't.
const bool possible_texture_shuffle =
(tex && m_vt.m_primclass == GS_SPRITE_CLASS && frame_psm.bpp == 16 &&
const bool possible_texture_shuffle = tex && m_vt.m_primclass == GS_SPRITE_CLASS && frame_psm.bpp == 16 &&
GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 &&
(tex->m_32_bits_fmt ||
(is_shuffle || (tex->m_32_bits_fmt ||
(m_cached_ctx.TEX0.TBP0 != m_cached_ctx.FRAME.Block() && IsOpaque() && !(m_context->TEX1.MMIN & 1) &&
m_cached_ctx.FRAME.FBMSK && g_texture_cache->Has32BitTarget(m_cached_ctx.FRAME.Block()))));
if (possible_texture_shuffle)
@@ -1128,9 +1127,9 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
return GSVector2i(width, height);
}
GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex, const bool can_expand)
GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex, const bool can_expand, const bool is_shuffle)
{
const GSVector2i valid_size = GetValidSize(tex);
const GSVector2i valid_size = GetValidSize(tex, is_shuffle);
return g_texture_cache->GetTargetSize(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, valid_size.x, valid_size.y, can_expand);
}
@@ -2860,7 +2859,8 @@ void GSRendererHW::Draw()
(m_vt.m_primclass == GS_SPRITE_CLASS || (m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_index.tail % 6) == 0 && TrianglesAreQuads(true) && m_index.tail > 6)))
{
// Tail check is to make sure we have enough strips to go all the way across the page, or if it's using a region clamp could be used to draw strips.
if (GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 && (m_index.tail >= (m_cached_ctx.TEX0.TBW * 2) || m_cached_ctx.CLAMP.WMS > CLAMP_CLAMP || m_cached_ctx.CLAMP.WMT > CLAMP_CLAMP))
if (GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 &&
(m_index.tail >= (m_cached_ctx.TEX0.TBW * 2) || m_cached_ctx.TEX0.TBP0 == m_cached_ctx.FRAME.Block() || m_cached_ctx.CLAMP.WMS > CLAMP_CLAMP || m_cached_ctx.CLAMP.WMT > CLAMP_CLAMP))
{
const GSVertex* v = &m_vertex.buff[0];
@@ -2884,21 +2884,45 @@ void GSRendererHW::Draw()
}
// It's possible it's writing to an old 32bit target, but is actually just a 16bit copy, so let's make sure it's actually using a mask.
if (!shuffle_target && m_cached_ctx.FRAME.FBMSK)
if (!shuffle_target)
{
// FBW is going to be wrong for channel shuffling into a new target, so take it from the source.
FRAME_TEX0.U64 = 0;
FRAME_TEX0.TBP0 = m_cached_ctx.FRAME.Block();
FRAME_TEX0.TBW = m_cached_ctx.FRAME.FBW;
FRAME_TEX0.PSM = m_cached_ctx.FRAME.PSM;
bool shuffle_channel_reads = !m_cached_ctx.FRAME.FBMSK;
const u32 increment = (m_vt.m_primclass == GS_TRIANGLE_CLASS) ? 3 : 2;
const GSVertex* v = &m_vertex.buff[0];
GSTextureCache::Target* tgt = g_texture_cache->LookupTarget(FRAME_TEX0, GSVector2i(m_vt.m_max.p.x, m_vt.m_max.p.y), GetTextureScaleFactor(), GSTextureCache::RenderTarget, false,
fm, false, false, false, false, GSVector4i::zero(), true);
if (shuffle_channel_reads)
{
for (u32 i = 0; i < m_index.tail; i += increment)
{
const int first_u = (PRIM->FST ? v[i].U : static_cast<int>(v[i].ST.S / v[(increment == 2) ? i + 1 : i].RGBAQ.Q)) >> 4;
const int second_u = (PRIM->FST ? v[i + 1].U : static_cast<int>(v[i + 1].ST.S / v[i + 1].RGBAQ.Q)) >> 4;
const int vector_width = std::abs(v[i + 1].XYZ.X - v[i].XYZ.X) / 16;
const int tex_width = std::abs(second_u - first_u);
// & 7 just a quicker way of doing % 8
if ((vector_width & 7) != 0 || (tex_width & 7) != 0 || tex_width != vector_width)
{
shuffle_channel_reads = false;
break;
}
}
}
if (m_cached_ctx.FRAME.FBMSK || shuffle_channel_reads)
{
// FBW is going to be wrong for channel shuffling into a new target, so take it from the source.
FRAME_TEX0.U64 = 0;
FRAME_TEX0.TBP0 = m_cached_ctx.FRAME.Block();
FRAME_TEX0.TBW = m_cached_ctx.FRAME.FBW;
FRAME_TEX0.PSM = m_cached_ctx.FRAME.PSM;
if (tgt)
shuffle_target = tgt->m_32_bits_fmt;
GSTextureCache::Target* tgt = g_texture_cache->FindOverlappingTarget(FRAME_TEX0.TBP0, GSLocalMemory::GetEndBlockAddress(FRAME_TEX0.TBP0, FRAME_TEX0.TBW, FRAME_TEX0.PSM, m_r));
tgt = nullptr;
if (tgt)
shuffle_target = tgt->m_32_bits_fmt;
else
shuffle_target = shuffle_channel_reads;
tgt = nullptr;
}
}
}
@@ -2920,9 +2944,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]]
{
@@ -2942,7 +2966,13 @@ void GSRendererHW::Draw()
if (possible_shuffle && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp != 16)
possible_shuffle &= draw_uses_target;
possible_shuffle &= src && (src->m_from_target != nullptr || (m_skip && possible_shuffle));
const bool shuffle_source = possible_shuffle && src && ((src->m_from_target != nullptr && GSLocalMemory::m_psm[src->m_from_target->m_TEX0.PSM].bpp != 16) || m_skip);
if (!shuffle_source && possible_shuffle)
{
const bool is_16bit_copy = m_cached_ctx.TEX0.TBP0 != m_cached_ctx.FRAME.Block() && shuffle_target && IsOpaque() && !(context->TEX1.MMIN & 1) && !src->m_32_bits_fmt && m_cached_ctx.FRAME.FBMSK;
possible_shuffle &= is_16bit_copy || (m_cached_ctx.TEX0.TBP0 == m_cached_ctx.FRAME.Block() && shuffle_target);
}
// 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.
@@ -2988,7 +3018,7 @@ void GSRendererHW::Draw()
const bool can_expand = !(m_cached_ctx.ZBUF.ZMSK && output_black);
// Estimate size based on the scissor rectangle and height cache.
GSVector2i t_size = GetTargetSize(src, can_expand);
GSVector2i t_size = GetTargetSize(src, can_expand, possible_shuffle);
const GSVector4i t_size_rect = GSVector4i::loadh(t_size);
// Ensure draw rect is clamped to framebuffer size. Necessary for updating valid area.
@@ -3077,7 +3107,7 @@ void GSRendererHW::Draw()
if (!ds && m_cached_ctx.FRAME.FBP != m_cached_ctx.ZBUF.ZBP)
{
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src, possible_shuffle), target_scale, GSTextureCache::DepthStencil,
true, 0, false, force_preload, preserve_depth, m_r, src);
if (!ds) [[unlikely]]
{
@@ -3212,7 +3242,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;
}
@@ -3228,7 +3258,7 @@ void GSRendererHW::Draw()
return;
}
rt = g_texture_cache->CreateTarget(FRAME_TEX0, t_size, GetValidSize(src), (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && scale_draw < 0 && is_possible_mem_clear != ClearType::NormalClear) ? src->m_from_target->GetScale() : target_scale,
rt = g_texture_cache->CreateTarget(FRAME_TEX0, t_size, GetValidSize(src, possible_shuffle), (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && scale_draw < 0 && is_possible_mem_clear != ClearType::NormalClear) ? src->m_from_target->GetScale() : target_scale,
GSTextureCache::RenderTarget, true, fm, false, force_preload, preserve_rt_color || possible_shuffle, lookup_rect, src);
if (!rt) [[unlikely]]
@@ -3242,6 +3272,49 @@ void GSRendererHW::Draw()
{
rt->UpdateValidity(GSVector4i::loadh(GSVector2i(GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x, GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y)), true);
}
if (src && !src->m_from_target && GSLocalMemory::m_psm[src->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[m_context->FRAME.PSM].bpp &&
(GSUtil::GetChannelMask(src->m_TEX0.PSM) & GSUtil::GetChannelMask(m_context->FRAME.PSM)) != 0)
{
const u32 draw_end = GSLocalMemory::GetEndBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r) + 1;
const u32 draw_start = GSLocalMemory::GetStartBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r);
if (draw_start <= src->m_TEX0.TBP0 && draw_end > src->m_TEX0.TBP0)
{
g_texture_cache->ReplaceSourceTexture(src, rt->GetTexture(), rt->GetScale(), rt->GetUnscaledSize(), nullptr, true);
src->m_from_target = rt;
src->m_from_target_TEX0 = rt->m_TEX0;
src->m_target_direct = true;
src->m_shared_texture = true;
src->m_target = true;
src->m_texture = rt->m_texture;
src->m_32_bits_fmt = rt->m_32_bits_fmt;
src->m_valid_rect = rt->m_valid;
src->m_alpha_minmax.first = rt->m_alpha_min;
src->m_alpha_minmax.second = rt->m_alpha_max;
const int target_width = std::max(FRAME_TEX0.TBW, 1U);
const int page_offset = (src->m_TEX0.TBP0 - rt->m_TEX0.TBP0) >> 5;
const int vertical_page_offset = page_offset / target_width;
const int horizontal_page_offset = page_offset - (vertical_page_offset * target_width);
if (vertical_page_offset)
{
const int height = std::max(rt->m_valid.w, possible_shuffle ? (m_r.w / 2) : m_r.w);
src->m_region.SetY(vertical_page_offset * GSLocalMemory::m_psm[rt->m_TEX0.PSM].pgs.y, height);
}
if (horizontal_page_offset)
src->m_region.SetX(horizontal_page_offset * GSLocalMemory::m_psm[rt->m_TEX0.PSM].pgs.x, target_width * GSLocalMemory::m_psm[rt->m_TEX0.PSM].pgs.x);
if (rt->m_dirty.empty())
{
RGBAMask rgba_mask;
rgba_mask._u32 = GSUtil::GetChannelMask(rt->m_TEX0.PSM);
g_texture_cache->AddDirtyRectTarget(rt, m_r, FRAME_TEX0.PSM, FRAME_TEX0.TBW, rgba_mask, GSLocalMemory::m_psm[FRAME_TEX0.PSM].trbpp >= 16);
}
}
}
}
else if (rt->m_TEX0.TBP0 != m_cached_ctx.FRAME.Block())
{
@@ -3348,85 +3421,134 @@ void GSRendererHW::Draw()
t_size.x = rt->m_unscaled_size.x - horizontal_offset;
t_size.y = rt->m_unscaled_size.y - vertical_offset;
}
// Z isn't offset but RT is, so we need a temp Z to align it, hopefully nothing will ever write to the Z too, right??
if (ds && vertical_offset && (m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) != (m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0))
// Don't resize if the BPP don't match.
GSVector2i new_size = GetValidSize(src, possible_shuffle);
if (new_size.x > rt->m_unscaled_size.x || new_size.y > rt->m_unscaled_size.y)
{
const u32 new_width = std::max(new_size.x, rt->m_unscaled_size.x);
const u32 new_height = std::max(new_size.y, rt->m_unscaled_size.y);
//DevCon.Warning("HW: Resizing texture %d x %d draw %d", rt->m_unscaled_size.x, new_height, s_n);
rt->ResizeTexture(new_width, new_height);
}
else if ((IsPageCopy() || is_possible_mem_clear) && m_r.width() <= frame_psm.pgs.x && m_r.height() <= frame_psm.pgs.y)
{
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
GSVector4i update_valid = GSVector4i::loadh(GSVector2i(horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x, GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y + vertical_offset));
rt->UpdateValidity(update_valid, true);
if (is_possible_mem_clear)
{
m_using_temp_z = true;
const int z_vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(rt->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
if (g_texture_cache->GetTemporaryZ() != nullptr)
if ((horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x) >= static_cast<int>(rt->m_TEX0.TBW * 64) && next_ctx.FRAME.Block() == (m_cached_ctx.FRAME.Block() + 0x20))
{
GSTextureCache::TempZAddress z_address_info = g_texture_cache->GetTemporaryZInfo();
if (ds->m_TEX0.TBP0 != z_address_info.ZBP || z_address_info.offset != static_cast<u32>(vertical_offset - z_vertical_offset))
g_texture_cache->InvalidateTemporaryZ();
else if (!m_r.rintersect(z_address_info.rect_since + GSVector4i(0, z_address_info.offset, 0, z_address_info.offset)).rempty() && m_cached_ctx.TEST.ZTST > ZTST_ALWAYS)
{
GL_CACHE("HW: RT in RT Updating Z copy on draw %d z_offset %d", s_n, z_address_info.offset);
GSVector4i dRect = GSVector4i(z_address_info.rect_since.x * ds->m_scale, (z_address_info.offset + z_address_info.rect_since.y) * ds->m_scale, (z_address_info.rect_since.z + (1.0f / ds->m_scale)) * ds->m_scale, (z_address_info.offset + z_address_info.rect_since.w + (1.0f / ds->m_scale)) * ds->m_scale);
g_gs_device->StretchRect(ds->m_texture, GSVector4(z_address_info.rect_since.x / static_cast<float>(ds->m_unscaled_size.x), z_address_info.rect_since.y / static_cast<float>(ds->m_unscaled_size.y), (z_address_info.rect_since.z + (1.0f / ds->m_scale)) / static_cast<float>(ds->m_unscaled_size.x), (z_address_info.rect_since.w + (1.0f / ds->m_scale)) / static_cast<float>(ds->m_unscaled_size.y)), g_texture_cache->GetTemporaryZ(), GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
z_address_info.rect_since = GSVector4i::zero();
g_texture_cache->SetTemporaryZInfo(z_address_info);
}
}
if (g_texture_cache->GetTemporaryZ() == nullptr)
{
m_temp_z_full_copy = false;
const u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y);
const GSVector4i dRect = GSVector4i(0, vertical_offset * ds->m_scale, ds->m_unscaled_size.x * ds->m_scale, (vertical_offset + ds->m_unscaled_size.y - z_vertical_offset) * ds->m_scale);
const int new_height = std::max(static_cast<int>(vertical_size * ds->m_scale), dRect.w);
if (GSTexture* tex = g_gs_device->CreateDepthStencil(ds->m_unscaled_size.x * ds->m_scale, new_height, GSTexture::Format::DepthStencil, true))
{
GL_CACHE("HW: RT in RT Z copy on draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset);
g_gs_device->StretchRect(ds->m_texture, GSVector4(0.0f, z_vertical_offset / static_cast<float>(ds->m_unscaled_size.y), 1.0f, (ds->m_unscaled_size.y - z_vertical_offset) / static_cast<float>(ds->m_unscaled_size.y)), tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
g_texture_cache->SetTemporaryZ(tex);
g_texture_cache->SetTemporaryZInfo(ds->m_TEX0.TBP0, vertical_offset - z_vertical_offset);
t_size.y = std::max(new_height, t_size.y);
}
else
{
DevCon.Warning("HW: Temporary depth buffer creation failed.");
m_using_temp_z = false;
}
update_valid.x = 0;
update_valid.z = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x;
update_valid.y += GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y;
update_valid.w += GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y;
rt->UpdateValidity(update_valid, true);
}
}
}
// Don't resize if the BPP don't match.
if (frame_psm.bpp == GSLocalMemory::m_psm[rt->m_TEX0.PSM].bpp)
}
// Z or RT are offset from each other, so we need a temp Z to align it
if (ds && rt && (m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) != (m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0))
{
m_using_temp_z = true;
const int page_offset = (static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32);
const int z_vertical_offset = (page_offset / std::max(ds->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
const int z_horizontal_offset = (page_offset % std::max(ds->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x;
if (g_texture_cache->GetTemporaryZ() != nullptr)
{
if (m_r.w > rt->m_unscaled_size.y || m_r.z > rt->m_unscaled_size.x)
GSTextureCache::TempZAddress z_address_info = g_texture_cache->GetTemporaryZInfo();
const int old_z_vertical_offset = (page_offset / std::max(ds->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
const int old_z_horizontal_offset = (page_offset % std::max(ds->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x;
if (ds->m_TEX0.TBP0 != z_address_info.ZBP || z_address_info.offset != page_offset)
g_texture_cache->InvalidateTemporaryZ();
else if (!m_r.rintersect(z_address_info.rect_since).rempty() && m_cached_ctx.TEST.ZTST > ZTST_ALWAYS)
{
const u32 new_height = std::max(m_r.w, rt->m_unscaled_size.y);
const u32 new_width = std::max(m_r.z, rt->m_unscaled_size.x);
GL_CACHE("HW: RT in RT Updating Z copy on draw %d z_offset %d", s_n, z_address_info.offset);
GSVector4 sRect = GSVector4(z_address_info.rect_since.x / static_cast<float>(ds->m_unscaled_size.x), z_address_info.rect_since.y / static_cast<float>(ds->m_unscaled_size.y), (z_address_info.rect_since.z + (1.0f / ds->m_scale)) / static_cast<float>(ds->m_unscaled_size.x), (z_address_info.rect_since.w + (1.0f / ds->m_scale)) / static_cast<float>(ds->m_unscaled_size.y));
GSVector4i dRect = GSVector4i((old_z_horizontal_offset + z_address_info.rect_since.x) * ds->m_scale, (old_z_vertical_offset + z_address_info.rect_since.y) * ds->m_scale, (old_z_horizontal_offset + z_address_info.rect_since.z + (1.0f / ds->m_scale)) * ds->m_scale, (old_z_vertical_offset + z_address_info.rect_since.w + (1.0f / ds->m_scale)) * ds->m_scale);
//DevCon.Warning("HW: Resizing texture %d x %d draw %d", rt->m_unscaled_size.x, new_height, s_n);
rt->ResizeTexture(new_width, new_height);
sRect = sRect.min(GSVector4(1.0f));
dRect = dRect.min_u32(GSVector4i(ds->m_unscaled_size.x * ds->m_scale, ds->m_unscaled_size.y * ds->m_scale).xyxy());
const bool frame_masked = ((m_cached_ctx.FRAME.FBMSK & frame_psm.fmsk) == frame_psm.fmsk) || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ATST_NEVER && !(m_cached_ctx.TEST.AFAIL & AFAIL_FB_ONLY));
rt->UpdateValidity(m_r, !frame_masked);
rt->UpdateDrawn(m_r, !frame_masked);
g_gs_device->StretchRect(ds->m_texture, sRect, g_texture_cache->GetTemporaryZ(), GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
z_address_info.rect_since = GSVector4i::zero();
g_texture_cache->SetTemporaryZInfo(z_address_info);
}
else if ((IsPageCopy() || is_possible_mem_clear) && m_r.width() <= frame_psm.pgs.x && m_r.height() <= frame_psm.pgs.y)
}
if (g_texture_cache->GetTemporaryZ() == nullptr)
{
m_temp_z_full_copy = false;
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
const int rt_page_offset = (static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) / 32);
const int vertical_page_offset = (rt_page_offset / std::max(static_cast<int>(rt->m_TEX0.TBW), 1));
const int vertical_offset = vertical_page_offset * frame_psm.pgs.y;
const int horizontal_offset = (rt_page_offset - (vertical_page_offset * std::max(static_cast<int>(rt->m_TEX0.TBW), 1))) * frame_psm.pgs.x;
const u32 horizontal_size = std::max(rt->m_unscaled_size.x, ds->m_unscaled_size.x);
const u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y);
GSVector4i dRect = GSVector4i(horizontal_offset * ds->m_scale, vertical_offset * ds->m_scale, ds->m_unscaled_size.x * ds->m_scale, ds->m_unscaled_size.y * ds->m_scale);
const int new_height = std::max(static_cast<int>(vertical_size * ds->m_scale), dRect.w);
const int new_width = std::max(static_cast<int>(horizontal_size * ds->m_scale), dRect.z);
const int height_diff = new_height - (ds->m_unscaled_size.y * ds->m_scale);
const int width_diff = new_width - (ds->m_unscaled_size.x * ds->m_scale);
if (GSTexture* tex = g_gs_device->CreateDepthStencil(new_width, new_height, GSTexture::Format::DepthStencil, true))
{
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
GSVector4i update_valid = GSVector4i::loadh(GSVector2i(horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x, GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y + vertical_offset));
rt->UpdateValidity(update_valid, true);
if (is_possible_mem_clear)
GSVector4 sRect = GSVector4(static_cast<float>(z_horizontal_offset) / static_cast<float>(ds->m_unscaled_size.x), static_cast<float>(z_vertical_offset) / static_cast<float>(ds->m_unscaled_size.y), 1.0f - (static_cast<float>(horizontal_offset - z_horizontal_offset) / static_cast<float>(ds->m_unscaled_size.x)), 1.0f - (static_cast<float>(vertical_offset - z_vertical_offset) / static_cast<float>(ds->m_unscaled_size.y)));
const bool restricted_copy = !(((next_ctx.ZBUF.ZBP == m_context->ZBUF.ZBP && next_ctx.FRAME.FBP == m_context->FRAME.FBP)) && !(IsPossibleChannelShuffle() && !IsPageCopy()));
if (!restricted_copy)
{
if ((horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x) >= static_cast<int>(rt->m_TEX0.TBW * 64) && next_ctx.FRAME.Block() == (m_cached_ctx.FRAME.Block() + 0x20))
if (height_diff)
{
update_valid.x = 0;
update_valid.z = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x;
update_valid.y += GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y;
update_valid.w += GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y;
rt->UpdateValidity(update_valid, true);
const int adjust = std::min(height_diff, (vertical_offset - z_vertical_offset));
sRect.w += static_cast<float>(adjust) / static_cast<float>(ds->m_unscaled_size.y);
dRect.w += adjust;
}
if (width_diff)
{
const int adjust = std::min(width_diff, (horizontal_offset - z_horizontal_offset));
sRect.z += static_cast<float>(adjust) / static_cast<float>(ds->m_unscaled_size.x);
dRect.z += adjust;
}
}
else
{
// m_r already has horizontal_offset (rt offset) applied)
dRect = GSVector4i(m_r.x * ds->m_scale, m_r.y * ds->m_scale, ((1 + m_r.z) * ds->m_scale), ((1 + m_r.w) * ds->m_scale));
sRect = GSVector4(static_cast<float>((m_r.x - horizontal_offset) + z_horizontal_offset) / static_cast<float>(ds->m_unscaled_size.x), static_cast<float>((m_r.y - vertical_offset) + z_vertical_offset) / static_cast<float>(ds->m_unscaled_size.y), (static_cast<float>((m_r.z - horizontal_offset) + z_horizontal_offset) + 1.0f) / static_cast<float>(ds->m_unscaled_size.x), (static_cast<float>((m_r.w - vertical_offset) + z_vertical_offset) + 1.0f) / static_cast<float>(ds->m_unscaled_size.y));
}
// No point in copying more width than the width of the draw, it's going to be wasted (could still be tall, though).
sRect.z = std::min(sRect.z, sRect.x + ((1.0f * ds->m_scale) + (static_cast<float>(m_cached_ctx.FRAME.FBW * 64)) / static_cast<float>(ds->m_unscaled_size.x)));
dRect.z = std::min(dRect.z, dRect.x + static_cast<int>(1 * ds->m_scale) + static_cast<int>(static_cast<float>(m_cached_ctx.FRAME.FBW * 64) * ds->m_scale));
GL_CACHE("HW: RT in RT Z copy on draw %d z_vert_offset %d", s_n, page_offset);
g_gs_device->StretchRect(ds->m_texture, sRect, tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
g_texture_cache->SetTemporaryZ(tex);
g_texture_cache->SetTemporaryZInfo(ds->m_TEX0.TBP0, page_offset);
t_size.y = std::max(static_cast<int>(new_height / ds->m_scale), t_size.y);
}
else
{
DevCon.Warning("HW: Temporary depth buffer creation failed.");
m_using_temp_z = false;
}
}
}
@@ -3484,7 +3606,7 @@ void GSRendererHW::Draw()
// This should never happen, but just to be safe..
if (!ds)
{
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src, possible_shuffle), target_scale, GSTextureCache::DepthStencil,
true, 0, false, force_preload, preserve_depth, m_r, src);
if (!ds) [[unlikely]]
{
@@ -3760,9 +3882,11 @@ void GSRendererHW::Draw()
}
}
const bool blending_cd = PRIM->ABE && !m_context->ALPHA.IsOpaque();
bool valid_width_change = false;
if (rt && ((!is_possible_mem_clear || blending_cd) || rt->m_TEX0.PSM != FRAME_TEX0.PSM) && !m_in_target_draw)
{
if (rt->m_TEX0.TBW != FRAME_TEX0.TBW && !m_cached_ctx.ZBUF.ZMSK && (m_cached_ctx.FRAME.FBMSK & 0xFF000000))
valid_width_change = rt->m_TEX0.TBW != FRAME_TEX0.TBW;
if (valid_width_change && !m_cached_ctx.ZBUF.ZMSK && (m_cached_ctx.FRAME.FBMSK & 0xFF000000))
{
// Alpha could be a font, and since the width is changing it's no longer valid.
// Be careful of downsize copies or other effects, checking Z MSK should hopefully be enough.. (Okami).
@@ -3776,6 +3900,13 @@ void GSRendererHW::Draw()
FRAME_TEX0.TBP0 = rt->m_TEX0.TBP0;
rt->m_TEX0 = FRAME_TEX0;
}
if (valid_width_change)
{
GSVector4i new_valid_width = rt->m_valid;
new_valid_width.z = std::min(new_valid_width.z, static_cast<int>(rt->m_TEX0.TBW) * 64);
rt->ResizeValidity(new_valid_width);
}
}
if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM || (rt && ds->m_TEX0.TBW != rt->m_TEX0.TBW)) && !m_in_target_draw)
@@ -3785,7 +3916,18 @@ void GSRendererHW::Draw()
ZBUF_TEX0.TBP0 = ds->m_TEX0.TBP0;
ds->m_TEX0 = ZBUF_TEX0;
}
if (valid_width_change)
{
GSVector4i new_valid_width = ds->m_valid;
new_valid_width.z = std::min(new_valid_width.z, static_cast<int>(ds->m_TEX0.TBW) * 64);
ds->ResizeValidity(new_valid_width);
}
}
if (rt)
g_texture_cache->CombineAlignedInsideTargets(rt, src);
if (ds)
g_texture_cache->CombineAlignedInsideTargets(ds, src);
}
else if (!m_texture_shuffle)
{
@@ -3862,7 +4004,7 @@ void GSRendererHW::Draw()
}
// NFS Undercover does a draw with double width of the actual width 1280x240, which functions the same as doubling the height.
// Ignore single page/0 page stuff, that's just gonna get silly
else if (buffer_width > 64 && update_rect.z > buffer_width)
else if (m_texture_shuffle && buffer_width > 64 && update_rect.z > buffer_width)
{
update_rect.w *= static_cast<float>(update_rect.z) / static_cast<float>(buffer_width);
update_rect.z = buffer_width;
@@ -4013,9 +4155,21 @@ void GSRendererHW::Draw()
// Dark cloud writes to 424 when the buffer is only 416 high, but masks the Z.
// Updating the valid causes the Z to overlap the framebuffer, which is obviously incorrect.
const bool z_masked = m_cached_ctx.ZBUF.ZMSK;
const bool z_update = can_update_size && !z_masked;
ds->UpdateValidity(m_r, !z_masked && (can_update_size || m_r.w <= (resolution.y * 2)));
ds->UpdateDrawn(m_r, !z_masked && (can_update_size || m_r.w <= (resolution.y * 2)));
if (rt && m_using_temp_z)
{
const GSLocalMemory::psm_t& z_psm = GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM];
const int vertical_offset = ((static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(rt->m_TEX0.TBW), 1)) * frame_psm.pgs.y;
const int z_vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(ds->m_TEX0.TBW), 1)) * z_psm.pgs.y;
const GSVector4i ds_rect = m_r - GSVector4i(vertical_offset - z_vertical_offset);
ds->UpdateValidity(ds_rect, z_update && (can_update_size || (ds_rect.w <= (resolution.y * 2) && !m_texture_shuffle)));
}
else
{
ds->UpdateValidity(m_r, z_update && (can_update_size || m_r.w <= (resolution.y * 2)));
ds->UpdateDrawn(m_r, z_update && (can_update_size || m_r.w <= (resolution.y * 2)));
}
if (!new_rect && new_height && old_end_block != ds->m_end_block)
{
@@ -4240,54 +4394,63 @@ void GSRendererHW::Draw()
}
if (zm != 0xffffffff && ds)
if (ds)
{
const bool z_masked = m_cached_ctx.ZBUF.ZMSK;
const bool was_written = zm != 0xffffffff && m_cached_ctx.DepthWrite();
//ds->m_valid = ds->m_valid.runion(r);
// Limit to 2x the vertical height of the resolution (for double buffering)
ds->UpdateValidity(real_rect, !z_masked && (can_update_size || (real_rect.w <= (resolution.y * 2) && !m_texture_shuffle)));
if (m_using_temp_z)
{
if (m_cached_ctx.DepthWrite())
{
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
if ((m_state_flush_reason != CONTEXTCHANGE) || (next_ctx.ZBUF.ZBP == m_context->ZBUF.ZBP && next_ctx.FRAME.FBP == m_context->FRAME.FBP))
{
m_temp_z_full_copy = true;
}
else
{
const int vertical_offset = ((static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(rt->m_TEX0.TBW), 1)) * frame_psm.pgs.y;
const int z_vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(rt->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
if (!m_temp_z_full_copy)
{
const GSVector4i dRect = GSVector4i(real_rect.x * ds->m_scale, (z_vertical_offset + (real_rect.y - vertical_offset)) * ds->m_scale, (real_rect.z + (1.0f / ds->m_scale)) * ds->m_scale, (z_vertical_offset + (real_rect.w + (1.0f / ds->m_scale) - vertical_offset)) * ds->m_scale);
const GSVector4 sRect = GSVector4((real_rect.x * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>(real_rect.y * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), ((real_rect.z + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((real_rect.w + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
else
{
const GSVector4i dRect = GSVector4i(0, ds->m_valid.y * ds->m_scale, ds->m_valid.z * ds->m_scale, ds->m_valid.w * ds->m_scale);
const GSVector4 sRect = GSVector4((ds->m_valid.x * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>((ds->m_valid.y + vertical_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), ((ds->m_valid.z + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>(((ds->m_valid.w + vertical_offset) + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
const int z_vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(rt->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
const int z_horizontal_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) % std::max(rt->m_TEX0.TBW, 1U)) * GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x;
const int vertical_offset = ((static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(rt->m_TEX0.TBW), 1)) * frame_psm.pgs.y;
const int horizontal_offset = ((static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) / 32) % std::max(static_cast<int>(rt->m_TEX0.TBW), 1)) * frame_psm.pgs.x;
m_temp_z_full_copy = false;
if (was_written)
{
const GSVector4i ds_real_rect = real_rect - GSVector4i(vertical_offset - z_vertical_offset);
ds->UpdateValidity(ds_real_rect, !z_masked && (can_update_size || (ds_real_rect.w <= (resolution.y * 2) && !m_texture_shuffle)));
}
if (((m_state_flush_reason != CONTEXTCHANGE) || (next_ctx.ZBUF.ZBP == m_context->ZBUF.ZBP && next_ctx.FRAME.FBP == m_context->FRAME.FBP)) && !(IsPossibleChannelShuffle() && !IsPageCopy()))
{
m_temp_z_full_copy |= was_written;
}
else
{
if (!m_temp_z_full_copy && was_written)
{
GSVector4i dRect = GSVector4i((z_horizontal_offset + (real_rect.x - horizontal_offset)) * ds->m_scale, (z_vertical_offset + (real_rect.y - vertical_offset)) * ds->m_scale, ((z_horizontal_offset + real_rect.z + (1.0f / ds->m_scale)) - horizontal_offset) * ds->m_scale, (z_vertical_offset + (real_rect.w + (1.0f / ds->m_scale) - vertical_offset)) * ds->m_scale);
GSVector4 sRect = GSVector4((real_rect.x * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>(real_rect.y * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), ((real_rect.z + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((real_rect.w + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d rt_vert_offset %d z_horz_offset %d rt_horz_offset %d", s_n, z_vertical_offset, vertical_offset, z_horizontal_offset, horizontal_offset);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
else if (m_temp_z_full_copy)
{
GSVector4i dRect = GSVector4i((ds->m_valid.x + z_horizontal_offset) * ds->m_scale, (ds->m_valid.y + z_vertical_offset) * ds->m_scale, (ds->m_valid.z + z_horizontal_offset + (1.0f / ds->m_scale)) * ds->m_scale, (ds->m_valid.w + z_vertical_offset + (1.0f / ds->m_scale)) * ds->m_scale);
GSVector4 sRect = GSVector4(((ds->m_valid.x + horizontal_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>((ds->m_valid.y + vertical_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), (((ds->m_valid.z + horizontal_offset) + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((ds->m_valid.w + vertical_offset + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
}
m_temp_z_full_copy = false;
}
}
else if (m_cached_ctx.DepthWrite() && g_texture_cache->GetTemporaryZ() != nullptr)
else if (was_written && g_texture_cache->GetTemporaryZ() != nullptr)
{
ds->UpdateValidity(real_rect, !z_masked && (can_update_size || (real_rect.w <= (resolution.y * 2) && !m_texture_shuffle)));
GSTextureCache::TempZAddress z_address_info = g_texture_cache->GetTemporaryZInfo();
if (ds->m_TEX0.TBP0 == z_address_info.ZBP)
{
@@ -5030,6 +5193,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;
}
@@ -5888,10 +6053,9 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
// Switch DATE_PRIMID with DATE_BARRIER in such cases to ensure accuracy.
// No mix of COLCLIP + sw blend + DATE_PRIMID, neither sw fbmask + DATE_PRIMID.
// Note: Do the swap in the end, saves the expensive draw splitting/barriers when mixed software blending is used.
if (sw_blending && DATE_PRIMID && m_conf.require_full_barrier)
if (sw_blending && DATE_PRIMID && features.texture_barrier && m_conf.require_full_barrier)
{
GL_PERF("DATE: Swap DATE_PRIMID with DATE_BARRIER");
m_conf.require_full_barrier = true;
DATE_PRIMID = false;
DATE_BARRIER = true;
}
@@ -6331,7 +6495,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
src_target = rt;
}
// Be careful of single page channel shuffles where depth is the source but it's not going to the same place, we can't read this directly.
else if (ds && m_conf.tex == m_conf.ds && (!m_channel_shuffle || static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) == static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0)))
else if (ds && m_conf.tex == m_conf.ds && (!m_channel_shuffle || (rt && static_cast<int>(m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) == static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0))))
{
// GL, Vulkan (in General layout), not DirectX!
const bool can_read_current_depth_buffer = g_gs_device->Features().test_and_sample_depth;
@@ -6367,10 +6531,9 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
// We need to copy. Try to cut down the source range as much as possible so we don't copy texels we're not reading.
const GSVector2i& src_unscaled_size = src_target->GetUnscaledSize();
const GSVector4i src_bounds = src_target->GetUnscaledRect();
GSVector4i copy_range;
GSVector2i copy_size;
GSVector2i copy_dst_offset;
const bool copied_rt = src_target && !tex->m_shared_texture;
GSVector4i copy_range = GSVector4i::zero();
GSVector2i copy_size = GSVector2i(0);
GSVector2i copy_dst_offset = GSVector2i(0);
// Shuffles take the whole target. This should've already been halved.
// We can't partially copy depth targets in DirectX, and GL/Vulkan should use the direct read above.
// Restricting it also breaks Tom and Jerry...
@@ -6494,21 +6657,15 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
unscaled_size = copy_size;
scale = m_downscale_source ? 1.0f : src_target->GetScale();
const float src_scale = src_target->GetScale();
GL_CACHE("HW: Copy size: %dx%d, range: %d,%d -> %d,%d (%dx%d) @ %.1f", copy_size.x, copy_size.y, copy_range.x,
copy_range.y, copy_range.z, copy_range.w, copy_range.width(), copy_range.height(), scale);
const GSVector2i scaled_copy_size = GSVector2i(static_cast<int>(std::ceil(static_cast<float>(copy_size.x) * scale)),
static_cast<int>(std::ceil(static_cast<float>(copy_size.y) * scale)));
const GSVector4i scaled_copy_range = GSVector4i((GSVector4(copy_range) * GSVector4(src_scale)).ceil());
const GSVector2i scaled_copy_dst_offset =
GSVector2i(static_cast<int>(std::ceil(static_cast<float>(copy_dst_offset.x) * scale)),
static_cast<int>(std::ceil(static_cast<float>(copy_dst_offset.y) * scale)));
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 +6705,21 @@ __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();
}
@@ -7300,7 +7470,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
if (m_conf.destination_alpha >= GSHWDrawConfig::DestinationAlphaMode::Stencil &&
m_conf.destination_alpha <= GSHWDrawConfig::DestinationAlphaMode::StencilOne && !m_conf.ds)
{
const bool is_one_barrier = (m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle));
const bool is_one_barrier = (features.texture_barrier && m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle));
if ((temp_ds.reset(g_gs_device->CreateDepthStencil(m_conf.rt->GetWidth(), m_conf.rt->GetHeight(), GSTexture::Format::DepthStencil, false)), temp_ds))
{
m_conf.ds = temp_ds.get();
@@ -7476,11 +7646,17 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
pxAssert(!m_conf.require_full_barrier || !m_conf.ps.colclip_hw);
// Swap full barrier for one barrier when there's no overlap, or a shuffle.
if (m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle))
if (features.texture_barrier && m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle))
{
m_conf.require_full_barrier = false;
m_conf.require_one_barrier = true;
}
else if (!features.texture_barrier)
{
// These shouldn't be enabled if texture barriers aren't supported, make sure they are off.
m_conf.ps.write_rg = 0;
m_conf.require_full_barrier = false;
}
// rs
const GSVector4i hacked_scissor = m_channel_shuffle ? GSVector4i::cxpr(0, 0, 1024, 1024) : m_context->scissor.in;
@@ -8945,10 +9121,7 @@ void GSRendererHW::EndHLEHardwareDraw(bool force_copy_on_hazard /* = false */)
return;
}
// DX11 can't partial copy depth textures.
const GSVector4i copy_rect = (src->IsDepthStencil() && !features.test_and_sample_depth) ?
src->GetRect() :
config.drawarea.rintersect(src->GetRect());
const GSVector4i copy_rect = config.drawarea.rintersect(src->GetRect());
g_gs_device->CopyRect(src, copy, copy_rect - copy_rect.xyxy(), copy_rect.x, copy_rect.y);
config.tex = copy;
}

View File

@@ -222,8 +222,8 @@ public:
GSVector4i ComputeBoundingBox(const GSVector2i& rtsize, float rtscale);
void MergeSprite(GSTextureCache::Source* tex);
float GetTextureScaleFactor() override;
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr);
GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr, const bool can_expand = true);
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr, const bool is_shuffle = false);
GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr, const bool can_expand = true, const bool is_shuffle = false);
void Reset(bool hardware_reset) override;
void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override;

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)
{
@@ -1107,17 +1107,15 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
if (dst->m_unscaled_size != t->m_unscaled_size)
{
t->ResizeTexture(t->m_unscaled_size.x, t->m_unscaled_size.y);
t->m_valid = dst->m_valid;
}
CopyRGBFromDepthToColor(t, dst);
}
t->m_valid = t->m_valid.runion(dst->m_valid);
dst = t;
if (GSUtil::GetChannelMask(TEX0.PSM) & 0x8)
t->UnscaleRTAlpha();
// Don't need to de-RTA here as we were actually copying the RGB over, preserving the existing alpha.
inside_target = false;
break;
}
@@ -1183,7 +1181,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 +1190,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);
@@ -1410,16 +1408,31 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
if (rect_clean)
{
bool can_use = true;
for (auto& dirty : t->m_dirty)
{
const GSVector4i dirty_rect = dirty.GetDirtyRect(t->m_TEX0, t->m_TEX0.PSM != dirty.psm);
if (!dirty_rect.rintersect(new_rect).rempty())
{
rect_clean = false;
partial |= !new_rect.rintersect(dirty_rect).eq(new_rect) || dirty_rect.eq(new_rect);
if(!dirty_rect.rintersect(t->m_valid).eq(t->m_valid) || GSUtil::GetChannelMask(t->m_TEX0.PSM) != t->m_dirty.GetDirtyChannels())
partial |= !new_rect.rintersect(dirty_rect).eq(new_rect) || dirty_rect.eq(new_rect);
else // Nothing is valid anymore, kill it.
{
can_use = false;
}
break;
}
}
if (!can_use)
{
InvalidateSourcesFromTarget(t);
i = list.erase(i);
delete t;
continue;
}
}
const u32 channel_mask = GSUtil::GetChannelMask(psm);
@@ -1456,7 +1469,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 +1498,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;
@@ -1683,22 +1696,27 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
u32 src_psm = psm;
// If the input is C16 and it's actually a shuffle of 32bits we need to correct the size.
if ((tex_color_psm & 0xF) <= PSMCT24 && (psm & 0x7) == PSMCT16 && possible_shuffle)
if ((tex_color_psm & 0xF) <= PSMCT24 && (psm & 0x7) == PSMCT16)
{
src_psm = t->m_TEX0.PSM;
// If it's taking double width for the shuffle, half that.
if (src_bw == (rt_tbw * 2))
if (possible_shuffle)
{
src_bw = rt_tbw;
src_psm = t->m_TEX0.PSM;
// If it's taking double width for the shuffle, half that.
if (src_bw == (rt_tbw * 2))
{
src_bw = rt_tbw;
rect.x /= 2;
rect.z /= 2;
}
else
{
rect.y /= 2;
rect.w /= 2;
rect.x /= 2;
rect.z /= 2;
}
else
{
rect.y /= 2;
rect.w /= 2;
}
}
else // Formats are not compatible for normal draws, only shuffles.
continue;
}
if (bp > t->m_TEX0.TBP0)
{
@@ -1710,11 +1728,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 || bw == 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 +1743,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 +1792,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 +1818,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 +1875,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 +1892,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 +1953,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 +1975,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)
{
@@ -2087,6 +2106,10 @@ GSVector2i GSTextureCache::ScaleRenderTargetSize(const GSVector2i& sz, float sca
void GSTextureCache::CombineAlignedInsideTargets(Target* target, GSTextureCache::Source* src)
{
// Don't combine targets if Tex in RT is off, it will just fail to find them and make a new one, causing a loop of copies.
if (GSConfig.UserHacks_TextureInsideRt < GSTextureInRtMode::InsideTargets)
return;
auto& list = m_dst[target->m_type];
for (auto i = list.begin(); i != list.end();)
@@ -2096,7 +2119,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;
@@ -2120,12 +2143,17 @@ void GSTextureCache::CombineAlignedInsideTargets(Target* target, GSTextureCache:
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 source_rect = GSVector4(t->m_drawn_since_read) / (GSVector4(t->m_unscaled_size).xyxy() * 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);
target->m_valid_alpha_high |= t->m_valid_alpha_high;
target->m_valid_alpha_low |= t->m_valid_alpha_low;
GL_CACHE("Combining %x-%x in to %x-%x draw %d", t->m_TEX0.TBP0, t->m_end_block, target->m_TEX0.TBP0, target->m_end_block, GSState::s_n);
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);
@@ -2269,7 +2297,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_32_bits_fmt |= (psm_s.bpp != 16);
break;
}
else if(!(src && src->m_from_target == t))
else if (!(src && src->m_from_target == t))
{
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to change in target", t->m_TEX0.TBP0, t->m_TEX0.TBW, psm_str(t->m_TEX0.PSM));
InvalidateSourcesFromTarget(t);
@@ -2332,11 +2360,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
lookup_rect = lookup_rect & GSVector4i(~8);
const GSVector4i translated_rect = GSVector4i(0, 0, 0, 0).max_i32(TranslateAlignedRectByPage(t, TEX0.TBP0, TEX0.PSM, TEX0.TBW, lookup_rect));
const GSVector4i dirty_rect = t->m_dirty.empty() ? GSVector4i::zero() : t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(t->m_valid);
const GSVector4i dirty_rect = t->m_dirty.empty() ? GSVector4i::zero() : t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size);
const bool all_dirty = dirty_rect.eq(t->m_valid);
if (!is_shuffle && !t->m_dirty.empty() && (!preserve_alpha && !preserve_rgb) && (GSState::s_n - 1) != t->m_last_draw)
if (!is_shuffle && !dirty_rect.rempty() && (!preserve_alpha && !preserve_rgb) && (GSState::s_n - 3) > t->m_last_draw)
{
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to dirty areas not preserved (Likely change in target)", t->m_TEX0.TBP0, t->m_TEX0.TBW, psm_str(t->m_TEX0.PSM));
InvalidateSourcesFromTarget(t);
@@ -2346,7 +2374,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
continue;
}
if (!all_dirty && ((translated_rect.w <= t->m_valid.w) || widthpage_offset == 0 || (GSState::s_n - 1) == t->m_last_draw))
if (!all_dirty && ((translated_rect.w <= t->m_valid.w) || widthpage_offset == 0 || (GSState::s_n - 3) <= t->m_last_draw))
{
if (TEX0.TBW == t->m_TEX0.TBW && !is_shuffle && widthpage_offset == 0 && ((min_rect.w + 63) / 64) > 1)
{
@@ -2592,7 +2620,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
src->m_target_direct = false;
src->m_shared_texture = false;
if(!req_copy)
if (!req_copy)
dst->ResizeTexture(new_size.x, new_size.y, true, true, GSVector4i(dRect), true);
else
{
@@ -2642,7 +2670,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
if ((!is_shuffle && (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp != GSLocalMemory::m_psm[TEX0.PSM].bpp || GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth)) ||
(is_shuffle && GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16))
{
if(GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth || dst->m_TEX0.TBW != TEX0.TBW)
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth || dst->m_TEX0.TBW != TEX0.TBW)
dst->m_32_bits_fmt = GSLocalMemory::m_psm[TEX0.PSM].bpp != 16;
if (!is_shuffle || (is_shuffle && GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16))
@@ -2692,7 +2720,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
}
if (!dst->m_valid_rgb)
const u32 mask = GSLocalMemory::m_psm[TEX0.PSM].fmsk;
if (!dst->m_valid_rgb && ((fbmask & 0x00FFFFFF) & mask) != (mask & 0x00FFFFFF))
{
GL_CACHE("TC: Cannot find RGB target for %s[%x], clearing.", to_string(type), dst->m_TEX0.TBP0);
@@ -2774,11 +2803,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
for (auto i = rev_list.begin(); i != rev_list.end(); ++i)
{
Target* t = *i;
// Don't pull in targets without valid lower 24 bits, it makes no sense to convert them.
// Don't pull in targets without valid lower 24 bits unless the Z is 32bits and the alpha is valid, it makes no sense to convert them otherwise.
// FIXME: Technically the difference in size is fine, but if the target gets reinterpreted, the hw renderer doesn't rearrange the target.
// This does cause some extra uploads in some games (like Burnout), but without this, bad data gets displayed in games like Transformers.
if (bp != t->m_TEX0.TBP0 || !t->m_valid_rgb || (!is_shuffle && t->m_TEX0.TBW != TEX0.TBW &&
(possible_clear || ((~GSLocalMemory::m_psm[t->m_TEX0.PSM].fmsk | fbmask) == 0xffffffff))))
if (bp != t->m_TEX0.TBP0 || (!t->m_valid_rgb && (!(GSUtil::GetChannelMask(TEX0.PSM) & 0x8) || !(t->m_valid_alpha_low || t->m_valid_alpha_high))) ||
(!is_shuffle && t->m_TEX0.TBW != TEX0.TBW && (possible_clear || ((~GSLocalMemory::m_psm[t->m_TEX0.PSM].fmsk | fbmask) == 0xffffffff))))
{
continue;
}
@@ -3013,9 +3042,8 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(GIFRegTEX0 TEX0, const GSVe
if (!is_frame)
{
// Not having this valid could make things explode, but I do enjoy watching the world burn (and this is actually more correct).
dst->m_valid_rgb =true;
const u32 mask = GSLocalMemory::m_psm[TEX0.PSM].fmsk;
dst->m_valid_rgb = GSLocalMemory::m_psm[TEX0.PSM].depth || ((fbmask & 0x00FFFFFF) & mask) != (mask & 0x00FFFFFF) || (dst->m_dirty.GetDirtyChannels() & 0x7);
// If there is an opposite target without valid RGB, we need to match them up
auto& rev_list = m_dst[1 - type];
@@ -3024,9 +3052,6 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(GIFRegTEX0 TEX0, const GSVe
Target* const rev_t = *j;
if (rev_t->m_TEX0.TBP0 == dst->m_TEX0.TBP0 && GSLocalMemory::m_psm[rev_t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp)
{
if (GSLocalMemory::m_psm[rev_t->m_TEX0.PSM].trbpp == 24 && ((fbmask & 0x00FFFFFF) & mask) == (mask & 0x00FFFFFF))
dst->m_valid_rgb = false;
if (!rev_t->m_valid_rgb && dst->m_valid_rgb)
rev_t->m_was_dst_matched = true;
@@ -3265,23 +3290,19 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
if (buffer_width != std::max(1U, t->m_TEX0.TBW))
{
i++;
// Check if this got messed with at some point, if it did just nuke it.
if (t->m_valid.width() == dst->m_valid.width())
if (!preserve_target && t->m_age > 0)
{
// Not correct, but it's better than a null reference.
// Probably best we don't poke the beast if it's being used as the current source.
if (src && src->m_target_direct && src->m_from_target == t)
{
DevCon.Warning("Replacing source target, texture may be invalid");
src->m_texture = dst->m_texture;
src->m_from_target = dst;
}
continue;
InvalidateSourcesFromTarget(t);
i = list.erase(j);
delete t;
}
else
i++;
continue;
}
// If the two targets are misaligned, it's likely a relocation, so we can just kill the old target.
@@ -3919,7 +3940,7 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
const u32 offset = (std::abs(static_cast<int>(start_bp - t->m_TEX0.TBP0)) >> 5) % std::max(1U, t->m_TEX0.TBW);
// If not fully contained but they are aligned and or clean, just dirty the area.
if (start_bp != t->m_TEX0.TBP0 && (t->m_TEX0.TBP0 < start_bp || t->UnwrappedEndBlock() > end_bp) && (offset == 0 || t->m_dirty.size() == 0))
if (type != DepthStencil && start_bp != t->m_TEX0.TBP0 && (t->m_TEX0.TBP0 < start_bp || t->UnwrappedEndBlock() > end_bp) && (offset == 0 || t->m_dirty.size() == 0))
{
if (write_bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[write_psm].bpp)
{
@@ -5436,7 +5457,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_unscaled_size = dst->m_unscaled_size;
src->m_shared_texture = true;
if(channel_shuffle)
if (channel_shuffle)
m_temporary_source = src;
}
@@ -5786,7 +5807,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_region.SetX(x_offset, x_offset + tw);
src->m_region.SetY(y_offset, y_offset + th);
if(!GSConfig.UserHacks_NativePaletteDraw)
if (!GSConfig.UserHacks_NativePaletteDraw)
m_temporary_source = src;
}
else
@@ -6776,7 +6797,7 @@ GSTextureCache::Source::~Source()
// to recycle.
if (!m_shared_texture && !m_from_hash_cache && m_texture)
{
if(m_from_target)
if (m_from_target)
g_texture_cache->m_target_memory_usage -= m_texture->GetMemUsage();
else
g_texture_cache->m_source_memory_usage -= m_texture->GetMemUsage();

View File

@@ -209,7 +209,7 @@ public:
struct TempZAddress
{
u32 ZBP;
u32 offset;
int offset;
GSVector4i rect_since;
};
@@ -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

@@ -2489,12 +2489,15 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
if (config.require_one_barrier && !m_features.texture_barrier)
{
// Requires a copy of the RT
// Requires a copy of the RT.
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, colclip_rt ? GSTexture::Format::ColorClip : GSTexture::Format::Color, true);
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}",
config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
if (draw_rt_clone)
{
GL_PUSH("GL: Copy RT to temp texture {%d,%d %dx%d}",
config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
CopyRect(colclip_rt ? colclip_rt : config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top);
}
}
IASetVertexBuffer(config.verts, config.nverts);
@@ -2563,7 +2566,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
if (check_barrier && ((config.tex && (config.tex == config.ds || config.tex == config.rt)) || ((psel.ps.IsFeedbackLoop() || psel.ps.blend_c == 1) && GLState::rt == config.rt)))
{
// Ensure all depth writes are finished before sampling
GL_INS("Texture barrier to flush depth or rt before reading");
GL_INS("GL: Texture barrier to flush depth or rt before reading");
glTextureBarrier();
}
// additional non-pipeline config stuff

View File

@@ -1491,7 +1491,7 @@ __ri void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSV
case 2: break;
}
if(!(sel.fpsm == 1 && sel.abc == 1))
if (!(sel.fpsm == 1 && sel.abc == 1))
{
switch(sel.abc)
{

View File

@@ -562,7 +562,7 @@ L("loop");
L("step");
// if(steps <= 0) break;
// if (steps <= 0) break;
if (!m_sel.edge)
{
@@ -768,7 +768,7 @@ void GSDrawScanlineCodeGenerator::Init()
cvttps2dq(xym6, vt);
// s = vti.xxxx() + m_local.d[skip].s;
// t = vti.yyyy(); if(!sprite) t += m_local.d[skip].t;
// t = vti.yyyy(); if (!sprite) t += m_local.d[skip].t;
pshufd(s, xym6, _MM_SHUFFLE(0, 0, 0, 0));
pshufd(t, xym6, _MM_SHUFFLE(1, 1, 1, 1));
@@ -925,7 +925,7 @@ void GSDrawScanlineCodeGenerator::Step()
// GSVector4i stq = m_local.d4.stq;
// s += stq.xxxx();
// if(!sprite) t += st.yyyy();
// if (!sprite) t += st.yyyy();
broadcasti128(stq, _rip_local_d(stq));
@@ -2096,7 +2096,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
clamp16(_ga, tmp);
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
@@ -2109,7 +2109,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
case TFX_DECAL:
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
// GSVector4i ga = iip ? gaf : m_local.c.ga;
@@ -2139,7 +2139,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
case TFX_HIGHLIGHT2:
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
@@ -2990,8 +2990,8 @@ void GSDrawScanlineCodeGenerator::WritePixel(const XYm& src_, const AddressReg&
{
if (fast)
{
// if(fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
// if(fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
// if (fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
// if (fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
test(mask, 0x0000000f << shift);
je("@f");
@@ -3020,10 +3020,10 @@ void GSDrawScanlineCodeGenerator::WritePixel(const XYm& src_, const AddressReg&
}
else
{
// if(fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
// if(fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
// if(fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
// if(fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
// if (fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
// if (fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
// if (fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
// if (fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
test(mask, 0x00000003 << shift);
je("@f");

View File

@@ -158,7 +158,7 @@ void GSDrawScanlineCodeGenerator::Generate()
Label exit;
armAsm->Bind(&m_step_label);
// if(steps <= 0) break;
// if (steps <= 0) break;
if (!m_sel.edge)
{
@@ -332,7 +332,7 @@ void GSDrawScanlineCodeGenerator::Init()
armAsm->Fcvtzs(v6.V4S(), v4.V4S());
// s = vti.xxxx() + m_local.d[skip].s;
// t = vti.yyyy(); if(!sprite) t += m_local.d[skip].t;
// t = vti.yyyy(); if (!sprite) t += m_local.d[skip].t;
armAsm->Dup(_temp_s.V4S(), v6.V4S(), 0);
armAsm->Dup(_temp_t.V4S(), v6.V4S(), 1);
@@ -485,7 +485,7 @@ void GSDrawScanlineCodeGenerator::Step()
// GSVector4i stq = m_local.d4.stq;
// s += stq.xxxx();
// if(!sprite) t += stq.yyyy();
// if (!sprite) t += stq.yyyy();
armAsm->Dup(_vscratch.V4S(), _d4_stq.V4S(), 0);
if (m_sel.prim != GS_SPRITE_CLASS || m_sel.mmin)
@@ -1394,7 +1394,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
modulate16(v6, _temp_ga, 1);
clamp16(v6, v3);
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
@@ -1407,7 +1407,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
case TFX_DECAL:
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
@@ -1435,7 +1435,7 @@ void GSDrawScanlineCodeGenerator::AlphaTFX()
case TFX_HIGHLIGHT2:
// if(!tcc) gat = gat.mix16(ga.srl16(7));
// if (!tcc) gat = gat.mix16(ga.srl16(7));
if (!m_sel.tcc)
{
@@ -2158,8 +2158,8 @@ void GSDrawScanlineCodeGenerator::WritePixel(const VRegister& src, const Registe
{
if (fast)
{
// if(fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
// if(fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
// if (fzm & 0x0f) GSVector4i::storel(&vm16[addr + 0], fs);
// if (fzm & 0xf0) GSVector4i::storeh(&vm16[addr + 8], fs);
Label skip_low, skip_high;
armAsm->Lsl(_wscratch, addr, 1); // *2
@@ -2177,10 +2177,10 @@ void GSDrawScanlineCodeGenerator::WritePixel(const VRegister& src, const Registe
}
else
{
// if(fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
// if(fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
// if(fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
// if(fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
// if (fzm & 0x03) WritePixel(fpsm, &vm16[addr + 0], fs.extract32<0>());
// if (fzm & 0x0c) WritePixel(fpsm, &vm16[addr + 2], fs.extract32<1>());
// if (fzm & 0x30) WritePixel(fpsm, &vm16[addr + 8], fs.extract32<2>());
// if (fzm & 0xc0) WritePixel(fpsm, &vm16[addr + 10], fs.extract32<3>());
Label skip_0, skip_1, skip_2, skip_3;

View File

@@ -444,9 +444,9 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
m1 = (y0011 == y1221).mask() & 7;
// if(i == 0) => y0 < y1 < y2
// if(i == 1) => y0 == y1 < y2
// if(i == 4) => y0 < y1 == y2
// if (i == 0) => y0 < y1 < y2
// if (i == 1) => y0 == y1 < y2
// if (i == 4) => y0 < y1 == y2
if (m1 == 7) // y0 == y1 == y2
return;
@@ -623,9 +623,9 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
m1 = (y0011 == y1221).mask() & 7;
// if(i == 0) => y0 < y1 < y2
// if(i == 1) => y0 == y1 < y2
// if(i == 4) => y0 < y1 == y2
// if (i == 0) => y0 < y1 < y2
// if (i == 1) => y0 == y1 < y2
// if (i == 4) => y0 < y1 == y2
if (m1 == 7)
return; // y0 == y1 == y2

View File

@@ -94,7 +94,7 @@ void GSRendererSW::VSync(u32 field, bool registers_written, bool idle_frame)
m_tc->IncAge();
m_draw_transfers.clear();
// if((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
// if ((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
}
GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset)

View File

@@ -515,7 +515,7 @@ void GSSetupPrimCodeGenerator::Color()
pshufd(xym1, xym0, _MM_SHUFFLE(1, 0, 3, 2));
punpcklwd(xym0, xym1);
// if(!tme) c = c.srl16(7);
// if (!tme) c = c.srl16(7);
if (m_sel.tfx == TFX_NONE)
{

View File

@@ -322,7 +322,7 @@ void GSSetupPrimCodeGenerator::Color()
armAsm->Ext(v1.V16B(), v0.V16B(), v0.V16B(), 8);
armAsm->Zip1(v0.V8H(), v0.V8H(), v1.V8H());
// if(!tme) c = c.srl16(7);
// if (!tme) c = c.srl16(7);
if (m_sel.tfx == TFX_NONE)
armAsm->Ushr(v0.V8H(), v0.V8H(), 7);

View File

@@ -10,9 +10,9 @@
#define ipumsk( src ) ( (src) & 0xff )
#define ipucase( src ) case ipumsk(src)
#define IPU_INT_TO( cycles ) if(!(cpuRegs.interrupt & (1<<4))) CPU_INT( DMAC_TO_IPU, cycles )
#define IPU_INT_TO( cycles ) if (!(cpuRegs.interrupt & (1<<4))) CPU_INT( DMAC_TO_IPU, cycles )
#define IPU_INT_FROM( cycles ) CPU_INT( DMAC_FROM_IPU, cycles )
#define IPU_INT_PROCESS( cycles ) if(!(cpuRegs.interrupt & (1 << IPU_PROCESS))) CPU_INT( IPU_PROCESS, cycles )
#define IPU_INT_PROCESS( cycles ) if (!(cpuRegs.interrupt & (1 << IPU_PROCESS))) CPU_INT( IPU_PROCESS, cycles )
//
// Bitfield Structures
//

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

@@ -190,7 +190,7 @@ static void execI()
#if 0
static long int print_me = 0;
// Based on cycle
// if( cpuRegs.cycle > 0x4f24d714 )
// if ( cpuRegs.cycle > 0x4f24d714 )
// Or dump from a particular PC (useful to debug handler/syscall)
if (pc == 0x80000000)
{

View File

@@ -20,7 +20,7 @@
#define G_GC(reg)
#endif
#define SUM_FLAG if(gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
#define SUM_FLAG if (gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
#ifdef _MSC_VER_
#pragma warning(disable:4244)

View File

@@ -356,7 +356,7 @@ void ba0W16(u32 mem, u16 value)
s_ba_command_executing = true;
s_ba_error_detected = false;
}
else if(s_ba[0x2] == 0x42) // Read Mode
else if (s_ba[0x2] == 0x42) // Read Mode
{
int size = (s_ba[masked_mem] & 0xF);
@@ -406,7 +406,7 @@ u16 ba0R16(u32 mem)
void MyMemCheck(u32 mem)
{
if( mem == 0x1c02f2a0 )
if ( mem == 0x1c02f2a0 )
Console.WriteLn("yo; (mem == 0x1c02f2a0) in MyMemCheck...");
}

View File

@@ -256,7 +256,7 @@ void iopTestIntc()
// Note: No need to set the iop's branch delta here, since the EE
// will run an IOP branch test regardless.
}
else if( !iopEventTestIsActive )
else if ( !iopEventTestIsActive )
psxSetNextBranchDelta( 2 );
}

View File

@@ -127,9 +127,9 @@ __ri void cpuException(u32 code, u32 bd)
cpuUpdateOperationMode();
return;
}
else if((code & 0x38000) == 0x10000)
else if ((code & 0x38000) == 0x10000)
offset = 0x80; //Performance Counter
else if((code & 0x38000) == 0x18000)
else if ((code & 0x38000) == 0x18000)
offset = 0x100; //Debug
else
Console.Error("Unknown Level 2 Exception!! Cause %x", code);

View File

@@ -1117,7 +1117,7 @@ static void RegWrite_Core(u16 value)
if (!thiscore.DmaMode && !(thiscore.Regs.STATX & 0x400))
thiscore.Regs.STATX &= ~0x80;
else if(!oldDmaMode && thiscore.DmaMode)
else if (!oldDmaMode && thiscore.DmaMode)
thiscore.Regs.STATX |= 0x80;
thiscore.ActiveTSA = thiscore.TSA;

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;

View File

@@ -164,7 +164,7 @@ static int jo_processDU(jo_bits_t *bits, float A[64], const unsigned char htdc[9
jo_writeBits(bits, run, 6);
if (AC < -127) {
jo_writeBits(bits, 128, 12);
} else if(AC > 127) {
} else if (AC > 127) {
jo_writeBits(bits, 0, 12);
}
code = AC & 0xFFF;

View File

@@ -93,7 +93,7 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
if(!vifXch.qwc)
vifX.inprogress &= ~0x1;
else if(vifX.irqoffset.value != 0)
else if (vifX.irqoffset.value != 0)
vifX.irqoffset.enabled = true;
}
else

View File

@@ -70,12 +70,12 @@ mem8_t iopHwRead8_Page1( u32 addr )
DevCon.Warning( "HwRead8 from Counter16 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) );
ret = psxHu8( addr );
}
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
else if ( masked_addr >= 0x480 && masked_addr < 0x4a0 )
{
DevCon.Warning( "HwRead8 from Counter32 [ignored] @ 0x%08x = 0x%02x", addr, psxHu8(addr) );
ret = psxHu8( addr );
}
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
else if ( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
ret = USBread8( addr );
PSXHW_LOG( "HwRead8 from USB @ 0x%08x = 0x%02x", addr, ret );
@@ -179,7 +179,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
// ------------------------------------------------------------------------
// Counters, 32-bit varieties!
//
else if( masked_addr >= 0x480 && masked_addr < 0x4b0 )
else if ( masked_addr >= 0x480 && masked_addr < 0x4b0 )
{
int cntidx = (( masked_addr >> 4 ) & 0xf) - 5;
switch( masked_addr & 0xf )
@@ -218,14 +218,14 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
// ------------------------------------------------------------------------
// USB, with both 16 and 32 bit interfaces
//
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
else if ( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
ret = (sizeof(T) == 2) ? USBread16( addr ) : USBread32( addr );
}
// ------------------------------------------------------------------------
// SPU2, accessible in 16 bit mode only!
//
else if( masked_addr >= pgmsk(HW_SPU2_START) && masked_addr < pgmsk(HW_SPU2_END) )
else if ( masked_addr >= pgmsk(HW_SPU2_START) && masked_addr < pgmsk(HW_SPU2_END) )
{
if( sizeof(T) == 2 )
ret = SPU2read( addr );
@@ -238,7 +238,7 @@ static __fi T _HwRead_16or32_Page1( u32 addr )
// ------------------------------------------------------------------------
// PS1 GPU access
//
else if( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
else if ( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
{
// todo: psx mode: this is new
if( sizeof(T) == 2 )
@@ -418,7 +418,7 @@ mem32_t iopHwRead32_Page8( u32 addr )
ret = g_Sio2.send3[parm];
Sio2Log.WriteLn("%s(%08X) SIO2 SEND3 Read (%08X)", __FUNCTION__, addr, ret);
}
else if( masked_addr < 0x260 )
else if ( masked_addr < 0x260 )
{
// SIO2 Send commands alternate registers. First reg maps to Send1, second
// to Send2, third to Send1, etc. And the following clever code does this:
@@ -426,7 +426,7 @@ mem32_t iopHwRead32_Page8( u32 addr )
ret = (masked_addr & 4) ? g_Sio2.send2[parm] : g_Sio2.send1[parm];
Sio2Log.WriteLn("%s(%08X) SIO2 SEND1/2 Read (%08X)", __FUNCTION__, addr, ret);
}
else if( masked_addr <= 0x280 )
else if ( masked_addr <= 0x280 )
{
switch( masked_addr )
{
@@ -471,7 +471,7 @@ mem32_t iopHwRead32_Page8( u32 addr )
break;
}
}
else if( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) )
else if ( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) )
{
ret = FWread32( addr );
} else {

View File

@@ -104,12 +104,12 @@ void iopHwWrite8_Page1( u32 addr, mem8_t val )
DbgCon.Warning( "HwWrite8 to Counter16 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
else if( masked_addr >= 0x480 && masked_addr < 0x4a0 )
else if ( masked_addr >= 0x480 && masked_addr < 0x4a0 )
{
DbgCon.Warning( "HwWrite8 to Counter32 [ignored] @ addr 0x%08x = 0x%02x", addr, psxHu8(addr) );
psxHu8( addr ) = val;
}
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
else if ( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
USBwrite8( addr, val );
}
@@ -219,7 +219,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
// ------------------------------------------------------------------------
// Counters, 32-bit varieties!
//
else if( masked_addr >= 0x480 && masked_addr < 0x4b0 )
else if ( masked_addr >= 0x480 && masked_addr < 0x4b0 )
{
int cntidx = (( masked_addr >> 4 ) & 0xf) - 5;
switch( masked_addr & 0xf )
@@ -252,14 +252,14 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
// ------------------------------------------------------------------------
// USB, with both 16 and 32 bit interfaces
//
else if( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
else if ( (masked_addr >= pgmsk(HW_USB_START)) && (masked_addr < pgmsk(HW_USB_END)) )
{
if( sizeof(T) == 2 ) USBwrite16( addr, val ); else USBwrite32( addr, val );
}
// ------------------------------------------------------------------------
// SPU2, accessible in 16 bit mode only!
//
else if( (masked_addr >= pgmsk(HW_SPU2_START)) && (masked_addr < pgmsk(HW_SPU2_END)) )
else if ( (masked_addr >= pgmsk(HW_SPU2_START)) && (masked_addr < pgmsk(HW_SPU2_END)) )
{
if( sizeof(T) == 2 )
SPU2write( addr, val );
@@ -272,7 +272,7 @@ static __fi void _HwWrite_16or32_Page1( u32 addr, T val )
// ------------------------------------------------------------------------
// PS1 GPU access
//
else if( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
else if ( (masked_addr >= pgmsk(HW_PS1_GPU_START)) && (masked_addr < pgmsk(HW_PS1_GPU_END)) )
{
// todo: psx mode: this is new
if( sizeof(T) == 2 )
@@ -599,7 +599,7 @@ void iopHwWrite32_Page8( u32 addr, mem32_t val )
const int parm = (masked_addr - 0x200) / 4;
g_Sio2.SetSend3(parm, val);
}
else if( masked_addr < 0x260 )
else if ( masked_addr < 0x260 )
{
// SIO2 Send commands alternate registers. First reg maps to Send1, second
// to Send2, third to Send1, etc. And the following clever code does this:
@@ -617,7 +617,7 @@ void iopHwWrite32_Page8( u32 addr, mem32_t val )
g_Sio2.send1[parm] = val;
}
}
else if( masked_addr <= 0x280 )
else if ( masked_addr <= 0x280 )
{
switch( masked_addr )
{
@@ -661,7 +661,7 @@ void iopHwWrite32_Page8( u32 addr, mem32_t val )
break;
}
}
else if( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) )
else if ( masked_addr >= pgmsk(HW_FW_START) && masked_addr <= pgmsk(HW_FW_END) )
{
FWwrite32( addr, val );
}

View File

@@ -161,7 +161,7 @@ static __ri const char* _ioplog_GetHwName( u32 addr, T val )
default: return "Invalid Counter";
}
}
else if( addr >= 0x1f801480 && addr < 0x1f8014b0 )
else if ( addr >= 0x1f801480 && addr < 0x1f8014b0 )
{
switch( addr & 0xf )
{
@@ -174,20 +174,20 @@ static __ri const char* _ioplog_GetHwName( u32 addr, T val )
default: return "Invalid Counter";
}
}
else if( (addr >= HW_USB_START) && (addr < HW_USB_END) )
else if ( (addr >= HW_USB_START) && (addr < HW_USB_END) )
{
return "USB";
}
else if( (addr >= HW_SPU2_START) && (addr < HW_SPU2_END) )
else if ( (addr >= HW_SPU2_START) && (addr < HW_SPU2_END) )
{
return "SPU2";
}
else if( addr >= pgmsk(HW_FW_START) && addr <= pgmsk(HW_FW_END) )
else if ( addr >= pgmsk(HW_FW_START) && addr <= pgmsk(HW_FW_END) )
{
return "FW";
}
else if( addr >= 0x1f808200 && addr < 0x1f808240 ) { return "SIO2 param"; }
else if( addr >= 0x1f808240 && addr < 0x1f808260 ) { return "SIO2 send"; }
else if ( addr >= 0x1f808200 && addr < 0x1f808240 ) { return "SIO2 param"; }
else if ( addr >= 0x1f808240 && addr < 0x1f808260 ) { return "SIO2 send"; }
return NULL; //"Unknown";
}

View File

@@ -648,7 +648,7 @@ static OperandType vtlbUnmappedPReadSm(u32 addr) {
}
return 0;
}
static RETURNS_R128 vtlbUnmappedPReadLg(u32 addr) { vtlb_BusError(addr, 0); if(!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)){ return readCache128(addr, false); } return r128_zero(); }
static RETURNS_R128 vtlbUnmappedPReadLg(u32 addr) { vtlb_BusError(addr, 0); if (!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)){ return readCache128(addr, false); } return r128_zero(); }
template <typename OperandType>
static void vtlbUnmappedPWriteSm(u32 addr, OperandType data) {
@@ -663,7 +663,7 @@ static void vtlbUnmappedPWriteSm(u32 addr, OperandType data) {
}
}
}
static void TAKES_R128 vtlbUnmappedPWriteLg(u32 addr, r128 data) { vtlb_BusError(addr, 1); if(!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)) { writeCache128(addr, reinterpret_cast<mem128_t*>(&data) /*Safe??*/, false); }}
static void TAKES_R128 vtlbUnmappedPWriteLg(u32 addr, r128 data) { vtlb_BusError(addr, 1); if (!CHECK_EEREC && CHECK_CACHE && CheckCache(addr)) { writeCache128(addr, reinterpret_cast<mem128_t*>(&data) /*Safe??*/, false); }}
// clang-format on
// --------------------------------------------------------------------------------------

View File

@@ -1356,7 +1356,7 @@ static void iBranchTest(u32 newpc)
// Check the Event scheduler if our "cycle target" has been reached.
// Equiv code to:
// cpuRegs.cycle += blockcycles;
// if( cpuRegs.cycle > g_nextEventCycle ) { DoEvents(); }
// if ( cpuRegs.cycle > g_nextEventCycle ) { DoEvents(); }
if (EmuConfig.Speedhacks.WaitLoop && s_nBlockFF && newpc == s_branchTo)
{

View File

@@ -247,7 +247,7 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit)
xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
}
}
else if(isEbit)
else if (isEbit)
{
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack)
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);

View File

@@ -1949,7 +1949,7 @@ mVUop(mVU_B)
pass2
{
if (mVUlow.badBranch) { xMOV(ptr32[&mVU.badBranch], branchAddr(mVU)); }
if (mVUlow.evilBranch) { if(isEvilBlock) xMOV(ptr32[&mVU.evilevilBranch], branchAddr(mVU)); else xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU)); }
if (mVUlow.evilBranch) { if (isEvilBlock) xMOV(ptr32[&mVU.evilevilBranch], branchAddr(mVU)); else xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU)); }
mVU.profiler.EmitOp(opB);
}
pass3 { mVUlog("B [<a href=\"#addr%04x\">%04x</a>]", branchAddr(mVU), branchAddr(mVU)); }