Compare commits

...

20 Commits

Author SHA1 Message Date
lightningterror
db5384e19c GS/HW: Add hazard check for date depth buffer creation.
Add fallback to PrimIDTracking if possible.
2025-05-12 21:39:43 +02:00
lightningterror
fd3984287b GS/HW: Add hazard check for temporary depth buffer creation. 2025-05-12 21:39:43 +02:00
lightningterror
31dbea4e0b GS: Retry texture creation after initial retry fails.
This should've been done.
2025-05-12 21:39:43 +02:00
refractionpcsx2
0992e784f1 GS/HW: Tighten shuffle check on source lookup 2025-05-12 21:28:41 +02:00
refractionpcsx2
c59cc1fbb7 GS/TC: Kill partially dirty RT in RT targets which haven't been used recently 2025-05-12 21:28:41 +02:00
refractionpcsx2
903edc79f7 GS/TC: Alter RT in RT target lookup further and expand target on Move if needed 2025-05-12 21:28:41 +02:00
refractionpcsx2
4c94c69f02 GS: Clear Adaptive Interlacing buffer when outputs are disabled 2025-05-12 21:28:41 +02:00
refractionpcsx2
4c57c214bd GS/HW: Expand target to fix requested source rect when dirty covers area 2025-05-12 21:28:41 +02:00
refractionpcsx2
1cbeea3016 GS/HW: Fix up inside target lookup behaviour in HW renderer 2025-05-12 21:28:41 +02:00
PCSX2 Bot
0d18738192 [ci skip] PAD: Update to latest controller database. 2025-05-12 21:01:31 +02:00
JordanTheToaster
1e7c7db29b GameDB: Various Fixes Part 3 Because I Forgot More 2025-05-12 01:05:14 +02:00
PCSX2 Bot
7c098a2665 [ci skip] Qt: Update Base Translation. 2025-05-11 02:02:52 +02:00
Ty
3ab539be1e CDVD: Fix for non-PCH builds 2025-05-10 15:38:02 -04:00
Ty
b46d5e4efc CI: Disable PCH on Linux 2025-05-10 15:38:02 -04:00
Jordan
db06e11a7c GameDB: RT in RT Part Deux.
Adds fixes such as ATNWTO to around 104 games and adjusts the names of even more. Don't ask me what I fixed I don't even remember at this point.
2025-05-10 19:54:21 +02:00
KamFretoZ
757ed33e4f FSUI: Add ImDrawList helper for drawing SVG images
Co-Authored-By: TheLastRar <TheLastRar@users.noreply.github.com>
2025-05-10 19:53:04 +02:00
KamFretoZ
8eb5dfce85 Qt/FSUI: Update branding to the about section 2025-05-10 19:53:04 +02:00
PCSX2 Bot
f34db72a97 [ci skip] Qt: Update Base Translation. 2025-05-09 18:13:36 -04:00
chaoticgd
3dfdc8ee6f Debugger: Fix a typo in the memory search view 2025-05-08 22:16:38 +02:00
chaoticgd
5a846296ca Docs: Add even more missing third party licenses 2025-05-08 09:23:22 -04:00
19 changed files with 3058 additions and 2125 deletions

View File

@@ -140,9 +140,11 @@ jobs:
-DCMAKE_CXX_COMPILER=clang++-17 \
-DCMAKE_EXE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
-DCMAKE_MODULE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DENABLE_SETCAP=OFF \
-DDISABLE_ADVANCE_SIMD=TRUE \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
$ADDITIONAL_CMAKE_ARGS
- name: Build PCSX2

View File

@@ -4,7 +4,7 @@
<h1>Third-Party Licenses</h1>
<h2>Index</h2>
<h2>Table of Contents</h2>
<ul>
<li><a href="#pcsx2">PCSX2 - PS2 Emulator for PCs</a></li>
@@ -37,6 +37,7 @@
<li><a href="#llvm">LLVM</a></li>
<li><a href="#lz4">LZ4</a></li>
<li><a href="#lzmasdk">LZMA SDK</a></li>
<li><a href="#notosans">Noto Sans</a></li>
<li><a href="#pixevents">PixEvents</a></li>
<li><a href="#plutosvg">PlutoSVG</a></li>
<li><a href="#plutovg">PlutoVG</a></li>
@@ -45,6 +46,7 @@
<li><a href="#rapidjson">RapidJSON</a></li>
<li><a href="#rcheevos">rcheevos</a></li>
<li><a href="#remixicon">Remix Icon</a></li>
<li><a href="#roboto">Roboto</a></li>
<li><a href="#shaderc">Shaderc</a></li>
<li><a href="#simpleini">simpleini</a></li>
<li><a href="#soundtouch">SoundTouch audio processing library</a></li>
@@ -3636,6 +3638,105 @@ for any purpose, commercial or non-commercial, and by any means.
</pre>
</div>
<div id="notosans">
<h3>Noto Sans - <a href="https://notofonts.github.io/">https://notofonts.github.io/</a></h3>
<pre>
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/hebrew)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
&quot;Font Software&quot; refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
&quot;Reserved Font Name&quot; refers to any names specified as such after the
copyright statement(s).
&quot;Original Version&quot; refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
&quot;Modified Version&quot; refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
&quot;Author&quot; refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION &amp; CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
</pre>
</div>
<div id="pixevents">
<h3>PixEvents - <a href="https://github.com/microsoft/PixEvents">https://github.com/microsoft/PixEvents</a></h3>
<pre>
@@ -4149,6 +4250,105 @@ SOFTWARE.
</pre>
</div>
<div id="roboto">
<h3>Roboto - <a href="https://fonts.google.com/specimen/Roboto">https://fonts.google.com/specimen/Roboto</a></h3>
<pre>
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
&quot;Font Software&quot; refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
&quot;Reserved Font Name&quot; refers to any names specified as such after the
copyright statement(s).
&quot;Original Version&quot; refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
&quot;Modified Version&quot; refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
&quot;Author&quot; refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION &amp; CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
</pre>
</div>
<div id="shaderc">
<h3>Shaderc - <a href="https://github.com/google/shaderc">https://github.com/google/shaderc</a></h3>
<pre>

