mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cdf5eefc9 | ||
|
|
c7ee72647d | ||
|
|
5434af348e | ||
|
|
169cea0f01 | ||
|
|
a8f3ec8184 | ||
|
|
7796b2a12b | ||
|
|
d9cffd58ba | ||
|
|
e566386240 | ||
|
|
45af1e172f | ||
|
|
768b2e52a6 | ||
|
|
7abd2009b0 | ||
|
|
46f075e891 | ||
|
|
832c381ac4 | ||
|
|
e021282264 | ||
|
|
2a60d385c6 | ||
|
|
4d37e35675 | ||
|
|
df3868a280 | ||
|
|
0799bb8cf1 | ||
|
|
69048dede4 | ||
|
|
76df6d1f43 | ||
|
|
2d03b21f2b | ||
|
|
62cbd44933 | ||
|
|
44c8f6d8b0 | ||
|
|
f3fc1dd59c | ||
|
|
708931e48b | ||
|
|
81800d2883 | ||
|
|
d0411d7ddf | ||
|
|
70e232cab3 | ||
|
|
f90396bda4 | ||
|
|
ae8808b86e | ||
|
|
8d5b827432 | ||
|
|
cb672697e7 | ||
|
|
0bae9fc29b | ||
|
|
49c8b68700 | ||
|
|
1e2fcd17e0 | ||
|
|
468b9d2655 | ||
|
|
a3305ff791 | ||
|
|
814b0d5873 |
54
.github/CONTRIBUTING.md
vendored
54
.github/CONTRIBUTING.md
vendored
@@ -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)
|
||||
4
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
4
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
@@ -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
|
||||
|
||||
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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. -->
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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 ..
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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: "スペースインベーダー アニバーサリー [筐体型コントローラ同梱セット]"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 '{}'.</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 '{}'.</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 '{}'.</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 '{2}'</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 '{}'.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct BreakPoint
|
||||
bool temporary = false;
|
||||
bool stepping = false;
|
||||
|
||||
bool hasCond;
|
||||
bool hasCond = false;
|
||||
BreakPointCond cond;
|
||||
BreakPointCpu cpu;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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...");
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)); }
|
||||
|
||||
Reference in New Issue
Block a user