File diff suppressed because it is too large Load Diff

View File

@@ -1290,6 +1290,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
03000000ac0500007a05000011010000,GameSir G5,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000373500009710000001020000,GameSir Kaleid Flux,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,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2675 329.6"><g id="vectorized_by_maxihplay"><path id="_2" d="M2181.5,5.7h438.1c27.8,0,50.4,22.6,50.4,50.4v92.5c0,27.8-22.6,50.4-50.4,50.4h-309.5v46.5h359.9v78.6h-488.5v-145.3c0-27.8,22.6-50.4,50.4-50.4h309.5v-50.8h-315l-44.9-71.9h0Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><g id="X"><polygon points="1619.8 5.7 1769.1 5.7 1867.5 102 1961.6 5.9 2115.8 5.9 2115.8 77.2 2039.6 77.2 1954.7 164 2037.1 245.4 2115.8 245.4 2115.8 324.1 1968.4 324.1 1867.8 224 1767.8 324 1619.8 324 1619.8 244.8 1699.3 244.8 1779.3 165.8 1692.8 77.2 1619.8 77.2 1619.8 5.7" fill="#3caeff" stroke-width="0"/><path d="M1623.2,8.7l17.5,17.5v30.1h57c3.1,0,6,1.2,8.2,3.4l93.8,93.4c7.3,7.3,7.2,19.1-.1,26.3l-86,84.2c-3.1,3-7.3,4.8-11.7,4.8h-61.2l-18.5-21.5,77-2.1,80.1-79.1-86.5-88.5h-73V5.7l3.4,3h0Z" fill="#279ff5" stroke-width="0"/><path d="M1623.9,9.7l16.8,16.5h121.8l93.4,93.4c6.7,6.7,17.6,6.7,24.3,0l92.6-92.5h121.8l19.2-19.2-152.1-2-94.1,96.1-98.3-96.3-145.4,4h0Z" fill="#50b6ff" stroke-width="0"/><path d="M2114.7,247.9l-20.2,20.6h-62.1c-3.8,0-7.4-1.5-10-4.1l-85.5-85.5c-7.7-7.6-7.7-20.1,0-27.7l90-90c3.2-3.2,7.5-5,12-5h55.5v-29l20.3-19.9,1.2,70-76.1,1.4-85,85.5,82.4,81.3h78.8l-1.3,2.4Z" fill="#34a2f2" stroke-width="0"/><path d="M1619.8,323.5l1.7-77.8,19.2,22.7v34h115.6c1.1,0,2.1-.4,2.8-1.2l95.2-95.2c7.8-7.8,20.4-7.7,28.1.1l92.9,94.7c.7.7,1.7,1.2,2.8,1.2h116.9l-.5-33.5,22-24.5-.6,80.1h-147.4l-100.6-100.1-100.1,100.1-148-.6h0Z" fill="#43b9f2" stroke-width="0"/><polygon points="1619.8 5.7 1769.1 5.7 1867.5 102 1961.6 5.9 2115.8 5.9 2115.8 77.2 2039.6 77.2 1954.7 164 2037.1 245.4 2115.8 245.4 2115.8 324.1 1968.4 324.1 1867.8 224 1767.8 324 1619.8 324 1619.8 244.8 1699.3 244.8 1779.3 165.8 1692.8 77.2 1619.8 77.2 1619.8 5.7" fill="none" stroke="#5d73cb" stroke-miterlimit="10" stroke-width="11"/></g><path id="S" d="M1554.7,5.7h-434c-27.8,0-50.4,22.6-50.4,50.4v95.9c0,27.9,22.6,50.4,50.4,50.4h302.8v43.3h-353.2v78.4h434c27.8,0,50.4-22.6,50.4-50.4v-97.6c0-27.9-22.6-50.4-50.4-50.4h-303.9v-48.1h306.3l48-71.9Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><path id="C" d="M1008.1,5.1h-395.5c-27.8,0-50.4,22.6-50.4,50.4v217.9c0,28,22.7,50.8,50.8,50.8h385.2v-79.2h-304.3V78.2h263.3l50.9-73.1Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/><path id="P" d="M5,55.5C5,27.6,27.6,5,55.5,5h390.3c27.7,0,50.2,22.5,50.2,50.2v139.4c0,27.9-22.6,50.4-50.5,50.4l-284-.6,64.2-71.9h139.8v-95h-225.4v246.5H5V55.5Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="10" stroke-width="10"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>576</width>
<height>294</height>
<width>580</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
@@ -19,45 +19,42 @@
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="sizeType">
<enum>QSizePolicy::Policy::Preferred</enum>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="icon">
<property name="maximumSize">
<property name="minimumSize">
<size>
<width>260</width>
<height>260</height>
<width>1</width>
<height>1</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="resources/resources.qrc">:/icons/logo.png</pixmap>
<pixmap resource="resources/resources.qrc">:/icons/PCSX2logo.svg</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="sizeType">
<enum>QSizePolicy::Policy::Preferred</enum>
</property>
</spacer>
</item>
@@ -69,7 +66,7 @@
<string extracomment="SCM= Source Code Management">SCM Version</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
@@ -79,7 +76,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -89,23 +86,31 @@
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="disclaimer">
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -115,12 +120,15 @@
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -131,19 +139,22 @@
<string notr="true">TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -151,7 +162,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
<set>QDialogButtonBox::StandardButton::Close</set>
</property>
<property name="centerButtons">
<bool>true</bool>
@@ -162,7 +173,6 @@
</widget>
<resources>
<include location="resources/resources.qrc"/>
<include location="resources/icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -72,7 +72,7 @@
</item>
<item>
<property name="text">
<string>Array of byte</string>
<string>Byte Array</string>
</property>
</item>
</widget>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280.11 34.51"><g id="vectorized_by_maxihplay"><path id="_2" d="M228.43.6h45.87c2.91,0,5.28,2.37,5.28,5.28v9.69c0,2.91-2.37,5.28-5.28,5.28h-32.41v4.87h37.69v8.23h-51.15v-15.21c0-2.91,2.37-5.28,5.28-5.28h32.41v-5.32h-32.98l-4.7-7.53Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><g id="X"><polygon id="polygon1" points="221.55 25.7 221.55 33.94 206.12 33.94 195.58 23.46 185.11 33.93 169.61 33.93 169.61 25.63 177.94 25.63 186.32 17.36 177.26 8.08 169.61 8.08 169.61 .6 185.25 .6 195.55 10.68 205.41 .62 221.55 .62 221.55 8.08 213.57 8.08 204.68 17.17 213.31 25.7 221.55 25.7" fill="#3caeff" stroke-width="0"/><path id="path1" d="M169.97.91l1.83,1.83v3.15h5.97c.32,0,.63.13.86.36l9.82,9.78c.76.76.75,2-.01,2.75l-9.01,8.82c-.32.31-.76.5-1.23.5h-6.41l-1.94-2.25,8.06-.22,8.39-8.28-9.06-9.27h-7.64V.6l.36.31Z" fill="#279ff5" stroke-width="0"/><path id="path2" d="M170.04,1.02l1.76,1.73h12.75l9.78,9.78c.7.7,1.84.7,2.54,0l9.7-9.69h12.75l2.01-2.01-15.93-.21-9.85,10.06-10.29-10.08-15.23.42Z" fill="#50b6ff" stroke-width="0"/><path id="path3" d="M221.44,25.96l-2.12,2.16h-6.5c-.4,0-.77-.16-1.05-.43l-8.95-8.95c-.81-.8-.81-2.1,0-2.9l9.42-9.42c.34-.34.79-.52,1.26-.52h5.81v-3.04l2.13-2.08.13,7.33-7.97.15-8.9,8.95,8.63,8.51h8.25l-.14.25Z" fill="#34a2f2" stroke-width="0"/><path id="path4" d="M169.61,33.87l.18-8.15,2.01,2.38v3.56h12.1c.12,0,.22-.04.29-.13l9.97-9.97c.82-.82,2.14-.81,2.94.01l9.73,9.92c.07.07.18.13.29.13h12.24l-.05-3.51,2.3-2.57-.06,8.39h-15.43l-10.53-10.48-10.48,10.48-15.5-.06Z" fill="#43b9f2" stroke-width="0"/><polygon id="polygon4" points="221.55 25.7 221.55 33.94 206.12 33.94 195.58 23.46 185.11 33.93 169.61 33.93 169.61 25.63 177.94 25.63 186.32 17.36 177.26 8.08 169.61 8.08 169.61 .6 185.25 .6 195.55 10.68 205.41 .62 221.55 .62 221.55 8.08 213.57 8.08 204.68 17.17 213.31 25.7 221.55 25.7" fill="none" stroke="#5d73cb" stroke-miterlimit="1.05" stroke-width="1.15"/></g><path id="S" d="M162.8.6h-45.45c-2.91,0-5.28,2.37-5.28,5.28v10.04c0,2.92,2.37,5.28,5.28,5.28h31.71v4.53h-36.98v8.21h45.45c2.91,0,5.28-2.37,5.28-5.28v-10.22c0-2.92-2.37-5.28-5.28-5.28h-31.82v-5.04h32.07l5.03-7.53Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><path id="C" d="M105.56.53h-41.41c-2.91,0-5.28,2.37-5.28,5.28v22.82c0,2.93,2.38,5.32,5.32,5.32h40.34v-8.29h-31.86V8.19h27.57l5.33-7.65Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/><path id="P" d="M.52,5.81C.52,2.89,2.89.52,5.81.52h40.87c2.9,0,5.26,2.36,5.26,5.26v14.6c0,2.92-2.37,5.28-5.29,5.28l-29.74-.06,6.72-7.53h14.64v-9.95H14.67v25.81H.52V5.81Z" fill="#fff" stroke="#7a7a7a" stroke-miterlimit="1.05" stroke-width="1.05"/></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -103,7 +103,7 @@
<file>icons/black/svg/window-2-line.svg</file>
<file>icons/black/svg/zoom-in-line.svg</file>
<file>icons/black/svg/zoom-out-line.svg</file>
<file>icons/logo.png</file>
<file>icons/PCSX2logo.svg</file>
<file>icons/QT.png</file>
<file>icons/update.png</file>
<file>icons/white/index.theme</file>

View File

@@ -5,6 +5,7 @@
#include "common/Pcsx2Defs.h"
#include <array>
#include <string>
class Error;

View File

@@ -3996,8 +3996,14 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
// If it's the start of the texture and our little adjustment is all that pushed it over, clamp it to 0.
// This stops the border check failing when using repeat but needed less than the full texture
// since this was making it take the full texture even though it wasn't needed.
if (!clamp_to_tsize && ((m_vt.m_min.t.floor() == GSVector4::zero()).mask() & 0x3) == 0x3)
st = st.max(GSVector4::zero());
if (!clamp_to_tsize)
{
const u32 mask = (m_vt.m_min.t.floor() == GSVector4::zero()).mask();
if (mask & 1) // X == 0
st.x = st.max(GSVector4::zero()).x;
if (mask & 2) // Y == 0
st.y = st.max(GSVector4::zero()).y;
}
}
// draw will get scissored, adjust UVs to suit

View File

@@ -493,6 +493,7 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int width, int height, i
{
ERROR_LOG("GS: Memory allocation failure for {}x{} texture. Purging pool and retrying.", size.x, size.y);
PurgePool();
t = CreateSurface(type, size.x, size.y, levels, format);
if (!t)
{
ERROR_LOG("GS: Memory allocation failure for {}x{} texture after purging pool.", size.x, size.y);

View File

@@ -934,7 +934,8 @@ public:
__fi bool IsPresentThrottleAllowed() const { return m_allow_present_throttle; }
__fi GSTexture* GetCurrent() const { return m_current; }
__fi GSTexture* GetMAD() const { return m_mad; }
void Recycle(GSTexture* t);
/// Returns true if it's an OpenGL-based renderer.

View File

@@ -118,6 +118,18 @@ bool GSRenderer::Merge(int field)
if (!tex[0] && !tex[1])
{
m_real_size = GSVector2i(0, 0);
// Clear out the MAD buffer as some remnants of the previously shown frame came be left over, causing a flash for one frame.
if (GSConfig.InterlaceMode == GSInterlaceMode::Automatic || GSConfig.InterlaceMode >= GSInterlaceMode::AdaptiveTFF)
{
GSTexture* mad_tex = g_gs_device->GetMAD();
if (mad_tex)
{
g_gs_device->ClearRenderTarget(mad_tex, 0);
mad_tex = nullptr;
}
}
return false;
}

View File

@@ -2859,7 +2859,8 @@ void GSRendererHW::Draw()
if (!no_rt && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16 && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp >= 16 &&
(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)))
{
if (GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16)
// 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))
{
const GSVertex* v = &m_vertex.buff[0];
@@ -3351,6 +3352,7 @@ void GSRendererHW::Draw()
// 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))
{
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)
{
@@ -3372,19 +3374,24 @@ void GSRendererHW::Draw()
if (g_texture_cache->GetTemporaryZ() == nullptr)
{
m_temp_z_full_copy = false;
u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y);
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);
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 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);
GSTexture* tex = g_gs_device->CreateDepthStencil(ds->m_unscaled_size.x * ds->m_scale, new_height, GSTexture::Format::DepthStencil, true);
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);
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;
}
}
m_using_temp_z = true;
}
}
// Don't resize if the BPP don't match.
@@ -3686,7 +3693,7 @@ void GSRendererHW::Draw()
m_vt.m_min.t *= 0.5f;
m_vt.m_max.t *= 0.5f;
tmm = GetTextureMinMax(MIP_TEX0, MIP_CLAMP, m_vt.IsLinear(), false);
tmm = GetTextureMinMax(MIP_TEX0, MIP_CLAMP, m_vt.IsLinear(), true);
src->UpdateLayer(MIP_TEX0, tmm.coverage, layer - m_lod.x);
}
@@ -3881,7 +3888,7 @@ void GSRendererHW::Draw()
const bool new_rect = rt->m_valid.rempty();
const bool new_height = new_h > rt->GetUnscaledHeight();
const int old_height = rt->m_texture->GetHeight();
bool merge_targets = false;
pxAssert(rt->GetScale() == target_scale);
if (rt->GetUnscaledWidth() != new_w || rt->GetUnscaledHeight() != new_h)
GL_INS("HW: Resize RT from %dx%d to %dx%d", rt->GetUnscaledWidth(), rt->GetUnscaledHeight(), new_w, new_h);
@@ -3904,7 +3911,10 @@ void GSRendererHW::Draw()
g_texture_cache->AddDirtyRectTarget(rt, height_dirty_rect, rt->m_TEX0.PSM, rt->m_TEX0.TBW, mask);
}
}*/
if ((new_w > rt->m_unscaled_size.x || new_h > rt->m_unscaled_size.y) && GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets)
merge_targets = true;
rt->ResizeTexture(new_w, new_h);
if (!m_texture_shuffle && !m_channel_shuffle)
@@ -3935,6 +3945,8 @@ void GSRendererHW::Draw()
rt->UpdateValidity(update_rect, !frame_masked && (rt_update || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle)));
rt->UpdateDrawn(update_rect, !frame_masked && (rt_update || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle)));
if (merge_targets)
g_texture_cache->CombineAlignedInsideTargets(rt, src);
// Probably changing to double buffering, so invalidate any old target that was next to it.
// This resolves an issue where the PCRTC will find the old target in FMV's causing flashing.
// Grandia Xtreme, Onimusha Warlord.
@@ -3979,13 +3991,16 @@ void GSRendererHW::Draw()
if (z_width != new_w || z_height != new_h)
{
GSVector4i dRect = GSVector4i(0, 0, g_texture_cache->GetTemporaryZ()->GetWidth(), g_texture_cache->GetTemporaryZ()->GetHeight());
GSTexture* tex = g_gs_device->CreateDepthStencil(new_w * ds->m_scale, new_h * ds->m_scale, GSTexture::Format::DepthStencil, true);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), GSVector4(0.0f, 0.0f, 1.0f, 1.0f), tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
g_texture_cache->InvalidateTemporaryZ();
g_texture_cache->SetTemporaryZ(tex);
if (GSTexture* tex = g_gs_device->CreateDepthStencil(new_w * ds->m_scale, new_h * ds->m_scale, GSTexture::Format::DepthStencil, true))
{
const GSVector4i dRect = GSVector4i(0, 0, g_texture_cache->GetTemporaryZ()->GetWidth(), g_texture_cache->GetTemporaryZ()->GetHeight());
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), GSVector4(0.0f, 0.0f, 1.0f, 1.0f), tex, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
g_texture_cache->InvalidateTemporaryZ();
g_texture_cache->SetTemporaryZ(tex);
}
else
DevCon.Warning("HW: Temporary depth buffer creation failed.");
}
}
if (!m_texture_shuffle && !m_channel_shuffle)
@@ -6296,56 +6311,58 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
// Detect framebuffer read that will need special handling
const GSTextureCache::Target* src_target = nullptr;
if (rt && m_conf.tex == m_conf.rt && !(m_channel_shuffle && tex && (tex_diff != frame_diff || target_region)))
if (!m_downscale_source || !tex->m_from_target)
{
// Can we read the framebuffer directly? (i.e. sample location matches up).
if (CanUseTexIsFB(rt, tex, tmm))
if (rt && m_conf.tex == m_conf.rt && !(m_channel_shuffle && tex && (tex_diff != frame_diff || target_region)))
{
m_conf.tex = nullptr;
m_conf.ps.tex_is_fb = true;
if (m_prim_overlap == PRIM_OVERLAP_NO || !g_gs_device->Features().texture_barrier)
m_conf.require_one_barrier = true;
else
m_conf.require_full_barrier = true;
// Can we read the framebuffer directly? (i.e. sample location matches up).
if (CanUseTexIsFB(rt, tex, tmm))
{
m_conf.tex = nullptr;
m_conf.ps.tex_is_fb = true;
if (m_prim_overlap == PRIM_OVERLAP_NO || !g_gs_device->Features().texture_barrier)
m_conf.require_one_barrier = true;
else
m_conf.require_full_barrier = true;
unscaled_size = rt->GetUnscaledSize();
scale = rt->GetScale();
unscaled_size = rt->GetUnscaledSize();
scale = rt->GetScale();
return;
}
GL_CACHE("HW: Source is render target, taking copy.");
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)))
{
// GL, Vulkan (in General layout), not DirectX!
const bool can_read_current_depth_buffer = g_gs_device->Features().test_and_sample_depth;
// If this is our current Z buffer, we might not be able to read it directly if it's being written to.
// Rather than leaving the backend to do it, we'll check it here.
if (can_read_current_depth_buffer && (m_cached_ctx.ZBUF.ZMSK || m_cached_ctx.TEST.ZTST == ZTST_NEVER))
{
// Safe to read!
GL_CACHE("HW: Source is depth buffer, not writing, safe to read.");
unscaled_size = ds->GetUnscaledSize();
scale = ds->GetScale();
return;
}
// Can't safely read the depth buffer, so we need to take a copy of it.
GL_CACHE("HW: Source is depth buffer, unsafe to read, taking copy.");
src_target = ds;
}
else if (m_channel_shuffle && tex->m_from_target && tex_diff != frame_diff)
{
src_target = tex->m_from_target;
}
else
{
// No match.
return;
}
GL_CACHE("HW: Source is render target, taking copy.");
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)))
{
// GL, Vulkan (in General layout), not DirectX!
const bool can_read_current_depth_buffer = g_gs_device->Features().test_and_sample_depth;
// If this is our current Z buffer, we might not be able to read it directly if it's being written to.
// Rather than leaving the backend to do it, we'll check it here.
if (can_read_current_depth_buffer && (m_cached_ctx.ZBUF.ZMSK || m_cached_ctx.TEST.ZTST == ZTST_NEVER))
{
// Safe to read!
GL_CACHE("HW: Source is depth buffer, not writing, safe to read.");
unscaled_size = ds->GetUnscaledSize();
scale = ds->GetScale();
return;
}
// Can't safely read the depth buffer, so we need to take a copy of it.
GL_CACHE("HW: Source is depth buffer, unsafe to read, taking copy.");
src_target = ds;
}
else if (m_channel_shuffle && tex->m_from_target && tex_diff != frame_diff)
{
src_target = tex->m_from_target;
}
else if (!m_downscale_source || !tex->m_from_target)
{
// No match.
return;
}
else
src_target = tex->m_from_target;
@@ -7270,8 +7287,25 @@ __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)
{
temp_ds.reset(g_gs_device->CreateDepthStencil(m_conf.rt->GetWidth(), m_conf.rt->GetHeight(), GSTexture::Format::DepthStencil, false));
m_conf.ds = temp_ds.get();
const bool is_one_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();
}
else if (features.primitive_id && !(m_conf.ps.scanmsk & 2) && (!m_conf.require_full_barrier || is_one_barrier))
{
DATE_one = false;
DATE_PRIMID = true;
m_conf.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking;
DevCon.Warning("HW: Depth buffer creation failed for Stencil Date. Fallback to PrimIDTracking.");
}
else
{
DATE = false;
DATE_one = false;
m_conf.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Off;
DevCon.Warning("HW: Depth buffer creation failed for Stencil Date.");
}
}
// vs

View File

@@ -240,7 +240,7 @@ bool GSTextureCache::CanTranslate(u32 bp, u32 bw, u32 spsm, GSVector4i r, u32 db
const bool page_aligned_rect = masked_rect.xyxy().eq(r.xyxy());
const bool width_match = ((bw * 64) / src_page_size.x) == ((dbw * 64) / dst_page_size.x);
const bool sequential_pages = page_aligned_rect && r.x == 0 && r.z == src_pixel_width;
const bool single_row = (((bw * 64) / src_page_size.x) <= ((dbw * 64) / dst_page_size.x)) && r.z <= src_pixel_width && r.w <= src_page_size.y;
const bool single_row = (((bw * 64) / src_page_size.x) <= ((dbw * 64) / dst_page_size.x)) && r.width() <= src_pixel_width && r.height() <= src_page_size.y;
const bool single_page_aligned = page_aligned_rect && r.z <= src_page_size.x && r.w <= src_page_size.y;
if (block_layout_match)
{
@@ -1412,7 +1412,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
{
for (auto& dirty : t->m_dirty)
{
GSVector4i dirty_rect = dirty.GetDirtyRect(t->m_TEX0, t->m_TEX0.PSM != dirty.psm);
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;
@@ -1426,10 +1426,19 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const u32 channels = t->m_dirty.GetDirtyChannels() & channel_mask;
// If the source is reading the rt, make sure it's big enough.
if (!possible_shuffle && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && real_fmt_match)
if (!possible_shuffle && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM)&& real_fmt_match)
{
// Be careful if a new texture has been uploaded that expands the current one (Valkyrie Profile 2 does this)
GSVector4i dirty_rect = (t->m_dirty.size() > 0 && bw == t->m_TEX0.TBW) ? t->m_dirty.GetTotalRect(t->m_TEX0, GSVector2i(new_rect.z, new_rect.w)) : GSVector4i(GSVector4(t->m_valid) * GSVector4(2));
// Try to clamp the size of the target when using repeat, we don't want it getting too huge.
GSVector4i resize_rect = new_rect;
if (CLAMP.WMS == 0 || CLAMP.WMS == 3)
resize_rect.z = std::min(resize_rect.z, static_cast<int>(t->m_TEX0.TBW) * 64);
if ((CLAMP.WMT == 0 || CLAMP.WMT == 3) && resize_rect.w > (t->m_valid.w * 2))
resize_rect.w = std::min(resize_rect.w, std::max(t->m_valid.w * 2, dirty_rect.w));
if (t->Overlaps(bp, bw, psm, new_rect))
ResizeTarget(t, new_rect, bp, psm, bw);
ResizeTarget(t, resize_rect, bp, psm, bw);
}
// If not all channels are clean/dirty or only part of the rect is dirty, we need to update the target.
if (((channels & channel_mask) != channel_mask || partial))
@@ -1462,8 +1471,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
if (block_boundary_rect.w > t->m_valid.w)
AddDirtyRectTarget(t, GSVector4i(t->m_valid.x, t->m_valid.w, std::max(block_boundary_rect.z, t->m_valid.z), block_boundary_rect.w), t->m_TEX0.PSM, t->m_TEX0.TBW, rgba_mask);
}
// Try to clamp the size of the target when using repeat, we don't want it getting too huge.
GSVector4i resize_rect = req_rect;
if (CLAMP.WMS == 0 || CLAMP.WMS == 3)
resize_rect.z = std::min(resize_rect.z, static_cast<int>(t->m_TEX0.TBW) * 64);
if ((CLAMP.WMT == 0 || CLAMP.WMT == 3) && resize_rect.w > (t->m_valid.w * 2))
resize_rect.w = std::min(resize_rect.w, t->m_valid.w * 2);
// Resize including the extra pixel for bilinear.
ResizeTarget(t, req_rect, bp, psm, bw);
ResizeTarget(t, resize_rect, bp, psm, bw);
}
}
}
@@ -1633,6 +1650,10 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
{
u32 rt_tbw = std::max(1U, t->m_TEX0.TBW);
u32 horz_page_offset = ((bp - t->m_TEX0.TBP0) >> 5) % rt_tbw;
if (GSLocalMemory::m_psm[psm].bpp == GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp && bw != rt_tbw && block_boundary_rect.height() > GSLocalMemory::m_psm[psm].pgs.y)
continue;
if (GSLocalMemory::m_psm[color_psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32 && bw != 1 &&
((t->m_TEX0.TBW < (horz_page_offset + ((block_boundary_rect.z + GSLocalMemory::m_psm[psm].pgs.x - 1) / GSLocalMemory::m_psm[psm].pgs.x)) ||
(t->m_TEX0.TBW != bw && block_boundary_rect.w > GSLocalMemory::m_psm[psm].pgs.y))))
@@ -2089,14 +2110,19 @@ void GSTextureCache::CombineAlignedInsideTargets(Target* target, GSTextureCache:
if ((page_offset + page_width) <= target->m_TEX0.TBW)
{
const u32 vertical_offset = (((t->m_TEX0.TBP0 - target->m_TEX0.TBP0) >> 5) / std::max(1U, t->m_TEX0.TBW)) * t_psm.pgs.y;
const u32 horizontal_offset = page_offset * t_psm.pgs.x;
const GSVector4i target_drect_unscaled = t->m_valid + GSVector4i(horizontal_offset, vertical_offset).xyxy();
const GSVector4 target_drect = GSVector4(target_drect_unscaled) * target->m_scale;
if (t->m_last_draw > target->m_last_draw || t->m_valid.rintersect(target->m_valid).rempty())
{
t->Update();
const u32 vertical_offset = (((t->m_TEX0.TBP0 - target->m_TEX0.TBP0) >> 5) / std::max(1U, t->m_TEX0.TBW)) * t_psm.pgs.y;
const u32 horizontal_offset = page_offset * t_psm.pgs.x;
const GSVector4i target_drect_unscaled = t->m_valid + GSVector4i(horizontal_offset, vertical_offset).xyxy();
const GSVector4 target_drect = GSVector4(target_drect_unscaled) * target->m_scale;
const bool valid_color = t->m_valid_rgb;
const bool valid_alpha = (t->m_valid_alpha_high | t->m_valid_alpha_low) && (GSUtil::GetChannelMask(t->m_TEX0.PSM) & 0x8);
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1), target->m_texture, target_drect, valid_color, valid_color, valid_color, valid_alpha, (target->m_type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY);
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1), target->m_texture, target_drect, (target->m_type == RenderTarget) ? ShaderConvert::COPY : ShaderConvert::DEPTH_COPY, t->m_scale < target->m_scale);
target->UpdateValidity(target_drect_unscaled);
target->UpdateValidity(target_drect_unscaled);
}
if (src && src->m_from_target == t)
{
@@ -2252,10 +2278,12 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
const bool is_aligned_ok = widthpage_offset == 0 || ((min_rect.width() <= static_cast<int>((t->m_TEX0.TBW - widthpage_offset) * 64) && (t->m_TEX0.TBW == TEX0.TBW || TEX0.TBW == 1)) && bp >= t->m_TEX0.TBP0);
const bool no_target_or_newer = (!dst || ((GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw)));
const bool width_match = (t->m_TEX0.TBW == TEX0.TBW || (TEX0.TBW == 1 && draw_rect.w <= GSLocalMemory::m_psm[t->m_TEX0.PSM].pgs.y));
const bool ds_offset = !ds || offset != 0;
const bool is_double_buffer = TEX0.TBP0 == ((((t->m_end_block + 1) - t->m_TEX0.TBP0) / 2) + t->m_TEX0.TBP0);
// if it's a shuffle, some games tend to offset back by a page, such as Tomb Raider, for no disernable reason, but it then causes problems.
// This can also happen horizontally (Catwoman moves everything one page left with shuffles), but this is too messy to deal with right now.
const bool overlaps = t->Overlaps(bp, TEX0.TBW, TEX0.PSM, min_rect) || (is_shuffle && src && GSLocalMemory::m_psm[src->m_TEX0.PSM].bpp == 8 && t->Overlaps(bp, TEX0.TBW, TEX0.PSM, min_rect + GSVector4i(0, 0, 0, 32)));
if (no_target_or_newer && is_aligned_ok && width_match && overlaps)
if (no_target_or_newer && is_aligned_ok && width_match && overlaps && (is_shuffle || ds_offset || is_double_buffer))
{
const GSLocalMemory::psm_t& s_psm = GSLocalMemory::m_psm[TEX0.PSM];
@@ -2286,13 +2314,33 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
InvalidateSourcesFromTarget(t);
i = list.erase(i);
delete t;
continue;
}
else if (t->m_dirty.empty() || (t->m_TEX0.TBP0 <= bp && t->m_last_draw >= (GSState::s_n - 1) &&
t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(GSVector4i(0, 0, 0, 0).max_i32(TranslateAlignedRectByPage(t, TEX0.TBP0, TEX0.PSM, TEX0.TBW, min_rect))).rempty()))
GSVector4i lookup_rect = min_rect;
if (is_shuffle)
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 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 (TEX0.TBW == t->m_TEX0.TBW && !is_shuffle && widthpage_offset == 0 && ((min_rect.w + 63)/ 64) > 1)
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);
i = list.erase(i);
delete t;
continue;
}
if (!all_dirty && ((translated_rect.w <= t->m_valid.w) || widthpage_offset == 0 || (GSState::s_n - 1) == t->m_last_draw))
{
if (TEX0.TBW == t->m_TEX0.TBW && !is_shuffle && widthpage_offset == 0 && ((min_rect.w + 63) / 64) > 1)
{
// Beyond Good and Evil does this awful thing where it puts one framebuffer at 0xf00, with the first row of pages blanked out, and the whole thing goes down to 0x2080
// which is a problem, because it then puts the Z buffer at 0x1fc0, then offsets THAT by 1 row of pages, so it starts at, you guessed it, 2080.
@@ -3036,6 +3084,8 @@ GSTextureCache::Target* GSTextureCache::CreateTarget(GIFRegTEX0 TEX0, const GSVe
else
dst->m_last_draw += 1; // If we preload and it needs to decorrect and we couldn't catch it early, we need to make sure it decorrects the data.
CombineAlignedInsideTargets(dst, src);
pxAssert(dst && dst->m_texture && dst->m_scale == scale);
return dst;
}
@@ -3859,8 +3909,9 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
continue;
}
// If not fully contained, just dirty the area.
if (start_bp != t->m_TEX0.TBP0 && (t->m_TEX0.TBP0 < start_bp || t->UnwrappedEndBlock() > end_bp))
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 (write_bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[write_psm].bpp)
{
@@ -4599,6 +4650,9 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
dst = LookupTarget(new_TEX0, target_size, src->m_scale, src->m_type);
if (!dst)
dst = CreateTarget(new_TEX0, target_size, target_size, src->m_scale, src->m_type);
else // Expand if necessary (Silent hill 4 takes an old target which is smaller).
dst->ResizeTexture(std::max(dst->m_unscaled_size.x, target_size.x), std::max(dst->m_unscaled_size.y, target_size.y));
if (!dst)
return false;

View File

@@ -244,6 +244,7 @@ namespace FullscreenUI
void DrawSvgTexture(GSTexture* padded_texture, ImVec2 unpadded_size);
void DrawCachedSvgTexture(const std::string& path, ImVec2 size, SvgScaling mode);
void DrawCachedSvgTextureAsync(const std::string& path, ImVec2 size, SvgScaling mode);
void DrawListSvgTexture(ImDrawList* drawList, GSTexture* padded_texture, const ImVec2& p_min, const ImVec2& p_unpadded_max);
static MainWindowType s_current_main_window = MainWindowType::None;
static PauseSubMenu s_current_pause_submenu = PauseSubMenu::None;
@@ -269,6 +270,7 @@ namespace FullscreenUI
static std::array<std::shared_ptr<GSTexture>, static_cast<u32>(GameDatabaseSchema::Compatibility::Perfect)>
s_game_compatibility_textures;
static std::shared_ptr<GSTexture> s_banner_texture;
static std::shared_ptr<GSTexture> s_fallback_disc_texture;
static std::shared_ptr<GSTexture> s_fallback_exe_texture;
static std::vector<std::unique_ptr<GSTexture>> s_cleanup_textures;
@@ -715,6 +717,23 @@ void FullscreenUI::DrawCachedSvgTextureAsync(const std::string& path, ImVec2 siz
DrawSvgTexture(GetCachedSvgTextureAsync(path, size, mode), size);
}
// p_unpadded_max should be equal to p_min + unpadded_size
void FullscreenUI::DrawListSvgTexture(ImDrawList* drawList, GSTexture* padded_texture, const ImVec2& p_min, const ImVec2& p_unpadded_max)
{
const ImVec2 unpadded_size = p_unpadded_max - p_min;
if (padded_texture != GetPlaceholderTexture().get())
{
const ImVec2 padded_size(padded_texture->GetWidth(), padded_texture->GetHeight());
const ImVec2 uv1 = unpadded_size / padded_size;
drawList->AddImage(reinterpret_cast<ImTextureID>(padded_texture->GetNativeHandle()), p_min, p_unpadded_max, ImVec2(0.0f, 0.0f), uv1);
}
else
{
// Placeholder is a png file and should be scaled by ImGui
drawList->AddImage(reinterpret_cast<ImTextureID>(padded_texture->GetNativeHandle()), p_min, p_unpadded_max);
}
}
//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
@@ -1096,6 +1115,8 @@ bool FullscreenUI::LoadResources()
bool FullscreenUI::LoadSvgResources()
{
s_banner_texture = LoadSvgTexture("icons/AppBanner.svg", LayoutScale(500.0f, 76.0f), SvgScaling::Fit);
for (u32 i = static_cast<u32>(GameDatabaseSchema::Compatibility::Nothing);
i <= static_cast<u32>(GameDatabaseSchema::Compatibility::Perfect); i++)
{
@@ -1109,6 +1130,7 @@ void FullscreenUI::DestroyResources()
{
s_fallback_exe_texture.reset();
s_fallback_disc_texture.reset();
s_banner_texture.reset();
for (auto& tex : s_game_compatibility_textures)
tex.reset();
for (auto& tex : s_cleanup_textures)
@@ -7017,7 +7039,7 @@ void FullscreenUI::OpenAboutWindow()
void FullscreenUI::DrawAboutWindow()
{
ImGui::SetNextWindowSize(LayoutScale(1000.0f, 580.0f));
ImGui::SetNextWindowSize(LayoutScale(1000.0f, 600.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(FSUI_CSTR("About PCSX2"));
@@ -7027,21 +7049,24 @@ void FullscreenUI::DrawAboutWindow()
if (ImGui::BeginPopupModal(FSUI_CSTR("About PCSX2"), &s_about_window_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
{
const ImVec2 image_size = LayoutScale(500.0f, 76.0f);
const ImRect image_bb(ImGui::GetCursorScreenPos(), ImGui::GetCursorScreenPos() + ImVec2(ImGui::GetCurrentWindow()->WorkRect.GetWidth(), image_size.y));
const ImRect image_rect(CenterImage(image_bb, image_size));
DrawListSvgTexture(ImGui::GetWindowDrawList(), s_banner_texture.get(), image_rect.Min, image_rect.Max);
const float indent = image_size.y + LayoutScale(12.0f);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + indent);
ImGui::TextWrapped("%s", FSUI_CSTR(
"PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a "
"combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. "
"This allows you to play PS2 games on your PC, with many additional features and benefits."));
ImGui::NewLine();
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), BuildVersion::GitRev);
ImGui::NewLine();
ImGui::TextWrapped("%s",
FSUI_CSTR("PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not "
"affiliated in any way with Sony Interactive Entertainment."));
ImGui::NewLine();
BeginMenuButtons();
if (ActiveButton(FSUI_ICONSTR(ICON_FA_GLOBE, "Website"), false))
@@ -7068,6 +7093,10 @@ void FullscreenUI::DrawAboutWindow()
EndMenuButtons();
const float alignment = image_size.x + image_size.y;
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + alignment);
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), BuildVersion::GitRev);
ImGui::EndPopup();
}
@@ -7803,8 +7832,8 @@ TRANSLATE_NOOP("FullscreenUI", "Identifies any new files added to the game direc
TRANSLATE_NOOP("FullscreenUI", "Forces a full rescan of all games previously identified.");
TRANSLATE_NOOP("FullscreenUI", "About PCSX2");
TRANSLATE_NOOP("FullscreenUI", "PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.");
TRANSLATE_NOOP("FullscreenUI", "Version: %s");
TRANSLATE_NOOP("FullscreenUI", "PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.");
TRANSLATE_NOOP("FullscreenUI", "Version: %s");
TRANSLATE_NOOP("FullscreenUI", "When enabled and logged in, PCSX2 will scan for achievements on startup.");
TRANSLATE_NOOP("FullscreenUI", "\"Challenge\" mode for achievements, including leaderboard tracking. Disables save state, cheats, and slowdown functions.");
TRANSLATE_NOOP("FullscreenUI", "Displays popup messages on events such as achievement unlocks and leaderboard submissions.");