mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-31 11:18:41 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfc3d2e1d4 | ||
|
|
680affd1fe | ||
|
|
ab1d2009a0 | ||
|
|
8196f46721 | ||
|
|
44460365c0 | ||
|
|
38d9aa5e73 | ||
|
|
830db2b326 | ||
|
|
51165f6061 | ||
|
|
2a9d38048e | ||
|
|
bba65b8a82 | ||
|
|
884086ba76 | ||
|
|
1fa6614cd5 | ||
|
|
57581724cd | ||
|
|
0ae6f7efc5 | ||
|
|
d0346436fb | ||
|
|
1b28980454 | ||
|
|
90a6088d61 | ||
|
|
338a2beaf0 | ||
|
|
ff9a910c1a | ||
|
|
d88921bb58 | ||
|
|
c1f3f0a247 | ||
|
|
df847835ad | ||
|
|
8aad1c78af | ||
|
|
7c97cf4799 | ||
|
|
fd11523cf4 | ||
|
|
a293a9bd4b | ||
|
|
8de0eb3c06 | ||
|
|
8bff172f0b | ||
|
|
7f26595804 | ||
|
|
68ec70f24f | ||
|
|
836591a44f | ||
|
|
dd4ded3d4b | ||
|
|
995e294856 | ||
|
|
c4e623eec2 | ||
|
|
61253d8201 | ||
|
|
0f05967190 | ||
|
|
ad0e469f87 | ||
|
|
512d24cea6 | ||
|
|
0850a3fab7 | ||
|
|
16db92526c | ||
|
|
30ad66e8f1 | ||
|
|
77f600a16c | ||
|
|
d96bf7f951 | ||
|
|
15948c2781 | ||
|
|
b0c744bd29 | ||
|
|
5eacfe1afb | ||
|
|
2f985b479e | ||
|
|
e61d8f2f8f | ||
|
|
f4e338f9fb | ||
|
|
9509745be9 | ||
|
|
91b47134ad | ||
|
|
6426f4432e | ||
|
|
191ea50663 | ||
|
|
7f5c0fca8f | ||
|
|
5f8798cf94 | ||
|
|
3aac709682 | ||
|
|
e3962aa794 | ||
|
|
1964bbc03a | ||
|
|
80675399aa | ||
|
|
6fb4c724bd | ||
|
|
b34606c9ce | ||
|
|
4e97381709 | ||
|
|
d4db49f969 | ||
|
|
4b54870da1 | ||
|
|
0ae91cbf64 | ||
|
|
041abd8abc | ||
|
|
43be6883df | ||
|
|
ad4e95cb78 | ||
|
|
38480d3aed | ||
|
|
3436bb3792 | ||
|
|
5bab8af38f | ||
|
|
61f344dd66 | ||
|
|
1811955fce | ||
|
|
449da42108 | ||
|
|
9493d3e9c9 | ||
|
|
e5c1052062 | ||
|
|
7edc4e2cb3 | ||
|
|
7ca28fc796 | ||
|
|
72f9bf83fd | ||
|
|
2695ddc9fc | ||
|
|
fbcc8671ac | ||
|
|
7e76230cf8 | ||
|
|
ba27221bf2 | ||
|
|
6cf1501050 | ||
|
|
a30ca0ce2a | ||
|
|
5e3e988846 | ||
|
|
bb42353c81 | ||
|
|
61740fc9ed | ||
|
|
ea30c90a6c | ||
|
|
3968a82775 | ||
|
|
6e40081dd9 | ||
|
|
2b8b43c94c | ||
|
|
3f0ecc2284 | ||
|
|
828e86bdf4 | ||
|
|
159d0c060f | ||
|
|
4a29fdb3f2 | ||
|
|
29da1bb9ef | ||
|
|
47636bb30f | ||
|
|
5fe64396b4 | ||
|
|
75b782f261 | ||
|
|
4a5cf0efb9 | ||
|
|
cfdae77331 | ||
|
|
ec0aaff8ac | ||
|
|
f651d8e26a | ||
|
|
0526769808 | ||
|
|
1866745936 |
@@ -12,21 +12,22 @@ body:
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord.
|
||||
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
### Please Avoid Issues Pertaining to the Following:
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest)
|
||||
- We do **not** accept issues relating to **upscaling** at this time
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
|
||||
- Please try your game at native resolution before creating an issue
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
|
||||
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time.
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
|
||||
- We do **not** accept issues relating to **upscaling** at this time.
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
|
||||
- Please try your game at native resolution before creating an issue.
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
|
||||
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
|
||||
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
|
||||
-If PCSX2 crashed, please post crash logs and the .dmp file if appropiate.
|
||||
|
||||
- type: textarea
|
||||
id: desc
|
||||
|
||||
@@ -12,20 +12,20 @@ body:
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord.
|
||||
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
### Please Avoid Issues Pertaining to the Following:
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest)
|
||||
- We do **not** accept issues relating to **upscaling** at this time
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
|
||||
- Please try your game at native resolution before creating an issue
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
|
||||
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time.
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
|
||||
- We do **not** accept issues relating to **upscaling** at this time.
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
|
||||
- Please try your game at native resolution before creating an issue.
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
|
||||
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
|
||||
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
|
||||
|
||||
- type: textarea
|
||||
@@ -55,13 +55,13 @@ body:
|
||||
## System Info
|
||||
|
||||
Please make sure your system meets our requirements for OS version, CPU and GPU
|
||||
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements)
|
||||
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements).
|
||||
|
||||
Performance issues as a result of not meeting our hardware requirements are not valid
|
||||
Performance issues as a result of not meeting our hardware requirements are not valid.
|
||||
|
||||
Please read our known issues pages for AMD and Intel drivers.
|
||||
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know)
|
||||
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know)
|
||||
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know).
|
||||
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know).
|
||||
|
||||
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
|
||||
- type: input
|
||||
@@ -120,11 +120,11 @@ body:
|
||||
attributes:
|
||||
label: Emulation Settings
|
||||
description: |
|
||||
Any non-default core settings. If you don't want to list them out, please provide screenshots of your configuration window
|
||||
Any non-default core settings. If you don't want to list them out, please provide screenshots of your configuration window.
|
||||
|
||||
Please note that the safe preset works for most games. MTVU can have some compatibility issues so please disable it before making a report
|
||||
Please note that the safe preset works for most games. MTVU can have some compatibility issues so please disable it before making a report.
|
||||
|
||||
If you need to modify the settings manually because a game requires you to do so to work, please state that explicitly
|
||||
If you need to modify the settings manually because a game requires you to do so to work, please state that explicitly.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
@@ -139,8 +139,8 @@ body:
|
||||
attributes:
|
||||
label: "Logs & Dumps"
|
||||
description: |
|
||||
Please feel free to attach any logs, block dumps, GSdump, etc here
|
||||
|
||||
Please feel free to attach any logs, block dumps, GSdump, etc here.
|
||||
If PCSX2 crashed, please post crash logs and the .dmp file if appropiate.
|
||||
If your problem is graphical in nature it is highly recommended that you provide a GSdump. [GSdump Guide](https://forums.pcsx2.net/Thread-How-to-create-a-proper-GS-dump)
|
||||
validations:
|
||||
required: false
|
||||
|
||||
Vendored
+2
-7
@@ -33,14 +33,9 @@
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
|
||||
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\imconfig.h" />
|
||||
<ClInclude Include="include\imgui.h" />
|
||||
@@ -60,4 +55,4 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpgd", "3rdparty\jpgd\jpgd.
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{4639972E-424E-4E13-8B07-CA403C481346}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2core", "pcsx2\pcsx2core.vcxproj", "{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2", "pcsx2\pcsx2.vcxproj", "{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "3rdparty\glad\glad.vcxproj", "{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}"
|
||||
EndProject
|
||||
|
||||
+401
-185
File diff suppressed because it is too large
Load Diff
@@ -534,6 +534,7 @@
|
||||
030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
|
||||
030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
|
||||
030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,
|
||||
030000009b2800006200000000000000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||
030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
|
||||
@@ -868,7 +869,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000000d0f0000ee00000000010000,Horipad Mini 4,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:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000242e0000ff0b000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Mac OS X,
|
||||
03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,
|
||||
03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
||||
03000000830500006020000000000000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
||||
03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
|
||||
03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,
|
||||
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1212,7 +1213,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Linux,
|
||||
03000000242e00008816000001010000,Hyperkin X91,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,
|
||||
03000000f00300008d03000011010000,HyperX Clutch,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,
|
||||
03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,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:b0,y:b3,platform:Linux,
|
||||
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||
03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
|
||||
@@ -1512,6 +1513,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000008f0e00001431000010010000,SZMY Power PS3,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,
|
||||
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,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:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
|
||||
03000000790000001c18000011010000,TGZ Controller,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,
|
||||
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,leftshoulder:b4,rightshoulder:b5,x:b3,y:b0,start:b7,platform:Linux,
|
||||
030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||
030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||
@@ -1587,6 +1590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005e040000130b000015050000,Xbox Series 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,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
060000005e040000120b000007050000,Xbox Series 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,
|
||||
060000005e040000120b00000b050000,Xbox Series 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,
|
||||
060000005e040000120b00000f050000,Xbox Series 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,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000200b000013050000,Xbox Wireless 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,
|
||||
03000000450c00002043000010010000,XEOX SL6556 BK,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,
|
||||
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
||||
|
||||
@@ -118,8 +118,7 @@ if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
|
||||
elseif(NOT DEFINED ARCH_FLAG AND USE_CLANG_CL)
|
||||
set(ARCH_FLAG "-msse4.1")
|
||||
endif()
|
||||
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1)
|
||||
set(_ARCH_64 1)
|
||||
list(APPEND PCSX2_DEFS _M_X86=1)
|
||||
set(_M_X86 1)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
|
||||
@@ -136,12 +135,15 @@ option(USE_PGO_OPTIMIZE "Enable PGO optimization (use profile)")
|
||||
# Note1: Builtin strcmp/memcmp was proved to be slower on Mesa than stdlib version.
|
||||
# Note2: float operation SSE is impacted by the PCSX2 SSE configuration. In particular, flush to zero denormal.
|
||||
if(MSVC AND NOT USE_CLANG_CL)
|
||||
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
|
||||
add_compile_options(
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:/permissive->"
|
||||
"/Zo"
|
||||
"/utf-8"
|
||||
)
|
||||
elseif(NOT MSVC)
|
||||
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse)
|
||||
|
||||
# -fno-operator-names should only be for C++ files, not C files.
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-operator-names>)
|
||||
endif()
|
||||
|
||||
set(CONFIG_REL_NO_DEB $<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>>)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
T ByteSwap(T value)
|
||||
{
|
||||
if constexpr (std::is_signed_v<T>)
|
||||
{
|
||||
return static_cast<T>(ByteSwap(std::make_unsigned_t<T>(value)));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::uint16_t>)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ushort(value);
|
||||
#else
|
||||
return __builtin_bswap16(value);
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::uint32_t>)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ulong(value);
|
||||
#else
|
||||
return __builtin_bswap32(value);
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::uint64_t>)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_uint64(value);
|
||||
#else
|
||||
return __builtin_bswap64(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ target_sources(common PRIVATE
|
||||
AlignedMalloc.h
|
||||
Assertions.h
|
||||
boost_spsc_queue.hpp
|
||||
ByteSwap.h
|
||||
Console.h
|
||||
CrashHandler.h
|
||||
DynamicLibrary.h
|
||||
@@ -154,6 +155,10 @@ if(APPLE)
|
||||
)
|
||||
target_compile_options(common PRIVATE -fobjc-arc)
|
||||
target_link_options(common PRIVATE -fobjc-link-runtime)
|
||||
target_link_libraries(common PRIVATE
|
||||
"-framework Foundation"
|
||||
"-framework IOKit"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DBUS_API)
|
||||
|
||||
@@ -181,10 +181,6 @@ namespace Perf
|
||||
ml.method_size = static_cast<unsigned int>(size);
|
||||
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml);
|
||||
}
|
||||
#else
|
||||
static void RegisterMethod(const void* ptr, size_t size, const char* method)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) && (defined(ProfileWithPerf) || defined(ProfileWithPerfJitDump))) || defined(ENABLE_VTUNE)
|
||||
|
||||
+2
-8
@@ -100,10 +100,7 @@ namespace StringUtil
|
||||
return std::nullopt;
|
||||
|
||||
if (endptr)
|
||||
{
|
||||
const size_t remaining_len = end - ptr - 1;
|
||||
*endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view();
|
||||
}
|
||||
*endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view();
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -131,10 +128,7 @@ namespace StringUtil
|
||||
return std::nullopt;
|
||||
|
||||
if (endptr)
|
||||
{
|
||||
const size_t remaining_len = end - ptr - 1;
|
||||
*endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view();
|
||||
}
|
||||
*endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+3
-12
@@ -22,7 +22,7 @@
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="vsprops\CommonLibrary.props" />
|
||||
<Import Project="vsprops\3rdpartyDeps.props" />
|
||||
<Import Project="vsprops\common.props" />
|
||||
<Import Condition="$(Configuration.Contains(Debug))" Project="vsprops\CodeGen_Debug.props" />
|
||||
<Import Condition="$(Configuration.Contains(Devel))" Project="vsprops\CodeGen_Devel.props" />
|
||||
<Import Condition="$(Configuration.Contains(Release))" Project="vsprops\CodeGen_Release.props" />
|
||||
@@ -37,17 +37,10 @@
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\libpng</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\jpgd</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<ForcedIncludeFiles>PrecompiledHeader.h</ForcedIncludeFiles>
|
||||
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -111,6 +104,7 @@
|
||||
<ClInclude Include="Align.h" />
|
||||
<ClInclude Include="AlignedMalloc.h" />
|
||||
<ClInclude Include="BitCast.h" />
|
||||
<ClInclude Include="ByteSwap.h" />
|
||||
<ClInclude Include="CrashHandler.h" />
|
||||
<ClInclude Include="DynamicLibrary.h" />
|
||||
<ClInclude Include="Easing.h" />
|
||||
@@ -180,9 +174,6 @@
|
||||
<ClInclude Include="ZipHelpers.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\3rdparty\glad\glad.vcxproj">
|
||||
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdparty\jpgd\jpgd.vcxproj">
|
||||
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -351,6 +351,9 @@
|
||||
<ClInclude Include="FileSystem.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ByteSwap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<_PropertySheetDisplayName>Pcsx3rdpartyDependencies</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\;$(SolutionDir)3rdparty\soundtouch\soundtouch\;$(SolutionDir)3rdparty\rapidyaml\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\fmt\fmt\include\;$(SolutionDir)3rdparty\libchdr\libchdr\include;$(SolutionDir)3rdparty\wil\include;$(SolutionDir)3rdparty\Vulkan-Headers\include\;$(SolutionDir)3rdparty\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIL_SUPPRESS_EXCEPTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)deps\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,38 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<_PropertySheetDisplayName>PcsxBaseProperties</_PropertySheetDisplayName>
|
||||
<OutDir>$(SolutionDir)bin\$(PcsxSubsection)\</OutDir>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
|
||||
<ExtensionsToDeleteOnClean>*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
|
||||
<!-- Force ThinLTO for Release builds, MSVC doesn't seem to do it otherwise. -->
|
||||
<!-- Also due to include order, needs to be set here, rather than in CodeGen_Release.props -->
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Release))"> -flto=thin %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>"$(SolutionDir)common\vsprops\preBuild.cmd"</Command>
|
||||
</PreBuildEvent>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,22 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<OutDir>$(SolutionDir)deps\$(PlatformName)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<!-- This sucks. Need a better solution. -->
|
||||
<PreBuildEvent>
|
||||
<Command>"$(SolutionDir)common\vsprops\preBuild.cmd"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
+33
-29
@@ -1,10 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<ProjectRootDir>$(ProjectDir)\..\..</ProjectRootDir>
|
||||
<SvnRootDir>$(ProjectRootDir)\..</SvnRootDir>
|
||||
<SvnCommonDir>$(SvnRootDir)\common</SvnCommonDir>
|
||||
<PcsxSubsection />
|
||||
<SSEString />
|
||||
<SSEString Condition="$(Configuration.Contains(AVX2))">-avx2</SSEString>
|
||||
<ArchString />
|
||||
@@ -17,42 +13,50 @@
|
||||
<EXEString>$(ProjectName)$(ArchString)$(SSEString)$(ToolkitString)$(BuildString)</EXEString>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>./;$(ProjectDir);$(ProjectDir)x86;$(ProjectDir)x86\ix86-32;$(ProjectDir)IPU;$(ProjectDir)System;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_M_X86;TIXML_USE_STL;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pcsx2.pch</PrecompiledHeaderOutputFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
|
||||
<!-- SH 2/3 flashlight, explicitly set here don't change -->
|
||||
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
|
||||
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
|
||||
<PreprocessorDefinitions>_M_X86;__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="!$(Configuration.Contains(Clang))">%(AdditionalOptions) /Zc:externConstexpr /Zc:__cplusplus /Zo /utf-8</AdditionalOptions>
|
||||
|
||||
<!-- Force ThinLTO for Release builds, MSVC doesn't seem to do it otherwise. -->
|
||||
<!-- Also due to include order, needs to be set here, rather than in CodeGen_Release.props -->
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Release))"> -flto=thin %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\;..\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<BuildMacro Include="ProjectRootDir">
|
||||
<Value>$(ProjectRootDir)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="SvnRootDir">
|
||||
<Value>$(SvnRootDir)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="SvnCommonDir">
|
||||
<Value>$(SvnCommonDir)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="PcsxSubsection">
|
||||
<Value>$(PcsxSubsection)</Value>
|
||||
</BuildMacro>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<PcsxSubsection>plugins</PcsxSubsection>
|
||||
<ProjectRootDir>$(ProjectDir)..</ProjectRootDir>
|
||||
<SvnRootDir>$(ProjectRootDir)\..\..\..</SvnRootDir>
|
||||
<SvnCommonDir>$(SvnRootDir)\common</SvnCommonDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
|
||||
<_PropertySheetDisplayName>PluginSvnRoot</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)\..\3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<BuildMacro Include="PcsxSubsection">
|
||||
<Value>$(PcsxSubsection)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="ProjectRootDir">
|
||||
<Value>$(ProjectRootDir)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="SvnRootDir">
|
||||
<Value>$(SvnRootDir)</Value>
|
||||
</BuildMacro>
|
||||
<BuildMacro Include="SvnCommonDir">
|
||||
<Value>$(SvnCommonDir)</Value>
|
||||
</BuildMacro>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+13
-26
@@ -37,25 +37,20 @@
|
||||
|
||||
#include "pcsx2/PrecompiledHeader.h"
|
||||
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/Frontend/CommonHost.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/Frontend/LogSink.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/ImGui/ImGuiManager.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/LogSink.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
#include "pcsx2/Frontend/Achievements.h"
|
||||
#endif
|
||||
|
||||
#include "svnrev.h"
|
||||
|
||||
namespace GSRunner
|
||||
@@ -87,14 +82,14 @@ static u32 s_loop_number = s_loop_count;
|
||||
|
||||
bool GSRunner::InitializeConfig()
|
||||
{
|
||||
if (!CommonHost::InitializeCriticalFolders())
|
||||
if (!EmuFolders::InitializeCriticalFolders())
|
||||
return false;
|
||||
|
||||
// don't provide an ini path, or bother loading. we'll store everything in memory.
|
||||
MemorySettingsInterface& si = s_settings_interface;
|
||||
Host::Internal::SetBaseSettingsLayer(&si);
|
||||
|
||||
CommonHost::SetDefaultSettings(si, true, true, true, true, true);
|
||||
VMManager::SetDefaultSettings(si, true, true, true, true, true);
|
||||
|
||||
// complete as quickly as possible
|
||||
si.SetBoolValue("EmuCore/GS", "FrameLimitEnable", false);
|
||||
@@ -131,7 +126,7 @@ bool GSRunner::InitializeConfig()
|
||||
si.SetStringValue("MemoryCards", fmt::format("Slot{}_Filename", i + 1).c_str(), "");
|
||||
}
|
||||
|
||||
CommonHost::LoadStartupSettings();
|
||||
VMManager::Internal::LoadStartupSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,12 +137,10 @@ void Host::CommitBaseSettingChanges()
|
||||
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
}
|
||||
|
||||
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_config);
|
||||
}
|
||||
|
||||
bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool hotkeys, bool ui)
|
||||
@@ -414,7 +407,7 @@ void GSRunner::InitializeConsole()
|
||||
const char* var = std::getenv("PCSX2_NOCONSOLE");
|
||||
s_no_console = (var && StringUtil::FromChars<bool>(var).value_or(false));
|
||||
if (!s_no_console)
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
LogSink::InitializeEarlyConsole();
|
||||
}
|
||||
|
||||
bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& params)
|
||||
@@ -540,7 +533,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
||||
{
|
||||
// disable timestamps, since we want to be able to diff the logs
|
||||
Console.WriteLn("Logging to %s...", logfile);
|
||||
CommonHost::SetFileLogPath(logfile);
|
||||
LogSink::SetFileLogPath(logfile);
|
||||
s_settings_interface.SetBoolValue("Logging", "EnableFileLogging", true);
|
||||
s_settings_interface.SetBoolValue("Logging", "EnableTimestamps", false);
|
||||
}
|
||||
@@ -626,12 +619,8 @@ int main(int argc, char* argv[])
|
||||
if (!GSRunner::ParseCommandLineArgs(argc, argv, params))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
|
||||
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
|
||||
{
|
||||
Console.Error("Failed to allocate globals/memory.");
|
||||
if (!VMManager::Internal::CPUThreadInitialize())
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (s_use_window.value_or(true) && !GSRunner::CreatePlatformWindow())
|
||||
{
|
||||
@@ -653,16 +642,14 @@ int main(int argc, char* argv[])
|
||||
VMManager::Shutdown(false);
|
||||
}
|
||||
|
||||
InputManager::CloseSources();
|
||||
VMManager::Internal::ReleaseMemory();
|
||||
VMManager::Internal::ReleaseGlobals();
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
GSRunner::DestroyPlatformWindow();
|
||||
LogSink::CloseFileLog();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void Host::CPUThreadVSync()
|
||||
void Host::VSyncOnCPUThread()
|
||||
{
|
||||
// update GS thread copy of frame number
|
||||
GetMTGS().RunOnGSThread([frame_number = GSDumpReplayer::GetFrameNumber()]() { s_dump_frame_number = frame_number; });
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(SolutionDir)common\vsprops\common.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProperties.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\3rdpartyDeps.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\GenerateSCMVersion.props" />
|
||||
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
|
||||
<Import Condition="$(Configuration.Contains(Devel))" Project="$(SolutionDir)common\vsprops\CodeGen_Devel.props" />
|
||||
<Import Condition="$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\CodeGen_Release.props" />
|
||||
@@ -34,84 +34,28 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\freetype\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xz\xz\src\liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\simpleini\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)pcsx2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<!-- Needed for moc pch -->
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(ProjectDir)\Settings;$(ProjectDir)\GameList</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\simpleini\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)pcsx2</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;DIRECTINPUT_VERSION=0x0800;PCSX2_CORE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<!-- SH 2/3 flashlight, explicitly set here don't change -->
|
||||
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalOptions>/Zc:__cplusplus /Zo /utf-8%(AdditionalOptions)</AdditionalOptions>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<LargeAddressAware>Yes</LargeAddressAware>
|
||||
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\fmt\fmt.vcxproj">
|
||||
<Project>{449ad25e-424a-4714-babc-68706cdcc33b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libjpeg\libjpeg.vcxproj">
|
||||
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj">
|
||||
<Project>{d6973076-9317-4ef2-a0b8-b7a18ac0713e}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
|
||||
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
|
||||
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libchdr\libchdr.vcxproj">
|
||||
<Project>{a0d2b3ad-1f72-4ee3-8b5c-f2c358da35f0}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\zlib\zlib.vcxproj">
|
||||
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
|
||||
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\imgui\imgui.vcxproj">
|
||||
<Project>{88fb34ec-845e-4f21-a552-f1573b9ed167}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)common\common.vcxproj">
|
||||
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2core.vcxproj">
|
||||
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2.vcxproj">
|
||||
<Project>{6c7986c4-3e4d-4dcc-b3c6-6bb12b238995}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
|
||||
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/SysForwardDefs.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include "CoverDownloadDialog.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
|
||||
CoverDownloadDialog::CoverDownloadDialog(QWidget* parent /*= nullptr*/)
|
||||
: QDialog(parent)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,16 +15,15 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
|
||||
#include "DisplayWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
|
||||
#include "pcsx2/ImGui/ImGuiManager.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,8 +14,11 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
|
||||
#include "common/LRUCache.h"
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,11 +15,12 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GameListRefreshThread.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
|
||||
#include "common/ProgressCallback.h"
|
||||
#include "common/Timer.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include "GameListRefreshThread.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
@@ -64,7 +65,9 @@ void AsyncRefreshProgressCallback::SetProgressValue(u32 value)
|
||||
fireUpdate();
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::SetTitle(const char* title) {}
|
||||
void AsyncRefreshProgressCallback::SetTitle(const char* title)
|
||||
{
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::DisplayError(const char* message)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,11 +15,19 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GameListModel.h"
|
||||
#include "GameListRefreshThread.h"
|
||||
#include "GameListWidget.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <QtCore/QSortFilterProxyModel>
|
||||
#include <QtGui/QPixmap>
|
||||
@@ -29,16 +37,9 @@
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
|
||||
#include "GameListModel.h"
|
||||
#include "GameListRefreshThread.h"
|
||||
#include "GameListWidget.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
static const char* SUPPORTED_FORMATS_STRING = QT_TRANSLATE_NOOP(GameListWidget,
|
||||
".bin/.iso (ISO Disc Images)\n"
|
||||
".mdf (Media Descriptor File)\n"
|
||||
".chd (Compressed Hunks of Data)\n"
|
||||
".cso (Compressed ISO)\n"
|
||||
".gz (Gzip Compressed ISO)");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,9 +14,12 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include "ui_EmptyGameListWidget.h"
|
||||
#include "ui_GameListWidget.h"
|
||||
|
||||
#include "pcsx2/GameList.h"
|
||||
|
||||
#include <QtWidgets/QListView>
|
||||
#include <QtWidgets/QTableView>
|
||||
|
||||
|
||||
+32
-33
@@ -15,31 +15,6 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QProgressBar>
|
||||
#include <QtWidgets/QStyle>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
#include "pcsx2/CDVD/CDVDdiscReader.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/LogSink.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/Recording/InputRecording.h"
|
||||
#include "pcsx2/Recording/InputRecordingControls.h"
|
||||
|
||||
#include "AboutDialog.h"
|
||||
#include "AutoUpdaterDialog.h"
|
||||
#include "CoverDownloadDialog.h"
|
||||
@@ -49,27 +24,50 @@
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/GameListSettingsWidget.h"
|
||||
#include "Settings/InterfaceSettingsWidget.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "svnrev.h"
|
||||
#include "Tools/InputRecording/InputRecordingViewer.h"
|
||||
#include "Tools/InputRecording/NewInputRecordingDlg.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
#include "pcsx2/CDVD/CDVDdiscReader.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/LogSink.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/Recording/InputRecording.h"
|
||||
#include "pcsx2/Recording/InputRecordingControls.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QProgressBar>
|
||||
#include <QtWidgets/QStyle>
|
||||
#include <QtWidgets/QStyleFactory>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include <Dbt.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
#include "pcsx2/Frontend/Achievements.h"
|
||||
#endif
|
||||
|
||||
const char* MainWindow::OPEN_FILE_FILTER =
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.elf *.irx *.gs *.gs.xz *.gs.zst *.dump);;"
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.gz *.elf *.irx *.gs *.gs.xz *.gs.zst *.dump);;"
|
||||
"Single-Track Raw Images (*.bin *.iso);;"
|
||||
"Cue Sheets (*.cue);;"
|
||||
"Media Descriptor File (*.mdf);;"
|
||||
"MAME CHD Images (*.chd);;"
|
||||
"CSO Images (*.cso);;"
|
||||
"GZ Images (*.gz);;"
|
||||
@@ -78,9 +76,10 @@ const char* MainWindow::OPEN_FILE_FILTER =
|
||||
"GS Dumps (*.gs *.gs.xz *.gs.zst);;"
|
||||
"Block Dumps (*.dump)");
|
||||
|
||||
const char* MainWindow::DISC_IMAGE_FILTER = QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.dump);;"
|
||||
const char* MainWindow::DISC_IMAGE_FILTER = QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.gz *.dump);;"
|
||||
"Single-Track Raw Images (*.bin *.iso);;"
|
||||
"Cue Sheets (*.cue);;"
|
||||
"Media Descriptor File (*.mdf);;"
|
||||
"MAME CHD Images (*.chd);;"
|
||||
"CSO Images (*.cso);;"
|
||||
"GZ Images (*.gz);;"
|
||||
|
||||
+53
-62
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,8 +15,32 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
#include "AutoUpdaterDialog.h"
|
||||
#include "DisplayWidget.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/Counters.h"
|
||||
#include "pcsx2/DebugTools/Debug.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/ImGui/FullscreenUI.h"
|
||||
#include "pcsx2/ImGui/ImGuiManager.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/LogSink.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
@@ -28,25 +52,6 @@
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Timer.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
#include "pcsx2/Counters.h"
|
||||
#include "pcsx2/DebugTools/Debug.h"
|
||||
#include "pcsx2/Frontend/CommonHost.h"
|
||||
#include "pcsx2/Frontend/FullscreenUI.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/Frontend/LogSink.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
@@ -55,17 +60,8 @@
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include "AutoUpdaterDialog.h"
|
||||
#include "DisplayWidget.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
#include "Frontend/Achievements.h"
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
|
||||
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
||||
|
||||
@@ -120,6 +116,7 @@ void EmuThread::start()
|
||||
pxAssertRel(!g_emu_thread, "Emu thread does not exist");
|
||||
|
||||
g_emu_thread = new EmuThread(QThread::currentThread());
|
||||
g_emu_thread->setStackSize(VMManager::EMU_THREAD_STACK_SIZE);
|
||||
g_emu_thread->QThread::start();
|
||||
g_emu_thread->m_started_semaphore.acquire();
|
||||
g_emu_thread->moveToThread(g_emu_thread);
|
||||
@@ -374,7 +371,12 @@ void EmuThread::run()
|
||||
connectSignals();
|
||||
|
||||
// Common host initialization (VM setup, etc).
|
||||
CommonHost::CPUThreadInitialize();
|
||||
if (!VMManager::Internal::CPUThreadInitialize())
|
||||
{
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
QMetaObject::invokeMethod(qApp, &QCoreApplication::quit, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start background polling because the VM won't do it for us.
|
||||
createBackgroundControllerPollTimer();
|
||||
@@ -395,7 +397,7 @@ void EmuThread::run()
|
||||
// Teardown in reverse order.
|
||||
stopBackgroundControllerPollTimer();
|
||||
destroyBackgroundControllerPollTimer();
|
||||
CommonHost::CPUThreadShutdown();
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
|
||||
// Move back to the UI thread, since we're no longer running.
|
||||
moveToThread(m_ui_thread);
|
||||
@@ -569,7 +571,7 @@ void EmuThread::updateEmuFolders()
|
||||
return;
|
||||
}
|
||||
|
||||
Host::Internal::UpdateEmuFolders();
|
||||
VMManager::Internal::UpdateEmuFolders();
|
||||
}
|
||||
|
||||
void EmuThread::connectSignals()
|
||||
@@ -585,7 +587,6 @@ void EmuThread::loadSettings(SettingsInterface& si, std::unique_lock<std::mutex>
|
||||
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
g_emu_thread->loadSettings(si, lock);
|
||||
}
|
||||
|
||||
@@ -609,7 +610,6 @@ void EmuThread::checkForSettingChanges(const Pcsx2Config& old_config)
|
||||
|
||||
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_config);
|
||||
g_emu_thread->checkForSettingChanges(old_config);
|
||||
}
|
||||
|
||||
@@ -931,35 +931,29 @@ void Host::RequestResizeHostDisplay(s32 width, s32 height)
|
||||
|
||||
void Host::OnVMStarting()
|
||||
{
|
||||
CommonHost::OnVMStarting();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMStarting();
|
||||
}
|
||||
|
||||
void Host::OnVMStarted()
|
||||
{
|
||||
CommonHost::OnVMStarted();
|
||||
emit g_emu_thread->onVMStarted();
|
||||
}
|
||||
|
||||
void Host::OnVMDestroyed()
|
||||
{
|
||||
CommonHost::OnVMDestroyed();
|
||||
emit g_emu_thread->onVMStopped();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
}
|
||||
|
||||
void Host::OnVMPaused()
|
||||
{
|
||||
CommonHost::OnVMPaused();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMPaused();
|
||||
}
|
||||
|
||||
void Host::OnVMResumed()
|
||||
{
|
||||
CommonHost::OnVMResumed();
|
||||
|
||||
// exit the event loop when we eventually return
|
||||
g_emu_thread->getEventLoop()->quit();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
@@ -974,7 +968,6 @@ void Host::OnVMResumed()
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
|
||||
const std::string& game_name, u32 game_crc)
|
||||
{
|
||||
CommonHost::OnGameChanged(disc_path, elf_override, game_serial, game_name, game_crc);
|
||||
emit g_emu_thread->onGameChanged(QString::fromStdString(disc_path), QString::fromStdString(elf_override),
|
||||
QString::fromStdString(game_serial), QString::fromStdString(game_name), game_crc);
|
||||
}
|
||||
@@ -1121,10 +1114,9 @@ void Host::OnAchievementsRefreshed()
|
||||
}
|
||||
#endif
|
||||
|
||||
void Host::CPUThreadVSync()
|
||||
void Host::VSyncOnCPUThread()
|
||||
{
|
||||
g_emu_thread->getEventLoop()->processEvents(QEventLoop::AllEvents);
|
||||
CommonHost::CPUThreadVSync();
|
||||
}
|
||||
|
||||
void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false */)
|
||||
@@ -1200,19 +1192,22 @@ SysMtgsThread& GetMTGS()
|
||||
|
||||
bool QtHost::InitializeConfig()
|
||||
{
|
||||
if (!CommonHost::InitializeCriticalFolders())
|
||||
if (!EmuFolders::InitializeCriticalFolders())
|
||||
{
|
||||
QMessageBox::critical(nullptr, QStringLiteral("PCSX2"),
|
||||
QStringLiteral("One or more critical directories are missing, your installation may be incomplete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write crash dumps to the data directory, since that'll be accessible for certain.
|
||||
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
|
||||
|
||||
const std::string path(Path::Combine(EmuFolders::Settings, "PCSX2.ini"));
|
||||
Console.WriteLn("Loading config from %s.", path.c_str());
|
||||
|
||||
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(path));
|
||||
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
|
||||
if (!s_base_settings_interface->Load() || !CommonHost::CheckSettingsVersion())
|
||||
if (!s_base_settings_interface->Load() || !VMManager::Internal::CheckSettingsVersion())
|
||||
{
|
||||
// If the config file doesn't exist, assume this is a new install and don't prompt to overwrite.
|
||||
if (FileSystem::FileExists(s_base_settings_interface->GetFileName().c_str()) &&
|
||||
@@ -1223,12 +1218,12 @@ bool QtHost::InitializeConfig()
|
||||
return false;
|
||||
}
|
||||
|
||||
CommonHost::SetDefaultSettings(*s_base_settings_interface, true, true, true, true, true);
|
||||
VMManager::SetDefaultSettings(*s_base_settings_interface, true, true, true, true, true);
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
CommonHost::SetBlockSystemConsole(QtHost::InNoGUIMode());
|
||||
CommonHost::LoadStartupSettings();
|
||||
LogSink::SetBlockSystemConsole(QtHost::InNoGUIMode());
|
||||
VMManager::Internal::LoadStartupSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1311,7 +1306,7 @@ bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool
|
||||
{
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
CommonHost::SetDefaultSettings(*s_base_settings_interface.get(), folders, core, controllers, hotkeys, ui);
|
||||
VMManager::SetDefaultSettings(*s_base_settings_interface.get(), folders, core, controllers, hotkeys, ui);
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
|
||||
@@ -1516,7 +1511,7 @@ void QtHost::HookSignals()
|
||||
|
||||
void QtHost::PrintCommandLineVersion()
|
||||
{
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
LogSink::InitializeEarlyConsole();
|
||||
std::fprintf(stderr, "%s\n", (GetAppNameAndVersion() + GetAppConfigSuffix()).toUtf8().constData());
|
||||
std::fprintf(stderr, "https://pcsx2.net/\n");
|
||||
std::fprintf(stderr, "\n");
|
||||
@@ -1632,7 +1627,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
|
||||
}
|
||||
else if (CHECK_ARG_PARAM(QStringLiteral("-logfile")))
|
||||
{
|
||||
CommonHost::SetFileLogPath((++it)->toStdString());
|
||||
LogSink::SetFileLogPath((++it)->toStdString());
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG(QStringLiteral("-bios")))
|
||||
@@ -1653,7 +1648,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
|
||||
}
|
||||
else if (CHECK_ARG(QStringLiteral("-earlyconsolelog")))
|
||||
{
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
LogSink::InitializeEarlyConsole();
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG(QStringLiteral("-bigpicture")))
|
||||
@@ -1710,7 +1705,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
|
||||
// or disc, we don't want to actually start.
|
||||
if (autoboot && !autoboot->source_type.has_value() && autoboot->filename.empty() && autoboot->elf_override.empty())
|
||||
{
|
||||
CommonHost::InitializeEarlyConsole();
|
||||
LogSink::InitializeEarlyConsole();
|
||||
Console.Warning("Skipping autoboot due to no boot parameters.");
|
||||
autoboot.reset();
|
||||
}
|
||||
@@ -1843,11 +1838,7 @@ int main(int argc, char* argv[])
|
||||
s_base_settings_interface->Save();
|
||||
|
||||
// Ensure emulog is flushed.
|
||||
if (emuLog)
|
||||
{
|
||||
std::fclose(emuLog);
|
||||
emuLog = nullptr;
|
||||
}
|
||||
LogSink::CloseFileLog();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -21,8 +21,7 @@
|
||||
#include <optional>
|
||||
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "common/Path.h"
|
||||
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,9 +14,12 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "AchievementLoginDialog.h"
|
||||
#include "pcsx2/Frontend/Achievements.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
#include "pcsx2/Achievements.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -22,8 +22,8 @@
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/Frontend/Achievements.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.palFrameRate, "EmuCore/GS", "FrameratePAL", 50.00f);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pineEnable, "EmuCore", "EnablePINE", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.pineSlot, "EmuCore", "PINESlot", 28011);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.eeRoundingMode, tr("Rounding Mode"), tr("Chop / Zero (Default)"), tr(""));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.eeClampMode, tr("Clamping Mode"), tr("Normal (Default)"), tr(""));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>809</width>
|
||||
<height>647</height>
|
||||
<height>725</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -37,7 +37,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>807</width>
|
||||
<height>645</height>
|
||||
<height>723</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -417,6 +417,45 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>PINE Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="pineSlot">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Slot:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="pineEnable">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <algorithm>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/ps2/BiosTools.h"
|
||||
|
||||
#include "BIOSSettingsWidget.h"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
#include "Settings/ControllerBindingWidgets.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,15 +15,16 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Settings/ControllerGlobalSettingsWidget.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/ControllerSettingWidgetBinder.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
|
||||
#ifdef SDL_BUILD
|
||||
#include "pcsx2/Frontend/SDLInputSource.h"
|
||||
#include "pcsx2/Input/SDLInputSource.h"
|
||||
#endif
|
||||
|
||||
ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,6 +15,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "QtHost.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -27,11 +32,6 @@
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
|
||||
#include "QtHost.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
/// This nastyness is required because input profiles aren't overlaid settings like the rest of them, it's
|
||||
/// input profile *or* global, not both.
|
||||
namespace ControllerSettingWidgetBinder
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "Settings/ControllerBindingWidgets.h"
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
|
||||
#include "pcsx2/Frontend/CommonHost.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/Sio.h"
|
||||
@@ -208,7 +207,7 @@ void ControllerSettingsDialog::onRestoreDefaultsClicked()
|
||||
// actually restore it
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
CommonHost::SetDefaultSettings(*Host::Internal::GetBaseSettingsLayer(), false, false, true, true, false);
|
||||
VMManager::SetDefaultSettings(*Host::Internal::GetBaseSettingsLayer(), false, false, true, true, false);
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,8 +15,10 @@
|
||||
|
||||
#pragma once
|
||||
#include "ui_ControllerSettingsDialog.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/USB/USB.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QString>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
||||
#include "DEV9SettingsWidget.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -19,9 +19,10 @@
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
DebugSettingsWidget::DebugSettingsWidget(SettingsDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <limits>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "EmulationSettingsWidget.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,22 +15,22 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "Frontend/GameList.h"
|
||||
#include "PAD/Host/PAD.h"
|
||||
|
||||
#include "GameSummaryWidget.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialog* dialog, QWidget* parent)
|
||||
: m_dialog(dialog)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "SettingsDialog.h"
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GS/GSCapture.h"
|
||||
#include "pcsx2/GS/GSUtil.h"
|
||||
@@ -181,8 +181,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Renderer Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_ui.crcFixLevel, "EmuCore/GS", "crc_hack_level", static_cast<int>(CRCHackLevel::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderBW, "EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderLevel, "EmuCore/GS", "UserHacks_CPUSpriteRenderLevel", 0);
|
||||
@@ -194,6 +192,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.frameBufferConversion, "EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDepthEmulation, "EmuCore/GS", "UserHacks_DisableDepthSupport", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableSafeFeatures, "EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableRenderFixes, "EmuCore/GS", "UserHacks_DisableRenderFixes", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadFrameData, "EmuCore/GS", "preload_frame_with_gs_data", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(
|
||||
sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
|
||||
@@ -253,6 +252,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "EmuCore/GS", "DisableShaderCache", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableVertexShaderExpand, "EmuCore/GS", "DisableVertexShaderExpand", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_ui.gsDownloadMode, "EmuCore/GS", "HWDownloadMode", static_cast<int>(GSHardwareDownloadMode::Enabled));
|
||||
|
||||
@@ -471,9 +471,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
"Unscaled: Native Dithering / Lowest dithering effect does not increase size of squares when upscaling.<br> "
|
||||
"Scaled: Upscaling-aware / Highest dithering effect."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.crcFixLevel, tr("CRC Fix Level"), tr("Automatic (Default)"),
|
||||
tr("Control the number of Auto-CRC fixes and hacks applied to games."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.blending, tr("Blending Accuracy"), tr("Basic (Recommended)"),
|
||||
tr("Control the accuracy level of the GS blending unit emulation.<br> "
|
||||
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will "
|
||||
@@ -545,6 +542,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
"Disables accurate GS Memory Clearing to be done on the CPU, and let the GPU handle it, which can help Kingdom Hearts "
|
||||
"games."));
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.disableRenderFixes, tr("Disable Render Fixes"), tr("Unchecked"), tr("This option disables game-specific render fixes."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.disablePartialInvalidation, tr("Disable Partial Source Invalidation"), tr("Unchecked"),
|
||||
tr("By default, the texture cache handles partial invalidations. Unfortunately it is very costly to compute CPU wise. "
|
||||
"This hack replaces the partial invalidation with a complete deletion of the texture to reduce the CPU load. "
|
||||
@@ -1051,7 +1051,6 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
|
||||
|
||||
check_bool("EmuCore/GS", "UserHacks", false);
|
||||
|
||||
check_int("EmuCore/GS", "crc_hack_level", static_cast<int>(CRCHackLevel::Automatic));
|
||||
check_int("EmuCore/GS", "UserHacks_Half_Bottom_Override", -1);
|
||||
check_int("EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
|
||||
check_int("EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
|
||||
@@ -1062,6 +1061,7 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
|
||||
check_bool("EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisableDepthSupport", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisableRenderFixes", false);
|
||||
check_bool("EmuCore/GS", "preload_frame_with_gs_data", false);
|
||||
check_bool("EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
|
||||
check_int("EmuCore/GS", "UserHacks_TextureInsideRt", static_cast<int>(GSTextureInRtMode::Disabled));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>498</height>
|
||||
<height>492</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -781,54 +781,13 @@
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="hardwareFixesLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>CRC Fix Level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="crcFixLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None (Debug)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minimum (Debug)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Partial (OpenGL)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (Direct3D)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Aggressive</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Half Screen Fix:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="halfScreenFix">
|
||||
<item>
|
||||
<property name="text">
|
||||
@@ -847,14 +806,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_36">
|
||||
<property name="text">
|
||||
<string>CPU Sprite Render Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QComboBox" name="cpuSpriteRenderBW">
|
||||
@@ -936,14 +895,14 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Software CLUT Render:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cpuCLUTRender">
|
||||
<property name="currentText">
|
||||
<string extracomment="0 (Disabled)">0 (Disabled)</string>
|
||||
@@ -968,14 +927,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_47">
|
||||
<property name="text">
|
||||
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="gpuTargetCLUTMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
@@ -994,40 +953,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_45">
|
||||
<property name="text">
|
||||
<string>Texture Inside RT:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="textureInsideRt">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Inside Target</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Merge Targets</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_30">
|
||||
<property name="text">
|
||||
<string>Auto Flush:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="hwAutoFlush">
|
||||
<item>
|
||||
<property name="text">
|
||||
@@ -1046,14 +979,40 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_45">
|
||||
<property name="text">
|
||||
<string>Texture Inside RT:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="textureInsideRt">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Inside Target</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Merge Targets</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Skipdraw Range:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawStart">
|
||||
@@ -1071,7 +1030,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="disableDepthEmulation">
|
||||
@@ -1094,45 +1053,52 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="estimateTextureRegion">
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="targetPartialInvalidation">
|
||||
<property name="text">
|
||||
<string>Estimate Texture Region</string>
|
||||
<string>Target Partial Invalidation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="frameBufferConversion">
|
||||
<property name="text">
|
||||
<string>Frame Buffer Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="gpuPaletteConversion">
|
||||
<property name="text">
|
||||
<string>GPU Palette Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="preloadFrameData">
|
||||
<property name="text">
|
||||
<string>Preload Frame Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="readTCOnClose">
|
||||
<property name="text">
|
||||
<string>Read Targets When Closing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="targetPartialInvalidation">
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="preloadFrameData">
|
||||
<property name="text">
|
||||
<string>Target Partial Invalidation</string>
|
||||
<string>Preload Frame Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="gpuPaletteConversion">
|
||||
<property name="text">
|
||||
<string>GPU Palette Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="frameBufferConversion">
|
||||
<property name="text">
|
||||
<string>Frame Buffer Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="estimateTextureRegion">
|
||||
<property name="text">
|
||||
<string>Estimate Texture Region</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="disableRenderFixes">
|
||||
<property name="text">
|
||||
<string>Disable Render Fixes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2180,13 +2146,6 @@
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="disableDualSource">
|
||||
<property name="text">
|
||||
<string>Disable Dual Source Blending</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="disableFramebufferFetch">
|
||||
<property name="text">
|
||||
@@ -2194,10 +2153,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="disableDualSource">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
<string>Disable Dual Source Blending</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2208,6 +2167,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disableVertexShaderExpand">
|
||||
<property name="text">
|
||||
<string>Disable Vertex Shader Expand</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,12 +15,14 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "InputBindingWidget.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,9 +14,12 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui_InputBindingDialog.h"
|
||||
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,9 +14,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common/Pcsx2Defs.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
@@ -15,38 +15,34 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Settings/AchievementSettingsWidget.h"
|
||||
#include "Settings/AdvancedSettingsWidget.h"
|
||||
#include "Settings/AudioSettingsWidget.h"
|
||||
#include "Settings/BIOSSettingsWidget.h"
|
||||
#include "Settings/DEV9SettingsWidget.h"
|
||||
#include "Settings/DebugSettingsWidget.h"
|
||||
#include "Settings/EmulationSettingsWidget.h"
|
||||
#include "Settings/FolderSettingsWidget.h"
|
||||
#include "Settings/GameFixSettingsWidget.h"
|
||||
#include "Settings/GameListSettingsWidget.h"
|
||||
#include "Settings/GameSummaryWidget.h"
|
||||
#include "Settings/GraphicsSettingsWidget.h"
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
#include "Settings/InterfaceSettingsWidget.h"
|
||||
#include "Settings/MemoryCardSettingsWidget.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
#include "AdvancedSettingsWidget.h"
|
||||
#include "AudioSettingsWidget.h"
|
||||
#include "BIOSSettingsWidget.h"
|
||||
#include "EmulationSettingsWidget.h"
|
||||
#include "GameSummaryWidget.h"
|
||||
#include "GameFixSettingsWidget.h"
|
||||
#include "GameListSettingsWidget.h"
|
||||
#include "GraphicsSettingsWidget.h"
|
||||
#include "DEV9SettingsWidget.h"
|
||||
#include "FolderSettingsWidget.h"
|
||||
#include "HotkeySettingsWidget.h"
|
||||
#include "InterfaceSettingsWidget.h"
|
||||
#include "MemoryCardSettingsWidget.h"
|
||||
#include "DebugSettingsWidget.h"
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
#include "AchievementSettingsWidget.h"
|
||||
#include "pcsx2/Frontend/Achievements.h"
|
||||
#endif
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QTextEdit>
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
#include "QtHost.h"
|
||||
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Host.h"
|
||||
|
||||
#include "common/Path.h"
|
||||
|
||||
|
||||
+12
-70
@@ -21,7 +21,7 @@
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(SolutionDir)common\vsprops\common.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProperties.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\3rdpartyDeps.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\GenerateSCMVersion.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\QtCompile.props" />
|
||||
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
|
||||
<Import Condition="$(Configuration.Contains(Devel))" Project="$(SolutionDir)common\vsprops\CodeGen_Devel.props" />
|
||||
@@ -35,51 +35,24 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\freetype\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xz\xz\src\liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\baseclasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\simpleini\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\lzma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\demangler\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\sdl2\include;$(SolutionDir)3rdparty\sdl2\SDL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)pcsx2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\lzma\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\simpleini\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\demangler\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\sdl2\include;$(SolutionDir)3rdparty\sdl2\SDL\include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)pcsx2</AdditionalIncludeDirectories>
|
||||
<!-- Needed for moc pch -->
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(ProjectDir)\Settings;$(ProjectDir)\GameList;$(ProjectDir)\Tools\InputRecording;$(ProjectDir)\Debugger;$(ProjectDir)\Debugger\Models</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;DIRECTINPUT_VERSION=0x0800;SDL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
|
||||
<PreprocessorDefinitions>__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<!-- SH 2/3 flashlight, explicitly set here don't change -->
|
||||
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PreprocessorDefinitions>LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;SDL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
||||
<!-- Current Qt debug builds assert on RTTI. Remove this once we next build Qt. -->
|
||||
<RuntimeTypeInfo Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Debug))">true</RuntimeTypeInfo>
|
||||
<AdditionalOptions>/Zc:__cplusplus /Zo /utf-8%(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<LargeAddressAware>Yes</LargeAddressAware>
|
||||
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(QtEntryPointLib);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -90,46 +63,15 @@
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\fmt\fmt.vcxproj">
|
||||
<Project>{449ad25e-424a-4714-babc-68706cdcc33b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libjpeg\libjpeg.vcxproj">
|
||||
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj">
|
||||
<Project>{d6973076-9317-4ef2-a0b8-b7a18ac0713e}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
|
||||
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
|
||||
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libchdr\libchdr.vcxproj">
|
||||
<Project>{a0d2b3ad-1f72-4ee3-8b5c-f2c358da35f0}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\zlib\zlib.vcxproj">
|
||||
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
|
||||
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\imgui\imgui.vcxproj">
|
||||
<Project>{88fb34ec-845e-4f21-a552-f1573b9ed167}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)common\common.vcxproj">
|
||||
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2core.vcxproj">
|
||||
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2.vcxproj">
|
||||
<Project>{6c7986c4-3e4d-4dcc-b3c6-6bb12b238995}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
|
||||
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdparty\lzma\lzma.vcxproj">
|
||||
<Project>{a4323327-3f2b-4271-83d9-7f9a3c66b6b2}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdparty\zydis\zydis.vcxproj">
|
||||
<Project>{67d0160c-0fe4-44b9-ac2e-82bbcf4104df}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdparty\demangler\demangler.vcxproj">
|
||||
<Project>{1e3d706c-1d95-4e1b-bdf2-ca3d0007df7f}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -15,48 +15,47 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/Achievements.h"
|
||||
#include "Frontend/CommonHost.h"
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/ImGuiFullscreen.h"
|
||||
#include "Frontend/ImGuiManager.h"
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
|
||||
#include "Achievements.h"
|
||||
#include "CDVD/IsoFS/IsoFS.h"
|
||||
#include "CDVD/IsoFS/IsoFSCDVD.h"
|
||||
#include "Elfheader.h"
|
||||
#include "GS.h"
|
||||
#include "Host.h"
|
||||
#include "ImGui/FullscreenUI.h"
|
||||
#include "ImGui/ImGuiFullscreen.h"
|
||||
#include "ImGui/ImGuiManager.h"
|
||||
#include "IopMem.h"
|
||||
#include "Memory.h"
|
||||
#include "VMManager.h"
|
||||
#include "svnrev.h"
|
||||
#include "vtlb.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/HTTPDownloader.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/General.h"
|
||||
#include "common/HTTPDownloader.h"
|
||||
#include "common/MD5Digest.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/ScopedGuard.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Timer.h"
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "rc_api_info.h"
|
||||
#include "rc_api_request.h"
|
||||
#include "rc_api_runtime.h"
|
||||
#include "rc_api_user.h"
|
||||
#include "rcheevos.h"
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include "CDVD/IsoFS/IsoFSCDVD.h"
|
||||
#include "CDVD/IsoFS/IsoFS.h"
|
||||
#include "Elfheader.h"
|
||||
#include "GS.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
#include "IopMem.h"
|
||||
#include "Memory.h"
|
||||
#include "VMManager.h"
|
||||
#include "vtlb.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -397,10 +396,8 @@ void Achievements::ClearGameInfo(bool clear_achievements, bool clear_leaderboard
|
||||
s_has_rich_presence = false;
|
||||
s_game_id = 0;
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
if (EmuConfig.EnableDiscordPresence)
|
||||
CommonHost::UpdateDiscordPresence(s_rich_presence_string);
|
||||
#endif
|
||||
VMManager::UpdateDiscordPresence(s_rich_presence_string);
|
||||
}
|
||||
|
||||
if (had_game)
|
||||
@@ -879,6 +876,17 @@ const std::string& Achievements::GetRichPresenceString()
|
||||
return s_rich_presence_string;
|
||||
}
|
||||
|
||||
std::string Achievements::SafeGetRichPresenceString()
|
||||
{
|
||||
std::string rich_presence_string;
|
||||
if (IsActive() && EmuConfig.Achievements.RichPresence)
|
||||
{
|
||||
std::unique_lock lock(s_achievements_mutex);
|
||||
rich_presence_string = s_rich_presence_string;
|
||||
}
|
||||
return rich_presence_string;
|
||||
}
|
||||
|
||||
void Achievements::EnsureCacheDirectoriesExist()
|
||||
{
|
||||
s_game_icon_cache_directory = Path::Combine(EmuFolders::Cache, "achievement_gameicon");
|
||||
@@ -1351,8 +1359,19 @@ std::optional<std::vector<u8>> Achievements::ReadELFFromCurrentDisc(const std::s
|
||||
std::optional<std::vector<u8>> ret;
|
||||
try
|
||||
{
|
||||
// ELF suffix hack. Taken from CDVD::loadElf
|
||||
// MLB2k6 has an elf whose suffix is actually ;2
|
||||
std::string filepath(elf_path);
|
||||
const std::string::size_type semi_pos = filepath.rfind(';');
|
||||
if (semi_pos != std::string::npos && std::string_view(filepath).substr(semi_pos) != ";1")
|
||||
{
|
||||
Console.Warning("(Achievements) Non-conforming version suffix (%s) detected and replaced.", elf_path.c_str());
|
||||
filepath.erase(semi_pos);
|
||||
filepath += ";1";
|
||||
}
|
||||
|
||||
IsoFSCDVD isofs;
|
||||
IsoFile file(isofs, elf_path);
|
||||
IsoFile file(isofs, filepath);
|
||||
const u32 size = file.getLength();
|
||||
|
||||
ret = std::vector<u8>();
|
||||
@@ -1550,10 +1569,8 @@ void Achievements::UpdateRichPresence()
|
||||
|
||||
Host::OnAchievementsRefreshed();
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
if (EmuConfig.EnableDiscordPresence)
|
||||
CommonHost::UpdateDiscordPresence(s_rich_presence_string);
|
||||
#endif
|
||||
VMManager::UpdateDiscordPresence(s_rich_presence_string);
|
||||
}
|
||||
|
||||
void Achievements::SendPingCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data)
|
||||
@@ -2262,4 +2279,6 @@ void Achievements::RAIntegration::RACallbackWriteMemory(unsigned int address, un
|
||||
PokeMemory(address, sizeof(value), nullptr, static_cast<unsigned>(value));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // ENABLE_RAINTEGRATION
|
||||
|
||||
#endif // ENABLE_ACHIEVEMENTS
|
||||
+192
-14
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,34 +14,190 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
enum class AchievementCategory : u8
|
||||
{
|
||||
Local = 0,
|
||||
Core = 3,
|
||||
Unofficial = 5
|
||||
};
|
||||
|
||||
// Implemented in Host.
|
||||
extern bool OnReset();
|
||||
extern void LoadState(const u8* state_data, u32 state_data_size);
|
||||
extern std::vector<u8> SaveState();
|
||||
extern void GameChanged(u32 crc);
|
||||
struct Achievement
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string memaddr;
|
||||
std::string badge_name;
|
||||
|
||||
// badge paths are mutable because they're resolved when they're needed.
|
||||
mutable std::string locked_badge_path;
|
||||
mutable std::string unlocked_badge_path;
|
||||
|
||||
u32 points;
|
||||
AchievementCategory category;
|
||||
bool locked;
|
||||
bool active;
|
||||
bool primed;
|
||||
};
|
||||
|
||||
struct Leaderboard
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
int format;
|
||||
};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
std::string user;
|
||||
std::string formatted_score;
|
||||
time_t submitted;
|
||||
u32 rank;
|
||||
bool is_self;
|
||||
};
|
||||
|
||||
// RAIntegration only exists for Windows, so no point checking it on other platforms.
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
bool IsUsingRAIntegration();
|
||||
#else
|
||||
__fi static bool IsUsingRAIntegration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
bool IsUnofficialTestModeActive();
|
||||
bool IsRichPresenceEnabled();
|
||||
bool HasActiveGame();
|
||||
|
||||
u32 GetGameID();
|
||||
|
||||
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
|
||||
void Initialize();
|
||||
void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config);
|
||||
|
||||
/// Called when the system is being reset. If it returns false, the reset should be aborted.
|
||||
bool OnReset();
|
||||
|
||||
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
|
||||
bool Shutdown();
|
||||
|
||||
/// Called when the system is being paused and resumed.
|
||||
void OnPaused(bool paused);
|
||||
|
||||
/// Called once a frame at vsync time on the CPU thread.
|
||||
void VSyncUpdate();
|
||||
|
||||
/// Called to process pending HTTP requests when the VM is paused, because otherwise the vsync event won't fire.
|
||||
void ProcessPendingHTTPRequestsFromGSThread();
|
||||
|
||||
void LoadState(const u8* state_data, u32 state_data_size);
|
||||
std::vector<u8> SaveState();
|
||||
|
||||
/// Returns true if the current game has any achievements or leaderboards.
|
||||
/// Does not need to have the lock held.
|
||||
bool SafeHasAchievementsOrLeaderboards();
|
||||
|
||||
const std::string& GetUsername();
|
||||
const std::string& GetRichPresenceString();
|
||||
std::string SafeGetRichPresenceString();
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
void Logout();
|
||||
|
||||
void GameChanged(u32 crc);
|
||||
|
||||
const std::string& GetGameTitle();
|
||||
const std::string& GetGameIcon();
|
||||
|
||||
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
|
||||
u32 GetUnlockedAchiementCount();
|
||||
u32 GetAchievementCount();
|
||||
u32 GetMaximumPointsForGame();
|
||||
u32 GetCurrentPointsForGame();
|
||||
|
||||
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
|
||||
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
|
||||
const Leaderboard* GetLeaderboardByID(u32 id);
|
||||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
std::string GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(
|
||||
const Achievement& achievement, bool download_if_missing = true, bool force_unlocked_icon = false);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
u32 GetPrimedAchievementCount();
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
void SwitchToRAIntegration();
|
||||
|
||||
namespace RAIntegration
|
||||
{
|
||||
void MainWindowChanged(void* new_handle);
|
||||
void GameChanged();
|
||||
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
|
||||
void ActivateMenuItem(int item);
|
||||
} // namespace RAIntegration
|
||||
#endif
|
||||
|
||||
/// Re-enables hardcode mode if it is enabled in the settings.
|
||||
extern bool ResetChallengeMode();
|
||||
bool ResetChallengeMode();
|
||||
|
||||
/// Forces hardcore mode off until next reset.
|
||||
extern void DisableChallengeMode();
|
||||
void DisableChallengeMode();
|
||||
|
||||
/// Prompts the user to disable hardcore mode, if they agree, returns true.
|
||||
extern bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
extern bool ChallengeModeActive();
|
||||
bool ChallengeModeActive();
|
||||
} // namespace Achievements
|
||||
|
||||
#else
|
||||
|
||||
// Make noops when compiling without cheevos.
|
||||
// Make noops when compiling without cheevos.
|
||||
namespace Achievements
|
||||
{
|
||||
static inline void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
static inline void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool OnReset()
|
||||
{
|
||||
return true;
|
||||
@@ -67,12 +223,34 @@ namespace Achievements
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void DisableChallengeMode() {}
|
||||
static inline void DisableChallengeMode()
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool ConfirmChallengeModeDisable(const char* trigger)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
static inline void OnPaused(bool paused)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void VSyncUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
static std::string SafeGetRichPresenceString()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
} // namespace Achievements
|
||||
|
||||
#endif
|
||||
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host
|
||||
{
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
} // namespace Host
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Common.h"
|
||||
#include "IopHw.h"
|
||||
#include "IopDma.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
@@ -1447,6 +1448,12 @@ void cdvdUpdateTrayState()
|
||||
cdvd.Tray.trayState = CDVD_DISC_SEEKING;
|
||||
cdvdUpdateStatus(CDVD_STATUS_SEEK);
|
||||
cdvd.Tray.cdvdActionSeconds = 2;
|
||||
// If we're swapping disc, reload the elf, patches etc to reflect the new disc.
|
||||
if (g_GameStarted)
|
||||
{
|
||||
cdvdReloadElfInfo();
|
||||
VMManager::Internal::SwappingGameOnCPUThread();
|
||||
}
|
||||
break;
|
||||
case CDVD_DISC_SEEKING:
|
||||
cdvd.Spinning = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2014 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,16 +14,15 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "AsyncFileReader.h"
|
||||
#include "CsoFileReader.h"
|
||||
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#ifdef __POSIX__
|
||||
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include <zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
// Implementation of CSO compressed ISO reading, based on:
|
||||
// https://github.com/unknownbrackets/maxcso/blob/master/README_CSO.md
|
||||
|
||||
@@ -14,15 +14,18 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include <fstream>
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "ChunksCache.h"
|
||||
#include "GzippedFileReader.h"
|
||||
#include "HostSettings.h"
|
||||
#include "zlib_indexed.h"
|
||||
#include "Host.h"
|
||||
#include "CDVD/zlib_indexed.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#define CLAMP(val, minval, maxval) (std::min(maxval, std::max(minval, val)))
|
||||
|
||||
|
||||
@@ -100,11 +100,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __POSIX__
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include <zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
|
||||
+53
-83
@@ -60,8 +60,8 @@ if(TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE SDL2::SDL2)
|
||||
endif()
|
||||
target_sources(PCSX2 PRIVATE
|
||||
Frontend/SDLInputSource.cpp
|
||||
Frontend/SDLInputSource.h
|
||||
Input/SDLInputSource.cpp
|
||||
Input/SDLInputSource.h
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -69,20 +69,17 @@ if(WIN32)
|
||||
set(MIN_WIN32 0x0A00)
|
||||
target_compile_definitions(PCSX2_FLAGS INTERFACE
|
||||
__SSE4_1__
|
||||
DIRECTINPUT_VERSION=0x0800
|
||||
WINVER=${MIN_WIN32}
|
||||
_WIN32_WINNT=${MIN_WIN32}
|
||||
WIN32_LEAN_AND_MEAN
|
||||
LZMA_API_STATIC
|
||||
WIL_SUPPRESS_EXCEPTIONS
|
||||
)
|
||||
target_include_directories(PCSX2_FLAGS INTERFACE
|
||||
../3rdparty # GL headers
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
# Main pcsx2 source
|
||||
set(pcsx2Sources
|
||||
Achievements.cpp
|
||||
Cache.cpp
|
||||
COP0.cpp
|
||||
COP2.cpp
|
||||
@@ -93,14 +90,20 @@ set(pcsx2Sources
|
||||
FW.cpp
|
||||
FiFo.cpp
|
||||
FPU.cpp
|
||||
GameList.cpp
|
||||
Gif.cpp
|
||||
Gif_Logger.cpp
|
||||
Gif_Unit.cpp
|
||||
GS.cpp
|
||||
GSDumpReplayer.cpp
|
||||
Host.cpp
|
||||
Hotkeys.cpp
|
||||
Hw.cpp
|
||||
HwRead.cpp
|
||||
HwWrite.cpp
|
||||
LayeredSettingsInterface.cpp
|
||||
LogSink.cpp
|
||||
INISettingsInterface.cpp
|
||||
Interpreter.cpp
|
||||
IopBios.cpp
|
||||
IopCounters.cpp
|
||||
@@ -150,6 +153,7 @@ set(pcsx2Sources
|
||||
Vif_Transfer.cpp
|
||||
Vif_Unpack.cpp
|
||||
VirtualMemory.cpp
|
||||
VMManager.cpp
|
||||
vtlb.cpp
|
||||
VU0.cpp
|
||||
VUmicro.cpp
|
||||
@@ -159,7 +163,8 @@ set(pcsx2Sources
|
||||
VU1microInterp.cpp
|
||||
VUflags.cpp
|
||||
VUmicroMem.cpp
|
||||
VUops.cpp)
|
||||
VUops.cpp
|
||||
)
|
||||
|
||||
# Main pcsx2 header
|
||||
set(pcsx2Headers
|
||||
@@ -174,18 +179,23 @@ set(pcsx2Headers
|
||||
GameDatabase.h
|
||||
Elfheader.h
|
||||
FW.h
|
||||
GameList.h
|
||||
Gif.h
|
||||
Gif_Unit.h
|
||||
GS.h
|
||||
GSDumpReplayer.h
|
||||
Hardware.h
|
||||
Host.h
|
||||
Hw.h
|
||||
INISettingsInterface.h
|
||||
IopBios.h
|
||||
IopCounters.h
|
||||
IopDma.h
|
||||
IopGte.h
|
||||
IopHw.h
|
||||
IopMem.h
|
||||
LayeredSettingsInterface.h
|
||||
LogSink.h
|
||||
PINE.h
|
||||
Mdec.h
|
||||
MTVU.h
|
||||
@@ -216,6 +226,7 @@ set(pcsx2Headers
|
||||
Vif.h
|
||||
Vif_Unpack.h
|
||||
VirtualMemory.h
|
||||
VMManager.h
|
||||
vtlb.h
|
||||
VUflags.h
|
||||
VUmicro.h
|
||||
@@ -615,7 +626,7 @@ if(USE_OPENGL)
|
||||
list(APPEND pcsx2GSHeaders GS/Renderers/OpenGL/GLContextWGL.h)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE opengl32.lib)
|
||||
elseif(APPLE)
|
||||
list(APPEND pcsx2GSSources GS/Renderers/OpenGL/GLContextAGL.cpp)
|
||||
list(APPEND pcsx2GSSources GS/Renderers/OpenGL/GLContextAGL.mm)
|
||||
list(APPEND pcsx2GSHeaders GS/Renderers/OpenGL/GLContextAGL.h)
|
||||
else()
|
||||
if(X11_API OR WAYLAND_API)
|
||||
@@ -647,7 +658,6 @@ if(USE_VULKAN)
|
||||
GS/Renderers/Vulkan/VKShaderCache.cpp
|
||||
GS/Renderers/Vulkan/VKStreamBuffer.cpp
|
||||
GS/Renderers/Vulkan/VKSwapChain.cpp
|
||||
GS/Renderers/Vulkan/VKTexture.cpp
|
||||
GS/Renderers/Vulkan/VKUtil.cpp
|
||||
)
|
||||
list(APPEND pcsx2GSHeaders
|
||||
@@ -661,23 +671,9 @@ if(USE_VULKAN)
|
||||
GS/Renderers/Vulkan/VKShaderCache.h
|
||||
GS/Renderers/Vulkan/VKStreamBuffer.h
|
||||
GS/Renderers/Vulkan/VKSwapChain.h
|
||||
GS/Renderers/Vulkan/VKTexture.h
|
||||
GS/Renderers/Vulkan/VKUtil.h
|
||||
)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers glslang)
|
||||
|
||||
if(APPLE)
|
||||
# Needed for Metal surface creation.
|
||||
target_compile_options(common PRIVATE -fobjc-arc)
|
||||
target_link_options(common PRIVATE -fobjc-link-runtime)
|
||||
elseif(NOT WIN32)
|
||||
if(X11_API)
|
||||
target_compile_definitions(common PUBLIC "VULKAN_USE_X11=1")
|
||||
endif()
|
||||
if(WAYLAND_API)
|
||||
target_compile_definitions(common PUBLIC "VULKAN_USE_WAYLAND=1")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(pcsx2GSMetalShaders
|
||||
@@ -719,7 +715,6 @@ if(WIN32)
|
||||
GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp
|
||||
GS/Renderers/DX12/D3D12ShaderCache.cpp
|
||||
GS/Renderers/DX12/D3D12StreamBuffer.cpp
|
||||
GS/Renderers/DX12/D3D12Texture.cpp
|
||||
GS/Renderers/DX12/GSDevice12.cpp
|
||||
GS/Renderers/DX12/GSTexture12.cpp
|
||||
)
|
||||
@@ -733,7 +728,6 @@ if(WIN32)
|
||||
GS/Renderers/DX12/D3D12DescriptorHeapManager.h
|
||||
GS/Renderers/DX12/D3D12ShaderCache.h
|
||||
GS/Renderers/DX12/D3D12StreamBuffer.h
|
||||
GS/Renderers/DX12/D3D12Texture.h
|
||||
GS/Renderers/DX12/GSDevice12.h
|
||||
GS/Renderers/DX12/GSTexture12.h
|
||||
)
|
||||
@@ -850,16 +844,27 @@ set(pcsx2DebugToolsHeaders
|
||||
DebugTools/DisVUops.h
|
||||
DebugTools/BiosDebugData.h)
|
||||
|
||||
# Frontend sources
|
||||
set(pcsx2FrontendSources
|
||||
Frontend/ImGuiManager.cpp
|
||||
Frontend/ImGuiOverlays.cpp
|
||||
set(pcsx2ImGuiSources
|
||||
ImGui/FullscreenUI.cpp
|
||||
ImGui/ImGuiFullscreen.cpp
|
||||
ImGui/ImGuiManager.cpp
|
||||
ImGui/ImGuiOverlays.cpp
|
||||
)
|
||||
|
||||
# Frontend headers
|
||||
set(pcsx2FrontendHeaders
|
||||
Frontend/ImGuiManager.h
|
||||
Frontend/ImGuiOverlays.h
|
||||
set(pcsx2ImGuiHeaders
|
||||
ImGui/FullscreenUI.h
|
||||
ImGui/ImGuiFullscreen.h
|
||||
ImGui/ImGuiManager.h
|
||||
ImGui/ImGuiOverlays.h
|
||||
)
|
||||
|
||||
set(pcsx2InputSources
|
||||
Input/InputManager.cpp
|
||||
Input/InputSource.cpp
|
||||
)
|
||||
set(pcsx2InputHeaders
|
||||
Input/InputManager.h
|
||||
Input/InputSource.h
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
@@ -878,42 +883,7 @@ if(APPLE)
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND pcsx2FrontendSources
|
||||
Frontend/CommonHost.cpp
|
||||
Frontend/CommonHotkeys.cpp
|
||||
Frontend/FullscreenUI.cpp
|
||||
Frontend/GameList.cpp
|
||||
Frontend/HostSettings.cpp
|
||||
Frontend/ImGuiFullscreen.cpp
|
||||
Frontend/InputManager.cpp
|
||||
Frontend/InputSource.cpp
|
||||
Frontend/LayeredSettingsInterface.cpp
|
||||
Frontend/LogSink.cpp
|
||||
GSDumpReplayer.cpp
|
||||
INISettingsInterface.cpp
|
||||
VMManager.cpp
|
||||
)
|
||||
list(APPEND pcsx2FrontendHeaders
|
||||
Frontend/CommonHost.h
|
||||
Frontend/FullscreenUI.h
|
||||
Frontend/GameList.h
|
||||
Frontend/ImGuiFullscreen.h
|
||||
Frontend/InputManager.h
|
||||
Frontend/InputSource.h
|
||||
Frontend/LayeredSettingsInterface.h
|
||||
Frontend/LogSink.h
|
||||
GSDumpReplayer.h
|
||||
HostSettings.h
|
||||
INISettingsInterface.h
|
||||
VMManager.h)
|
||||
|
||||
if(USE_ACHIEVEMENTS)
|
||||
list(APPEND pcsx2FrontendSources
|
||||
Frontend/Achievements.cpp
|
||||
)
|
||||
list(APPEND pcsx2FrontendHeaders
|
||||
Frontend/Achievements.h
|
||||
)
|
||||
target_compile_definitions(PCSX2_FLAGS INTERFACE
|
||||
ENABLE_ACHIEVEMENTS
|
||||
)
|
||||
@@ -939,13 +909,13 @@ if(USE_DISCORD_PRESENCE)
|
||||
)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND pcsx2FrontendSources
|
||||
Frontend/DInputSource.cpp
|
||||
Frontend/XInputSource.cpp
|
||||
list(APPEND pcsx2InputSources
|
||||
Input/DInputSource.cpp
|
||||
Input/XInputSource.cpp
|
||||
)
|
||||
list(APPEND pcsx2FrontendHeaders
|
||||
Frontend/DInputSource.h
|
||||
Frontend/XInputSource.h
|
||||
list(APPEND pcsx2InputHeaders
|
||||
Input/DInputSource.h
|
||||
Input/XInputSource.h
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1149,8 +1119,10 @@ target_sources(PCSX2 PRIVATE
|
||||
${pcsx2RecordingSources}
|
||||
${pcsx2DebugToolsSources}
|
||||
${pcsx2DebugToolsHeaders}
|
||||
${pcsx2FrontendSources}
|
||||
${pcsx2FrontendHeaders}
|
||||
${pcsx2ImGuiSources}
|
||||
${pcsx2ImGuiHeaders}
|
||||
${pcsx2InputSources}
|
||||
${pcsx2InputHeaders}
|
||||
${pcsx2ps2Sources}
|
||||
${pcsx2ps2Headers}
|
||||
)
|
||||
@@ -1249,12 +1221,10 @@ endif()
|
||||
|
||||
# additonal include directories
|
||||
target_include_directories(PCSX2_FLAGS INTERFACE
|
||||
.
|
||||
x86
|
||||
${CMAKE_BINARY_DIR}/pcsx2
|
||||
${CMAKE_BINARY_DIR}/common/include/
|
||||
"${CMAKE_SOURCE_DIR}/3rdparty/jpgd/"
|
||||
"${CMAKE_SOURCE_DIR}/3rdparty/xbyak/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_BINARY_DIR}/pcsx2"
|
||||
"${CMAKE_BINARY_DIR}/common/include"
|
||||
"${CMAKE_SOURCE_DIR}/3rdparty/xbyak"
|
||||
"${FFMPEG_INCLUDE_DIRS}"
|
||||
)
|
||||
|
||||
@@ -1413,7 +1383,7 @@ function(setup_main_executable target)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
source_groups_from_vcxproj_filters(pcsx2core.vcxproj.filters)
|
||||
source_groups_from_vcxproj_filters(pcsx2.vcxproj.filters)
|
||||
|
||||
# Unix-only files aren't in the vcxproj.filters
|
||||
source_group(System/Ps2/DEV9 REGULAR_EXPRESSION DEV9/*)
|
||||
|
||||
+7
-11
@@ -288,16 +288,6 @@ enum class HWMipmapLevel : s8
|
||||
Full
|
||||
};
|
||||
|
||||
enum class CRCHackLevel : s8
|
||||
{
|
||||
Automatic = -1,
|
||||
Off,
|
||||
Minimum,
|
||||
Partial,
|
||||
Full,
|
||||
Aggressive
|
||||
};
|
||||
|
||||
enum class AccBlendLevel : u8
|
||||
{
|
||||
Minimum,
|
||||
@@ -657,6 +647,7 @@ struct Pcsx2Config
|
||||
DisableShaderCache : 1,
|
||||
DisableDualSourceBlend : 1,
|
||||
DisableFramebufferFetch : 1,
|
||||
DisableVertexShaderExpand : 1,
|
||||
DisableThreadedPresentation : 1,
|
||||
SkipDuplicateFrames : 1,
|
||||
OsdShowMessages : 1,
|
||||
@@ -685,6 +676,7 @@ struct Pcsx2Config
|
||||
UserHacks_DisableDepthSupport : 1,
|
||||
UserHacks_DisablePartialInvalidation : 1,
|
||||
UserHacks_DisableSafeFeatures : 1,
|
||||
UserHacks_DisableRenderFixes : 1,
|
||||
UserHacks_MergePPSprite : 1,
|
||||
UserHacks_WildHack : 1,
|
||||
UserHacks_BilinearHack : 1,
|
||||
@@ -742,7 +734,6 @@ struct Pcsx2Config
|
||||
|
||||
HWMipmapLevel HWMipmap = HWMipmapLevel::Automatic;
|
||||
AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Basic;
|
||||
CRCHackLevel CRCHack = CRCHackLevel::Automatic;
|
||||
BiFiltering TextureFiltering = BiFiltering::PS2;
|
||||
TexturePreloadingLevel TexturePreloading = TexturePreloadingLevel::Full;
|
||||
GSDumpCompressionMethod GSDumpCompression = GSDumpCompressionMethod::Zstandard;
|
||||
@@ -1302,6 +1293,8 @@ struct Pcsx2Config
|
||||
McdOptions Mcd[8];
|
||||
std::string GzipIsoIndexTemplate; // for quick-access index with gzipped ISO
|
||||
|
||||
int PINESlot;
|
||||
|
||||
// Set at runtime, not loaded from config.
|
||||
std::string CurrentBlockdump;
|
||||
std::string CurrentIRX;
|
||||
@@ -1352,6 +1345,9 @@ namespace EmuFolders
|
||||
extern std::string InputProfiles;
|
||||
extern std::string Videos;
|
||||
|
||||
/// Initializes critical folders (AppRoot, DataRoot, Settings). Call once on startup.
|
||||
bool InitializeCriticalFolders();
|
||||
|
||||
// Assumes that AppRoot and DataRoot have been initialized.
|
||||
void SetDefaults(SettingsInterface& si);
|
||||
void LoadConfig(SettingsInterface& si);
|
||||
|
||||
@@ -99,7 +99,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
|
||||
WriteUInt16(identifyData, &index, sectorSize); //word 5
|
||||
//Default Number of sectors per track (Retired)
|
||||
WriteUInt16(identifyData, &index, defSectors); //word 6
|
||||
//Reserved for assignment by the CompactFlash™ Association
|
||||
//Reserved for assignment by the CompactFlash™ Association
|
||||
index += 2 * 2; //word 7-8
|
||||
//Retired
|
||||
index += 1 * 2; //word 9
|
||||
@@ -182,7 +182,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
|
||||
WriteUInt16(identifyData, &index, 0x1F); //word 64 (pio3,4 supported) selection not reported here
|
||||
//Minimum Multiword DMA transfer cycle time per word
|
||||
WriteUInt16(identifyData, &index, 80); //word 65
|
||||
//Manufacturer’s recommended Multiword DMA transfer cycle time
|
||||
//Manufacturer’s recommended Multiword DMA transfer cycle time
|
||||
WriteUInt16(identifyData, &index, 80); //word 66
|
||||
//Minimum PIO transfer cycle time without flow control
|
||||
WriteUInt16(identifyData, &index, 120); //word 67
|
||||
@@ -307,7 +307,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
|
||||
*/
|
||||
index = 93 * 2;
|
||||
WriteUInt16(identifyData, &index, (u16)(1 | (1 << 14) | 0x2000)); //word 93
|
||||
//Vendor’s recommended acoustic management value.
|
||||
//Vendor’s recommended acoustic management value.
|
||||
//94
|
||||
//Stream Minimum Request Size
|
||||
//95
|
||||
|
||||
@@ -468,7 +468,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
valueStack.push_back(val);
|
||||
}
|
||||
break;
|
||||
case EXOP_SIGNPLUS: // keine aktion nötig
|
||||
case EXOP_SIGNPLUS: // keine aktion nötig
|
||||
break;
|
||||
case EXOP_SIGNMINUS: // -0
|
||||
if (useFloat)
|
||||
|
||||
@@ -27,6 +27,7 @@ u32 ElfEntry;
|
||||
std::pair<u32,u32> ElfTextRange;
|
||||
std::string LastELF;
|
||||
bool isPSXElf;
|
||||
std::string ElfVersion;
|
||||
|
||||
// All of ElfObjects functions.
|
||||
ElfObject::ElfObject(std::string srcfile, IsoFile& isofile, bool isPSXElf)
|
||||
@@ -365,6 +366,7 @@ int GetPS2ElfName( std::string& name )
|
||||
{
|
||||
Console.WriteLn( Color_Blue, "(SYSTEM.CNF) Software version = %.*s",
|
||||
static_cast<int>(value.size()), value.data());
|
||||
ElfVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,3 +163,4 @@ extern u32 ElfEntry;
|
||||
extern std::pair<u32,u32> ElfTextRange;
|
||||
extern std::string LastELF;
|
||||
extern bool isPSXElf;
|
||||
extern std::string ElfVersion;
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common/Pcsx2Defs.h"
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "Config.h"
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
enum class AchievementCategory : u8
|
||||
{
|
||||
Local = 0,
|
||||
Core = 3,
|
||||
Unofficial = 5
|
||||
};
|
||||
|
||||
struct Achievement
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string memaddr;
|
||||
std::string badge_name;
|
||||
|
||||
// badge paths are mutable because they're resolved when they're needed.
|
||||
mutable std::string locked_badge_path;
|
||||
mutable std::string unlocked_badge_path;
|
||||
|
||||
u32 points;
|
||||
AchievementCategory category;
|
||||
bool locked;
|
||||
bool active;
|
||||
bool primed;
|
||||
};
|
||||
|
||||
struct Leaderboard
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
int format;
|
||||
};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
std::string user;
|
||||
std::string formatted_score;
|
||||
time_t submitted;
|
||||
u32 rank;
|
||||
bool is_self;
|
||||
};
|
||||
|
||||
// RAIntegration only exists for Windows, so no point checking it on other platforms.
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
|
||||
bool IsUsingRAIntegration();
|
||||
|
||||
#else
|
||||
|
||||
static __fi bool IsUsingRAIntegration() { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
bool IsUnofficialTestModeActive();
|
||||
bool IsRichPresenceEnabled();
|
||||
bool HasActiveGame();
|
||||
|
||||
u32 GetGameID();
|
||||
|
||||
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
|
||||
void Initialize();
|
||||
void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config);
|
||||
|
||||
/// Called when the system is being reset. If it returns false, the reset should be aborted.
|
||||
bool OnReset();
|
||||
|
||||
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
|
||||
bool Shutdown();
|
||||
|
||||
/// Called when the system is being paused and resumed.
|
||||
void OnPaused(bool paused);
|
||||
|
||||
/// Called once a frame at vsync time on the CPU thread.
|
||||
void VSyncUpdate();
|
||||
|
||||
/// Called to process pending HTTP requests when the VM is paused, because otherwise the vsync event won't fire.
|
||||
void ProcessPendingHTTPRequestsFromGSThread();
|
||||
|
||||
void LoadState(const u8* state_data, u32 state_data_size);
|
||||
std::vector<u8> SaveState();
|
||||
|
||||
/// Returns true if the current game has any achievements or leaderboards.
|
||||
/// Does not need to have the lock held.
|
||||
bool SafeHasAchievementsOrLeaderboards();
|
||||
|
||||
const std::string& GetUsername();
|
||||
const std::string& GetRichPresenceString();
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
void Logout();
|
||||
|
||||
void GameChanged(u32 crc);
|
||||
|
||||
const std::string& GetGameTitle();
|
||||
const std::string& GetGameIcon();
|
||||
|
||||
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
|
||||
u32 GetUnlockedAchiementCount();
|
||||
u32 GetAchievementCount();
|
||||
u32 GetMaximumPointsForGame();
|
||||
u32 GetCurrentPointsForGame();
|
||||
|
||||
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
|
||||
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
|
||||
const Leaderboard* GetLeaderboardByID(u32 id);
|
||||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
std::string GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(
|
||||
const Achievement& achievement, bool download_if_missing = true, bool force_unlocked_icon = false);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
u32 GetPrimedAchievementCount();
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
void SwitchToRAIntegration();
|
||||
|
||||
namespace RAIntegration
|
||||
{
|
||||
void MainWindowChanged(void* new_handle);
|
||||
void GameChanged();
|
||||
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
|
||||
void ActivateMenuItem(int item);
|
||||
} // namespace RAIntegration
|
||||
#endif
|
||||
} // namespace Achievements
|
||||
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host
|
||||
{
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
} // namespace Host
|
||||
@@ -1,544 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/Timer.h"
|
||||
#include "common/Threading.h"
|
||||
#include "Frontend/CommonHost.h"
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/GameList.h"
|
||||
#include "Frontend/LayeredSettingsInterface.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Frontend/LogSink.h"
|
||||
#include "GS.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "MemoryCardFile.h"
|
||||
#include "PAD/Host/PAD.h"
|
||||
#include "PerformanceMetrics.h"
|
||||
#include "Sio.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
#include "Frontend/Achievements.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
#include "discord_rpc.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include <KnownFolders.h>
|
||||
#include <ShlObj.h>
|
||||
#endif
|
||||
|
||||
static constexpr u32 SETTINGS_VERSION = 1;
|
||||
|
||||
namespace CommonHost
|
||||
{
|
||||
static void SetAppRoot();
|
||||
static void SetResourcesDirectory();
|
||||
static bool ShouldUsePortableMode();
|
||||
static void SetDataDirectory();
|
||||
static void SetCommonDefaultSettings(SettingsInterface& si);
|
||||
|
||||
static void UpdateInhibitScreensaver(bool allow);
|
||||
|
||||
static void UpdateSessionTime(const std::string& new_serial);
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
static void InitializeDiscordPresence();
|
||||
static void ShutdownDiscordPresence();
|
||||
static void PollDiscordPresence();
|
||||
static std::string GetRichPresenceString();
|
||||
#endif
|
||||
} // namespace CommonHost
|
||||
|
||||
// Used to track play time. We use a monotonic timer here, in case of clock changes.
|
||||
static u64 s_session_start_time = 0;
|
||||
static std::string s_session_serial;
|
||||
|
||||
static bool s_screensaver_inhibited = false;
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
static bool s_discord_presence_active = false;
|
||||
#endif
|
||||
|
||||
bool CommonHost::InitializeCriticalFolders()
|
||||
{
|
||||
SetAppRoot();
|
||||
SetResourcesDirectory();
|
||||
SetDataDirectory();
|
||||
|
||||
// logging of directories in case something goes wrong super early
|
||||
Console.WriteLn("AppRoot Directory: %s", EmuFolders::AppRoot.c_str());
|
||||
Console.WriteLn("DataRoot Directory: %s", EmuFolders::DataRoot.c_str());
|
||||
Console.WriteLn("Resources Directory: %s", EmuFolders::Resources.c_str());
|
||||
|
||||
// allow SetDataDirectory() to change settings directory (if we want to split config later on)
|
||||
if (EmuFolders::Settings.empty())
|
||||
{
|
||||
EmuFolders::Settings = Path::Combine(EmuFolders::DataRoot, "inis");
|
||||
|
||||
// Create settings directory if it doesn't exist. If we're not using portable mode, it won't.
|
||||
if (!FileSystem::DirectoryExists(EmuFolders::Settings.c_str()))
|
||||
FileSystem::CreateDirectoryPath(EmuFolders::Settings.c_str(), false);
|
||||
}
|
||||
|
||||
// Write crash dumps to the data directory, since that'll be accessible for certain.
|
||||
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
|
||||
|
||||
// the resources directory should exist, bail out if not
|
||||
if (!FileSystem::DirectoryExists(EmuFolders::Resources.c_str()))
|
||||
{
|
||||
Console.Error("Resources directory is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommonHost::SetAppRoot()
|
||||
{
|
||||
std::string program_path(FileSystem::GetProgramPath());
|
||||
Console.WriteLn("Program Path: %s", program_path.c_str());
|
||||
|
||||
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
|
||||
}
|
||||
|
||||
void CommonHost::SetResourcesDirectory()
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
// On Windows/Linux, these are in the binary directory.
|
||||
EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
|
||||
#else
|
||||
// On macOS, this is in the bundle resources directory.
|
||||
EmuFolders::Resources = Path::Canonicalize(Path::Combine(EmuFolders::AppRoot, "../Resources"));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CommonHost::ShouldUsePortableMode()
|
||||
{
|
||||
// Check whether portable.ini exists in the program directory.
|
||||
return FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.ini").c_str());
|
||||
}
|
||||
|
||||
void CommonHost::SetDataDirectory()
|
||||
{
|
||||
if (ShouldUsePortableMode())
|
||||
{
|
||||
EmuFolders::DataRoot = EmuFolders::AppRoot;
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
// On Windows, use My Documents\PCSX2 to match old installs.
|
||||
PWSTR documents_directory;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory)))
|
||||
{
|
||||
if (std::wcslen(documents_directory) > 0)
|
||||
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "PCSX2");
|
||||
CoTaskMemFree(documents_directory);
|
||||
}
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
// Use $XDG_CONFIG_HOME/PCSX2 if it exists.
|
||||
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
|
||||
{
|
||||
EmuFolders::DataRoot = Path::Combine(xdg_config_home, "PCSX2");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use ~/PCSX2 for non-XDG, and ~/.config/PCSX2 for XDG.
|
||||
// Maybe we should drop the former when Qt goes live.
|
||||
const char* home_dir = getenv("HOME");
|
||||
if (home_dir)
|
||||
{
|
||||
#ifdef USE_LEGACY_USER_DIRECTORY
|
||||
EmuFolders::DataRoot = Path::Combine(home_dir, "PCSX2");
|
||||
#else
|
||||
// ~/.config should exist, but just in case it doesn't and this is a fresh profile..
|
||||
const std::string config_dir(Path::Combine(home_dir, ".config"));
|
||||
if (!FileSystem::DirectoryExists(config_dir.c_str()))
|
||||
FileSystem::CreateDirectoryPath(config_dir.c_str(), false);
|
||||
|
||||
EmuFolders::DataRoot = Path::Combine(config_dir, "PCSX2");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/PCSX2";
|
||||
const char* home_dir = getenv("HOME");
|
||||
if (home_dir)
|
||||
EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
|
||||
#endif
|
||||
|
||||
// make sure it exists
|
||||
if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str()))
|
||||
{
|
||||
// we're in trouble if we fail to create this directory... but try to hobble on with portable
|
||||
if (!FileSystem::CreateDirectoryPath(EmuFolders::DataRoot.c_str(), false))
|
||||
EmuFolders::DataRoot.clear();
|
||||
}
|
||||
|
||||
// couldn't determine the data directory? fallback to portable.
|
||||
if (EmuFolders::DataRoot.empty())
|
||||
EmuFolders::DataRoot = EmuFolders::AppRoot;
|
||||
}
|
||||
|
||||
bool CommonHost::CheckSettingsVersion()
|
||||
{
|
||||
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
|
||||
|
||||
uint settings_version;
|
||||
return (bsi->GetUIntValue("UI", "SettingsVersion", &settings_version) && settings_version == SETTINGS_VERSION);
|
||||
}
|
||||
|
||||
void CommonHost::LoadStartupSettings()
|
||||
{
|
||||
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
|
||||
EmuFolders::LoadConfig(*bsi);
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
UpdateLogging(*bsi);
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
// RAIntegration switch must happen before the UI is created.
|
||||
if (Host::GetBaseBoolSettingValue("Achievements", "UseRAIntegration", false))
|
||||
Achievements::SwitchToRAIntegration();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui)
|
||||
{
|
||||
if (si.GetUIntValue("UI", "SettingsVersion", 0u) != SETTINGS_VERSION)
|
||||
si.SetUIntValue("UI", "SettingsVersion", SETTINGS_VERSION);
|
||||
|
||||
if (folders)
|
||||
EmuFolders::SetDefaults(si);
|
||||
if (core)
|
||||
{
|
||||
VMManager::SetDefaultSettings(si);
|
||||
SetCommonDefaultSettings(si);
|
||||
}
|
||||
if (controllers)
|
||||
PAD::SetDefaultControllerConfig(si);
|
||||
if (hotkeys)
|
||||
PAD::SetDefaultHotkeyConfig(si);
|
||||
if (ui)
|
||||
Host::SetDefaultUISettings(si);
|
||||
}
|
||||
|
||||
void CommonHost::SetCommonDefaultSettings(SettingsInterface& si)
|
||||
{
|
||||
SetDefaultLoggingSettings(si);
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadInitialize()
|
||||
{
|
||||
Threading::SetNameOfCurrentThread("CPU Thread");
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
|
||||
|
||||
// neither of these should ever fail.
|
||||
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
|
||||
pxFailRel("Failed to allocate memory map");
|
||||
|
||||
// We want settings loaded so we choose the correct renderer for big picture mode.
|
||||
// This also sorts out input sources.
|
||||
VMManager::LoadSettings();
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
if (EmuConfig.Achievements.Enabled)
|
||||
Achievements::Initialize();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
if (EmuConfig.EnableDiscordPresence)
|
||||
InitializeDiscordPresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadShutdown()
|
||||
{
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
ShutdownDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::Shutdown();
|
||||
#endif
|
||||
|
||||
InputManager::CloseSources();
|
||||
VMManager::WaitForSaveStateFlush();
|
||||
VMManager::Internal::ReleaseMemory();
|
||||
VMManager::Internal::ReleaseGlobals();
|
||||
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
|
||||
}
|
||||
|
||||
void CommonHost::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
SettingsInterface* binding_si = Host::GetSettingsInterfaceForBindings();
|
||||
InputManager::ReloadSources(si, lock);
|
||||
InputManager::ReloadBindings(si, *binding_si);
|
||||
|
||||
UpdateLogging(si);
|
||||
}
|
||||
|
||||
void CommonHost::CheckForSettingsChanges(const Pcsx2Config& old_config)
|
||||
{
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
if (EmuConfig.Achievements != old_config.Achievements)
|
||||
Achievements::UpdateSettings(old_config.Achievements);
|
||||
#endif
|
||||
|
||||
FullscreenUI::CheckForConfigChanges(old_config);
|
||||
|
||||
if (EmuConfig.InhibitScreensaver != old_config.InhibitScreensaver)
|
||||
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver && VMManager::GetState() == VMState::Running);
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
if (EmuConfig.EnableDiscordPresence != old_config.EnableDiscordPresence)
|
||||
{
|
||||
if (EmuConfig.EnableDiscordPresence)
|
||||
InitializeDiscordPresence();
|
||||
else
|
||||
ShutdownDiscordPresence();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::OnVMStarting()
|
||||
{
|
||||
CommonHost::Internal::ResetVMHotkeyState();
|
||||
}
|
||||
|
||||
void CommonHost::OnVMStarted()
|
||||
{
|
||||
FullscreenUI::OnVMStarted();
|
||||
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver);
|
||||
}
|
||||
|
||||
void CommonHost::OnVMDestroyed()
|
||||
{
|
||||
FullscreenUI::OnVMDestroyed();
|
||||
UpdateInhibitScreensaver(false);
|
||||
}
|
||||
|
||||
void CommonHost::OnVMPaused()
|
||||
{
|
||||
InputManager::PauseVibration();
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::OnPaused(true);
|
||||
#endif
|
||||
|
||||
UpdateInhibitScreensaver(false);
|
||||
}
|
||||
|
||||
void CommonHost::OnVMResumed()
|
||||
{
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::OnPaused(false);
|
||||
#endif
|
||||
|
||||
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver);
|
||||
}
|
||||
|
||||
void CommonHost::OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
|
||||
const std::string& game_name, u32 game_crc)
|
||||
{
|
||||
UpdateSessionTime(game_serial);
|
||||
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
GetMTGS().RunOnGSThread([disc_path, game_serial, game_name, game_crc]() {
|
||||
FullscreenUI::OnRunningGameChanged(std::move(disc_path), std::move(game_serial), std::move(game_name), game_crc);
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::GameChanged(game_crc);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(GetRichPresenceString());
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::CPUThreadVSync()
|
||||
{
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::VSyncUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
InputManager::PollSources();
|
||||
}
|
||||
|
||||
bool Host::GetSerialAndCRCForFilename(const char* filename, std::string* serial, u32* crc)
|
||||
{
|
||||
{
|
||||
auto lock = GameList::GetLock();
|
||||
if (const GameList::Entry* entry = GameList::GetEntryForPath(filename); entry)
|
||||
{
|
||||
*serial = entry->serial;
|
||||
*crc = entry->crc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Just scan it.. hopefully it'll come back okay.
|
||||
GameList::Entry temp_entry;
|
||||
if (GameList::PopulateEntryFromPath(filename, &temp_entry))
|
||||
{
|
||||
*serial = std::move(temp_entry.serial);
|
||||
*crc = temp_entry.crc;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommonHost::UpdateInhibitScreensaver(bool inhibit)
|
||||
{
|
||||
if (s_screensaver_inhibited == inhibit)
|
||||
return;
|
||||
|
||||
WindowInfo wi;
|
||||
auto top_level_wi = Host::GetTopLevelWindowInfo();
|
||||
if (top_level_wi.has_value())
|
||||
wi = top_level_wi.value();
|
||||
|
||||
s_screensaver_inhibited = inhibit;
|
||||
if (!WindowInfo::InhibitScreensaver(wi, inhibit) && inhibit)
|
||||
Console.Warning("Failed to inhibit screen saver.");
|
||||
}
|
||||
|
||||
void CommonHost::UpdateSessionTime(const std::string& new_serial)
|
||||
{
|
||||
if (s_session_serial == new_serial)
|
||||
return;
|
||||
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
if (!s_session_serial.empty())
|
||||
{
|
||||
// round up to seconds
|
||||
const std::time_t etime = static_cast<std::time_t>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
const std::time_t wtime = std::time(nullptr);
|
||||
GameList::AddPlayedTimeForSerial(s_session_serial, wtime, etime);
|
||||
}
|
||||
|
||||
s_session_serial = new_serial;
|
||||
s_session_start_time = ctime;
|
||||
}
|
||||
|
||||
u64 CommonHost::GetSessionPlayedTime()
|
||||
{
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
return static_cast<u64>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
|
||||
void CommonHost::InitializeDiscordPresence()
|
||||
{
|
||||
if (s_discord_presence_active)
|
||||
return;
|
||||
|
||||
DiscordEventHandlers handlers = {};
|
||||
Discord_Initialize("1025789002055430154", &handlers, 0, nullptr);
|
||||
s_discord_presence_active = true;
|
||||
|
||||
UpdateDiscordPresence(GetRichPresenceString());
|
||||
}
|
||||
|
||||
void CommonHost::ShutdownDiscordPresence()
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
Discord_ClearPresence();
|
||||
Discord_RunCallbacks();
|
||||
Discord_Shutdown();
|
||||
s_discord_presence_active = false;
|
||||
}
|
||||
|
||||
void CommonHost::UpdateDiscordPresence(const std::string& rich_presence)
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
// https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields
|
||||
DiscordRichPresence rp = {};
|
||||
rp.largeImageKey = "4k-pcsx2";
|
||||
rp.largeImageText = "PCSX2 Emulator";
|
||||
rp.startTimestamp = std::time(nullptr);
|
||||
|
||||
std::string details_string;
|
||||
if (VMManager::HasValidVM())
|
||||
details_string = VMManager::GetGameName();
|
||||
else
|
||||
details_string = "No Game Running";
|
||||
rp.details = details_string.c_str();
|
||||
|
||||
// Trim to 128 bytes as per Discord-RPC requirements
|
||||
std::string state_string;
|
||||
if (rich_presence.length() >= 128)
|
||||
{
|
||||
// 124 characters + 3 dots + null terminator
|
||||
state_string = fmt::format("{}...", std::string_view(rich_presence).substr(0, 124));
|
||||
}
|
||||
else
|
||||
{
|
||||
state_string = rich_presence;
|
||||
}
|
||||
rp.state = state_string.c_str();
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
void CommonHost::PollDiscordPresence()
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
std::string CommonHost::GetRichPresenceString()
|
||||
{
|
||||
std::string rich_presence_string;
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
if (Achievements::IsActive() && EmuConfig.Achievements.RichPresence)
|
||||
{
|
||||
auto lock = Achievements::GetLock();
|
||||
rich_presence_string = Achievements::GetRichPresenceString();
|
||||
}
|
||||
#endif
|
||||
return rich_presence_string;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Pcsx2Defs.h"
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
class SettingsInterface;
|
||||
|
||||
namespace Host
|
||||
{
|
||||
/// Sets host-specific default settings.
|
||||
void SetDefaultUISettings(SettingsInterface& si);
|
||||
} // namespace Host
|
||||
|
||||
namespace CommonHost
|
||||
{
|
||||
/// Initializes critical folders (AppRoot, DataRoot, Settings). Call once on startup.
|
||||
bool InitializeCriticalFolders();
|
||||
|
||||
/// Checks settings version. Call once on startup. If it returns false, you should prompt the user to reset.
|
||||
bool CheckSettingsVersion();
|
||||
|
||||
/// Loads early settings. Call once on startup.
|
||||
void LoadStartupSettings();
|
||||
|
||||
/// Sets default settings for the specified categories.
|
||||
void SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui);
|
||||
|
||||
/// Initializes common host state, called on the CPU thread.
|
||||
void CPUThreadInitialize();
|
||||
|
||||
/// Cleans up common host state, called on the CPU thread.
|
||||
void CPUThreadShutdown();
|
||||
|
||||
/// Loads common host settings (including input bindings).
|
||||
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
|
||||
|
||||
/// Called after settings are updated.
|
||||
void CheckForSettingsChanges(const Pcsx2Config& old_config);
|
||||
|
||||
/// Called when the VM is starting initialization, but has not been completed yet.
|
||||
void OnVMStarting();
|
||||
|
||||
/// Called when the VM is created.
|
||||
void OnVMStarted();
|
||||
|
||||
/// Called when the VM is shut down or destroyed.
|
||||
void OnVMDestroyed();
|
||||
|
||||
/// Called when the VM is paused.
|
||||
void OnVMPaused();
|
||||
|
||||
/// Called when the VM is resumed after being paused.
|
||||
void OnVMResumed();
|
||||
|
||||
/// Called when the running executable changes.
|
||||
void OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
|
||||
const std::string& game_name, u32 game_crc);
|
||||
|
||||
/// Provided by the host; called once per frame at guest vsync.
|
||||
void CPUThreadVSync();
|
||||
|
||||
/// Returns the time elapsed in the current play session.
|
||||
u64 GetSessionPlayedTime();
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
/// Called when the rich presence string, provided by RetroAchievements, changes.
|
||||
void UpdateDiscordPresence(const std::string& rich_presence);
|
||||
#endif
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
/// Resets any state for hotkey-related VMs, called on VM startup.
|
||||
void ResetVMHotkeyState();
|
||||
} // namespace Internal
|
||||
} // namespace CommonHost
|
||||
@@ -1,262 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "Frontend/LayeredSettingsInterface.h"
|
||||
#include "GS.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
#include "MemoryCardFile.h"
|
||||
#include "Sio.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
static std::mutex s_settings_mutex;
|
||||
static LayeredSettingsInterface s_layered_settings_interface;
|
||||
|
||||
std::unique_lock<std::mutex> Host::GetSettingsLock()
|
||||
{
|
||||
return std::unique_lock<std::mutex>(s_settings_mutex);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterface()
|
||||
{
|
||||
return &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterfaceForBindings()
|
||||
{
|
||||
SettingsInterface* input_layer = s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
return input_layer ? input_layer : &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
std::string Host::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
int Host::GetBaseIntSettingValue(const char* section, const char* key, int default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
uint Host::GetBaseUIntSettingValue(const char* section, const char* key, uint default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetBaseFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetBaseDoubleSettingValue(const char* section, const char* key, double default_value /* = 0.0f */)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetBaseStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringList(section, key);
|
||||
}
|
||||
|
||||
void Host::SetBaseBoolSettingValue(const char* section, const char* key, bool value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetBoolValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseIntSettingValue(const char* section, const char* key, int value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetIntValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseUIntSettingValue(const char* section, const char* key, uint value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetUIntValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseFloatSettingValue(const char* section, const char* key, float value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetFloatValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringSettingValue(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringList(section, key, values);
|
||||
}
|
||||
|
||||
bool Host::AddBaseValueToStringList(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->AddToStringList(section, key, value);
|
||||
}
|
||||
|
||||
bool Host::RemoveBaseValueFromStringList(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->RemoveFromStringList(section, key, value);
|
||||
}
|
||||
|
||||
void Host::RemoveBaseSettingValue(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->DeleteValue(section, key);
|
||||
}
|
||||
|
||||
std::string Host::GetStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
int Host::GetIntSettingValue(const char* section, const char* key, int default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
uint Host::GetUIntSettingValue(const char* section, const char* key, uint default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetDoubleSettingValue(const char* section, const char* key, double default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringList(section, key);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetBaseSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetGameSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetInputSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
}
|
||||
|
||||
void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr, "Base layer has not been set");
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetInputSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_INPUT, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::UpdateEmuFolders()
|
||||
{
|
||||
const std::string old_cheats_directory(EmuFolders::Cheats);
|
||||
const std::string old_cheats_ws_directory(EmuFolders::CheatsWS);
|
||||
const std::string old_cheats_ni_directory(EmuFolders::CheatsNI);
|
||||
const std::string old_memcards_directory(EmuFolders::MemoryCards);
|
||||
const std::string old_textures_directory(EmuFolders::Textures);
|
||||
const std::string old_videos_directory(EmuFolders::Videos);
|
||||
|
||||
EmuFolders::LoadConfig(*GetBaseSettingsLayer());
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
|
||||
if (VMManager::HasValidVM())
|
||||
{
|
||||
if (EmuFolders::Cheats != old_cheats_directory || EmuFolders::CheatsWS != old_cheats_ws_directory ||
|
||||
EmuFolders::CheatsNI != old_cheats_ni_directory)
|
||||
{
|
||||
VMManager::ReloadPatches(true, true);
|
||||
}
|
||||
|
||||
if (EmuFolders::MemoryCards != old_memcards_directory)
|
||||
{
|
||||
FileMcd_EmuClose();
|
||||
FileMcd_EmuOpen();
|
||||
AutoEject::SetAll();
|
||||
}
|
||||
|
||||
if (EmuFolders::Textures != old_textures_directory)
|
||||
{
|
||||
GetMTGS().RunOnGSThread([]() {
|
||||
if (VMManager::HasValidVM())
|
||||
GSTextureReplacements::ReloadReplacementMap();
|
||||
});
|
||||
}
|
||||
|
||||
if (EmuFolders::Videos != old_videos_directory)
|
||||
{
|
||||
if (VMManager::HasValidVM())
|
||||
GetMTGS().RunOnGSThread(&GSEndCapture);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+37
-65
@@ -15,92 +15,68 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "Counters.h"
|
||||
#include "ImGui/FullscreenUI.h"
|
||||
#include "ImGui/ImGuiManager.h"
|
||||
#include "GS.h"
|
||||
#include "GSCapture.h"
|
||||
#include "GSGL.h"
|
||||
#include "GSUtil.h"
|
||||
#include "GSExtra.h"
|
||||
#include "Renderers/Null/GSRendererNull.h"
|
||||
#include "Renderers/HW/GSRendererHW.h"
|
||||
#include "Renderers/HW/GSTextureReplacements.h"
|
||||
#include "GSGL.h"
|
||||
#include "GSLzma.h"
|
||||
#include "GSUtil.h"
|
||||
#include "Host.h"
|
||||
#include "Input/InputManager.h"
|
||||
#include "MultiISA.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "GS/Renderers/Null/GSRendererNull.h"
|
||||
#include "GS/Renderers/HW/GSRendererHW.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "GS/Renderers/OpenGL/GSDeviceOGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "GS/Renderers/Metal/GSMetalCPPAccessible.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VULKAN
|
||||
#include "GS/Renderers/Vulkan/GSDeviceVK.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "GS/Renderers/DX11/GSDevice11.h"
|
||||
#include "GS/Renderers/DX12/GSDevice12.h"
|
||||
#include "GS/Renderers/DX11/D3D.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "pcsx2/Config.h"
|
||||
#include "pcsx2/Counters.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Frontend/FullscreenUI.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/GS.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "Renderers/OpenGL/GSDeviceOGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "Renderers/Metal/GSMetalCPPAccessible.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VULKAN
|
||||
#include "Renderers/Vulkan/GSDeviceVK.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "Renderers/DX11/GSDevice11.h"
|
||||
#include "Renderers/DX12/GSDevice12.h"
|
||||
#include "GS/Renderers/DX11/D3D.h"
|
||||
|
||||
|
||||
static HRESULT s_hr = E_FAIL;
|
||||
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
|
||||
// do NOT undefine this/put it above includes, as x11 people love to redefine
|
||||
// things that make obscure compiler bugs, unless you want to run around and
|
||||
// debug obscure compiler errors --govanify
|
||||
#undef None
|
||||
|
||||
Pcsx2Config::GSOptions GSConfig;
|
||||
|
||||
static u64 s_next_manual_present_time;
|
||||
|
||||
int GSinit()
|
||||
void GSinit()
|
||||
{
|
||||
GSVertexSW::InitStatic();
|
||||
|
||||
GSUtil::Init();
|
||||
|
||||
#ifdef _WIN32
|
||||
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GSshutdown()
|
||||
{
|
||||
GSclose();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (SUCCEEDED(s_hr))
|
||||
{
|
||||
::CoUninitialize();
|
||||
|
||||
s_hr = E_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ensure all screenshots have been saved
|
||||
GSJoinSnapshotThreads();
|
||||
}
|
||||
@@ -189,7 +165,7 @@ static bool OpenGSDevice(GSRendererType renderer, bool clear_state_on_fail, bool
|
||||
return false;
|
||||
}
|
||||
|
||||
GSConfig.OsdShowGPU = EmuConfig.GS.OsdShowGPU && g_gs_device->SetGPUTimingEnabled(true);
|
||||
GSConfig.OsdShowGPU = GSConfig.OsdShowGPU && g_gs_device->SetGPUTimingEnabled(true);
|
||||
|
||||
Console.WriteLn(Color_StrongGreen, "%s Graphics Driver Info:", GSDevice::RenderAPIToString(new_api));
|
||||
Console.Indent().WriteLn(g_gs_device->GetDriverInfo());
|
||||
@@ -348,7 +324,7 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b
|
||||
Host::ReportErrorAsync(
|
||||
"Error", fmt::format("Failed to create render device. This may be due to your GPU not supporting the "
|
||||
"chosen renderer ({}), or because your graphics drivers need to be updated.",
|
||||
Pcsx2Config::GSOptions::GetRendererName(EmuConfig.GS.Renderer)));
|
||||
Pcsx2Config::GSOptions::GetRendererName(GSConfig.Renderer)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -774,8 +750,7 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
}
|
||||
|
||||
// Options which aren't using the global struct yet, so we need to recreate all GS objects.
|
||||
if (
|
||||
GSConfig.SWExtraThreads != old_config.SWExtraThreads ||
|
||||
if (GSConfig.SWExtraThreads != old_config.SWExtraThreads ||
|
||||
GSConfig.SWExtraThreadsHeight != old_config.SWExtraThreadsHeight)
|
||||
{
|
||||
if (!GSreopen(false, true, old_config))
|
||||
@@ -784,10 +759,7 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
return;
|
||||
}
|
||||
|
||||
// This is where we would do finer-grained checks in the future.
|
||||
// For example, flushing the texture cache when mipmap settings change.
|
||||
|
||||
if (GSConfig.CRCHack != old_config.CRCHack ||
|
||||
if (GSConfig.UserHacks_DisableRenderFixes != old_config.UserHacks_DisableRenderFixes ||
|
||||
GSConfig.UpscaleMultiplier != old_config.UpscaleMultiplier ||
|
||||
GSConfig.GetSkipCountFunctionId != old_config.GetSkipCountFunctionId ||
|
||||
GSConfig.BeforeDrawFunctionId != old_config.BeforeDrawFunctionId)
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class HostDisplay;
|
||||
s16 GSLookupGetSkipCountFunctionId(const std::string_view& name);
|
||||
s16 GSLookupBeforeDrawFunctionId(const std::string_view& name);
|
||||
|
||||
int GSinit();
|
||||
void GSinit();
|
||||
void GSshutdown();
|
||||
bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* basemem);
|
||||
bool GSreopen(bool recreate_device, bool recreate_renderer, const Pcsx2Config::GSOptions& old_config);
|
||||
|
||||
@@ -33,4 +33,8 @@
|
||||
<DisplayString Condition="m_type == 0">{{ RT @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
|
||||
<DisplayString Condition="m_type == 1">{{ Depth @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
|
||||
</Type>
|
||||
|
||||
<Type Name="GSTextureCache::SourceRegion">
|
||||
<DisplayString>{{ Min=({(s16)(bits & 0xFFFF)},{(s16)((bits >> 32) & 0xFFFF)}} Max={(s16)((bits >> 16) & 0xFFFF)},{(s16)((bits >> 48) & 0xFFFF)}) }}</DisplayString>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
|
||||
+6
-40
@@ -14,10 +14,12 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSCrc.h"
|
||||
#include "GSExtra.h"
|
||||
#include "GS.h"
|
||||
#include "HostSettings.h"
|
||||
|
||||
#include "GS/GSCrc.h"
|
||||
#include "GS/GSExtra.h"
|
||||
#include "GS/GS.h"
|
||||
#include "Host.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
const CRC::Game CRC::m_games[] =
|
||||
@@ -31,42 +33,6 @@ const CRC::Game CRC::m_games[] =
|
||||
{0x5C991F4E, ICO /* EU */},
|
||||
{0x788D8B4F, ICO /* EU */},
|
||||
{0x29C28734, ICO /* CH */},
|
||||
{0x60013EBD, PolyphonyDigitalGames /* EU */}, // Gran Turismo Concept
|
||||
{0x6810C3BC, PolyphonyDigitalGames /* CH */}, // Gran Turismo Concept 2002 Tokyo-Geneva
|
||||
{0x0EEF32A3, PolyphonyDigitalGames /* KO */}, // Gran Turismo Concept 2002 Tokyo-Seoul
|
||||
{0x3E9D448A, PolyphonyDigitalGames /* CH */}, // GT3
|
||||
{0xAD66643C, PolyphonyDigitalGames /* CH */}, // GT3
|
||||
{0x85AE91B3, PolyphonyDigitalGames /* US */}, // GT3
|
||||
{0x8AA991B0, PolyphonyDigitalGames /* US */}, // GT3
|
||||
{0xC220951A, PolyphonyDigitalGames /* JP */}, // GT3
|
||||
{0x9DE5CF65, PolyphonyDigitalGames /* JP */}, // GT3
|
||||
{0x706DFF80, PolyphonyDigitalGames /* JP */}, // GT3 Store Disc Vol. 2
|
||||
{0x55CE5111, PolyphonyDigitalGames /* JP */}, // Gran Turismo 2000 Body Omen
|
||||
{0xE9A7E08D, PolyphonyDigitalGames /* JP */}, // Gran Turismo 2000 Body Omen
|
||||
{0xB590CE04, PolyphonyDigitalGames /* EU */}, // GT3
|
||||
{0xC02C653E, PolyphonyDigitalGames /* CH */}, // GT4
|
||||
{0x7ABDBB5E, PolyphonyDigitalGames /* CH */}, // GT4
|
||||
{0xAEAD1CA3, PolyphonyDigitalGames /* JP */}, // GT4
|
||||
{0xA3AF15A0, PolyphonyDigitalGames /* JP */}, // GT4 PS2 Racing Pack
|
||||
{0xE906EA37, PolyphonyDigitalGames /* JP */}, // GT4 First Preview
|
||||
{0xCA6243B9, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
|
||||
{0xDD764BBE, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
|
||||
{0xE1258846, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
|
||||
{0x27B8F05F, PolyphonyDigitalGames /* JP */}, // GT4 Prius Trial Version
|
||||
{0x30E41D93, PolyphonyDigitalGames /* KO */}, // GT4
|
||||
{0x715CF2EC, PolyphonyDigitalGames /* EU */}, // GT4
|
||||
{0x44A61C8F, PolyphonyDigitalGames /* EU */}, // GT4
|
||||
{0x0086E35B, PolyphonyDigitalGames /* EU */}, // GT4
|
||||
{0x3FB69323, PolyphonyDigitalGames /* EU */}, // GT4 Prologue
|
||||
{0x77E61C8A, PolyphonyDigitalGames /* US */}, // GT4
|
||||
{0x33C6E35E, PolyphonyDigitalGames /* US */}, // GT4
|
||||
{0x70538747, PolyphonyDigitalGames /* US */}, // GT4 Toyota Prius Trial
|
||||
{0x32A1C752, PolyphonyDigitalGames /* US */}, // GT4 Online Beta
|
||||
{0x2A84A1E2, PolyphonyDigitalGames /* US */}, // GT4 Mazda MX-5 Edition
|
||||
{0x0087EEC4, PolyphonyDigitalGames /* NoRegion */}, // GT4 Online Beta, JP and US versions have the same CRC
|
||||
{0x5AC7E79C, PolyphonyDigitalGames /* CH */}, // TouristTrophy
|
||||
{0xFF9C0E93, PolyphonyDigitalGames /* US */}, // TouristTrophy
|
||||
{0xCA9AA903, PolyphonyDigitalGames /* EU */}, // TouristTrophy
|
||||
{0xFC46EA61, Tekken5 /* JP */},
|
||||
{0x1F88EE37, Tekken5 /* EU */},
|
||||
{0x1F88BECD, Tekken5 /* EU */}, // language selector...
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
NoTitle,
|
||||
GetawayGames,
|
||||
ICO,
|
||||
PolyphonyDigitalGames,
|
||||
SMTNocturne,
|
||||
Tekken5,
|
||||
TitleCount,
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
|
||||
struct
|
||||
{
|
||||
GSVector4 in;
|
||||
GSVector4i in;
|
||||
GSVector4i ex;
|
||||
GSVector4i ofxy;
|
||||
} scissor;
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
scissor.ex.U16[2] = (u16)((SCISSOR.SCAX1 << 4) + XYOFFSET.OFX - 0x8000);
|
||||
scissor.ex.U16[3] = (u16)((SCISSOR.SCAY1 << 4) + XYOFFSET.OFY - 0x8000);
|
||||
|
||||
scissor.in = GSVector4(
|
||||
scissor.in = GSVector4i(
|
||||
(int)SCISSOR.SCAX0,
|
||||
(int)SCISSOR.SCAY0,
|
||||
(int)SCISSOR.SCAX1 + 1,
|
||||
|
||||
@@ -131,12 +131,6 @@ __fi static T VectorAlign(T value)
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifdef __POSIX__
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include <zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ALIGN_STACK(n) alignas(n) int dummy__; (void)dummy__;
|
||||
#else
|
||||
@@ -149,17 +143,3 @@ __fi static T VectorAlign(T value)
|
||||
#define ALIGN_STACK(n) alignas(n) int dummy__;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VTUNE
|
||||
#include "jitprofiling.h"
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "jitprofiling.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DIRECTORY_SEPARATOR '\\'
|
||||
#else
|
||||
#include <sys/stat.h> // mkdir
|
||||
#define DIRECTORY_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
@@ -453,6 +453,22 @@ bool GSLocalMemory::IsPageAligned(u32 psm, const GSVector4i& rc)
|
||||
return (rc & pgmsk).eq(GSVector4i::zero());
|
||||
}
|
||||
|
||||
u32 GSLocalMemory::GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect)
|
||||
{
|
||||
u32 result = m_psm[psm].info.bn(rect.z - 1, rect.w - 1, bp, bw); // Valid only for color formats
|
||||
|
||||
// If rect is page aligned, we can assume it's the start of the next block-1 as the max block position.
|
||||
// Using real end point for Z formats causes problems because it's a lower value.
|
||||
const GSVector2i page_size = GSLocalMemory::m_psm[psm].pgs;
|
||||
if ((rect.z & (page_size.x - 1)) == 0 && (rect.w & (page_size.y - 1)) == 0)
|
||||
{
|
||||
constexpr u32 page_mask = (1 << 5) - 1;
|
||||
result = (((result + page_mask) & ~page_mask)) - 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void GSLocalMemory::ReadTexture(const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA)
|
||||
|
||||
@@ -546,6 +546,7 @@ public:
|
||||
GSPixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
|
||||
std::vector<GSVector2i>* GetPage2TileMap(const GIFRegTEX0& TEX0);
|
||||
static bool IsPageAligned(u32 psm, const GSVector4i& rc);
|
||||
static u32 GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect);
|
||||
|
||||
// address
|
||||
|
||||
|
||||
+17
-6
@@ -827,7 +827,15 @@ void GSState::ApplyTEX0(GIFRegTEX0& TEX0)
|
||||
m_mem.m_clut.ClearDrawInvalidity();
|
||||
CLUTAutoFlush(PRIM->PRIM);
|
||||
}
|
||||
|
||||
Flush(GSFlushReason::CLUTCHANGE);
|
||||
|
||||
// Abort any channel shuffle skipping, since this is likely part of a new shuffle.
|
||||
// Test case: Tomb Raider series. This is gated by the CBP actually changing, because
|
||||
// Urban Chaos writes to the memory backing the CLUT in the middle of a shuffle, and
|
||||
// it's unclear whether the CLUT would actually get reloaded in that case.
|
||||
if (TEX0.CBP != m_mem.m_clut.GetCLUTCBP())
|
||||
m_channel_shuffle = false;
|
||||
}
|
||||
|
||||
TEX0.CPSM &= 0xa; // 1010b
|
||||
@@ -2579,7 +2587,7 @@ void GSState::SetGameCRC(u32 crc)
|
||||
|
||||
void GSState::UpdateCRCHacks()
|
||||
{
|
||||
m_game = CRC::Lookup((GSConfig.CRCHack != CRCHackLevel::Off) ? m_crc : 0);
|
||||
m_game = CRC::Lookup(GSConfig.UserHacks_DisableRenderFixes ? 0 : m_crc);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2600,6 +2608,7 @@ void GSState::UpdateScissor()
|
||||
{
|
||||
m_scissor = m_context->scissor.ex;
|
||||
m_ofxy = m_context->scissor.ofxy;
|
||||
m_scissor_invalid = !m_context->scissor.in.gt32(m_context->scissor.in.zwzw()).allfalse();
|
||||
}
|
||||
|
||||
void GSState::UpdateVertexKick()
|
||||
@@ -2956,7 +2965,7 @@ __forceinline void GSState::HandleAutoFlush()
|
||||
tex_rect += GSVector4i(0, 0, 0, 1);
|
||||
|
||||
const GSVector2i offset = GSVector2i(m_context->XYOFFSET.OFX, m_context->XYOFFSET.OFY);
|
||||
const GSVector4i scissor = GSVector4i(m_context->scissor.in);
|
||||
const GSVector4i scissor = m_context->scissor.in;
|
||||
GSVector4i old_tex_rect = GSVector4i::zero();
|
||||
int current_draw_end = m_index.tail;
|
||||
|
||||
@@ -3009,7 +3018,7 @@ __forceinline void GSState::HandleAutoFlush()
|
||||
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(m_context->scissor.in);
|
||||
area_out = area_out & page_mask;
|
||||
area_out += GSVector4i(0, 0, 1, 1); // Intersect goes on space inside the rect
|
||||
area_out.z += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x;
|
||||
@@ -3110,6 +3119,9 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
if (m < n)
|
||||
return;
|
||||
|
||||
// Skip draws when scissor is out of range (i.e. bottom-right is less than top-left), since everything will get clipped.
|
||||
skip |= static_cast<u32>(m_scissor_invalid);
|
||||
|
||||
if (skip == 0 && (prim != GS_TRIANGLEFAN || m <= 4)) // m_vertex.xy only knows about the last 4 vertices, head could be far behind for fan
|
||||
{
|
||||
GSVector4i pmin, pmax;
|
||||
@@ -3333,8 +3345,7 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
}
|
||||
}
|
||||
|
||||
const GSVector4i scissor = GSVector4i(m_context->scissor.in);
|
||||
temp_draw_rect = min.upl64(max).rintersect(scissor);
|
||||
temp_draw_rect = min.upl64(max).rintersect(m_context->scissor.in);
|
||||
}
|
||||
|
||||
CLUTAutoFlush(prim);
|
||||
@@ -3498,7 +3509,7 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
|
||||
// When coordinates are fractional, GS appears to draw to the right/bottom (effectively
|
||||
// taking the ceiling), not to the top/left (taking the floor).
|
||||
const GSVector4i int_rc(m_vt.m_min.p.ceil().xyxy(m_vt.m_max.p.floor()));
|
||||
const GSVector4i scissored_rc(int_rc.rintersect(GSVector4i(m_context->scissor.in)));
|
||||
const GSVector4i scissored_rc(int_rc.rintersect(m_context->scissor.in));
|
||||
if (!int_rc.eq(scissored_rc))
|
||||
{
|
||||
// draw will get scissored, adjust UVs to suit
|
||||
|
||||
+40
-22
@@ -222,10 +222,12 @@ public:
|
||||
u32 m_crc = 0;
|
||||
CRC::Game m_game = {};
|
||||
std::unique_ptr<GSDumpBase> m_dump;
|
||||
bool m_scissor_invalid = false;
|
||||
bool m_nativeres = false;
|
||||
bool m_mipmap = false;
|
||||
bool m_texflush_flag = false;
|
||||
bool m_isPackedUV_HackFlag = false;
|
||||
bool m_channel_shuffle = false;
|
||||
u8 m_scanmask_used = 0;
|
||||
u8 m_force_preload = 0;
|
||||
u32 m_dirty_gs_regs = 0;
|
||||
@@ -540,16 +542,10 @@ public:
|
||||
GSVector4i out_rect = PCRTCDisplays[display].framebufferRect;
|
||||
|
||||
if (out_rect.z >= 2048)
|
||||
{
|
||||
out_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.x;
|
||||
out_rect.x = 0;
|
||||
}
|
||||
out_rect.z -= out_rect.x;
|
||||
|
||||
if (out_rect.w >= 2048)
|
||||
{
|
||||
out_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.y;
|
||||
out_rect.y = 0;
|
||||
}
|
||||
out_rect.w -= out_rect.y;
|
||||
|
||||
// Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy.
|
||||
const int min_mag = std::max(1, PCRTCDisplays[display].magnification.y);
|
||||
@@ -563,12 +559,6 @@ public:
|
||||
offset = (max_height / min_mag) - offset;
|
||||
out_rect.w = std::min(out_rect.w, offset);
|
||||
|
||||
// Hardware mode needs a wider framebuffer as it can't offset the read.
|
||||
if (GSConfig.UseHardwareRenderer())
|
||||
{
|
||||
out_rect.z += PCRTCDisplays[display].framebufferOffsets.x;
|
||||
out_rect.w += PCRTCDisplays[display].framebufferOffsets.y;
|
||||
}
|
||||
return GSVector2i(out_rect.z, out_rect.w);
|
||||
}
|
||||
}
|
||||
@@ -645,21 +635,45 @@ public:
|
||||
{
|
||||
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc && !scanmask)
|
||||
{
|
||||
if (abs(PCRTCDisplays[1].framebufferOffsets.y - PCRTCDisplays[0].framebufferOffsets.y) == 1
|
||||
GSVector2i fb0 = GSVector2i(PCRTCDisplays[0].framebufferOffsets.x, PCRTCDisplays[0].framebufferOffsets.y);
|
||||
GSVector2i fb1 = GSVector2i(PCRTCDisplays[1].framebufferOffsets.x, PCRTCDisplays[1].framebufferOffsets.y);
|
||||
|
||||
if (fb0.x + PCRTCDisplays[0].displayRect.z > 2048)
|
||||
{
|
||||
fb0.x -= 2048;
|
||||
fb0.x = abs(fb0.x);
|
||||
}
|
||||
if (fb0.y + PCRTCDisplays[0].displayRect.w > 2048)
|
||||
{
|
||||
fb0.y -= 2048;
|
||||
fb0.y = abs(fb0.y);
|
||||
}
|
||||
if (fb1.x + PCRTCDisplays[1].displayRect.z > 2048)
|
||||
{
|
||||
fb1.x -= 2048;
|
||||
fb1.x = abs(fb1.x);
|
||||
}
|
||||
if (fb1.y + PCRTCDisplays[1].displayRect.w > 2048)
|
||||
{
|
||||
fb1.y -= 2048;
|
||||
fb1.y = abs(fb1.y);
|
||||
}
|
||||
|
||||
if (abs(fb1.y - fb0.y) == 1
|
||||
&& PCRTCDisplays[0].displayRect.y == PCRTCDisplays[1].displayRect.y)
|
||||
{
|
||||
if (PCRTCDisplays[1].framebufferOffsets.y < PCRTCDisplays[0].framebufferOffsets.y)
|
||||
PCRTCDisplays[0].framebufferOffsets.y = PCRTCDisplays[1].framebufferOffsets.y;
|
||||
if (fb1.y < fb0.y)
|
||||
PCRTCDisplays[0].framebufferOffsets.y = fb1.y;
|
||||
else
|
||||
PCRTCDisplays[1].framebufferOffsets.y = PCRTCDisplays[0].framebufferOffsets.y;
|
||||
PCRTCDisplays[1].framebufferOffsets.y = fb0.y;
|
||||
}
|
||||
if (abs(PCRTCDisplays[1].framebufferOffsets.x - PCRTCDisplays[0].framebufferOffsets.x) == 1
|
||||
if (abs(fb1.x - fb0.x) == 1
|
||||
&& PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x)
|
||||
{
|
||||
if (PCRTCDisplays[1].framebufferOffsets.x < PCRTCDisplays[0].framebufferOffsets.x)
|
||||
PCRTCDisplays[0].framebufferOffsets.x = PCRTCDisplays[1].framebufferOffsets.x;
|
||||
if (fb1.x < fb0.x)
|
||||
PCRTCDisplays[0].framebufferOffsets.x = fb1.x;
|
||||
else
|
||||
PCRTCDisplays[1].framebufferOffsets.x = PCRTCDisplays[0].framebufferOffsets.x;
|
||||
PCRTCDisplays[1].framebufferOffsets.x = fb0.x;
|
||||
}
|
||||
}
|
||||
PCRTCDisplays[0].framebufferRect.x += PCRTCDisplays[0].framebufferOffsets.x;
|
||||
@@ -683,11 +697,15 @@ public:
|
||||
{
|
||||
if (PCRTCDisplays[display].framebufferRect.z >= 2048)
|
||||
{
|
||||
PCRTCDisplays[display].displayRect.x += 2048 - PCRTCDisplays[display].framebufferRect.x;
|
||||
PCRTCDisplays[display].displayRect.z += 2048 - PCRTCDisplays[display].framebufferRect.x;
|
||||
PCRTCDisplays[display].framebufferRect.x = 0;
|
||||
PCRTCDisplays[display].framebufferRect.z -= 2048;
|
||||
}
|
||||
if (PCRTCDisplays[display].framebufferRect.w >= 2048)
|
||||
{
|
||||
PCRTCDisplays[display].displayRect.y += 2048 - PCRTCDisplays[display].framebufferRect.y;
|
||||
PCRTCDisplays[display].displayRect.w += 2048 - PCRTCDisplays[display].framebufferRect.y;
|
||||
PCRTCDisplays[display].framebufferRect.y = 0;
|
||||
PCRTCDisplays[display].framebufferRect.w -= 2048;
|
||||
}
|
||||
|
||||
@@ -196,11 +196,6 @@ u32 GSUtil::GetChannelMask(u32 spsm)
|
||||
}
|
||||
}
|
||||
|
||||
CRCHackLevel GSUtil::GetRecommendedCRCHackLevel(GSRendererType type)
|
||||
{
|
||||
return (type == GSRendererType::DX11 || type == GSRendererType::DX12) ? CRCHackLevel::Full : CRCHackLevel::Partial;
|
||||
}
|
||||
|
||||
GSRendererType GSUtil::GetPreferredRenderer()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
|
||||
@@ -35,7 +35,6 @@ public:
|
||||
static bool HasSameSwizzleBits(u32 spsm, u32 dpsm);
|
||||
static u32 GetChannelMask(u32 spsm);
|
||||
|
||||
static CRCHackLevel GetRecommendedCRCHackLevel(GSRendererType type);
|
||||
static GSRendererType GetPreferredRenderer();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -14,11 +14,12 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSDevice.h"
|
||||
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/GSGL.h"
|
||||
#include "GS/GS.h"
|
||||
#include "Host.h"
|
||||
#include "HostSettings.h"
|
||||
|
||||
#include "common/Align.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
|
||||
@@ -754,7 +754,7 @@ protected:
|
||||
static constexpr u32 MAX_POOLED_TEXTURES = 300;
|
||||
static constexpr u32 MAX_TEXTURE_AGE = 10;
|
||||
static constexpr u32 NUM_CAS_CONSTANTS = 12; // 8 plus src offset x/y, 16 byte alignment
|
||||
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u16) * 65532 * 6;
|
||||
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u16) * 16383 * 6;
|
||||
|
||||
WindowInfo m_window_info;
|
||||
VsyncMode m_vsync_mode = VsyncMode::Off;
|
||||
@@ -881,7 +881,6 @@ public:
|
||||
virtual void ClearRenderTarget(GSTexture* t, u32 c) = 0;
|
||||
virtual void InvalidateRenderTarget(GSTexture* t) = 0;
|
||||
virtual void ClearDepth(GSTexture* t) = 0;
|
||||
virtual void ClearStencil(GSTexture* t, u8 c) = 0;
|
||||
|
||||
virtual void PushDebugGroup(const char* fmt, ...) = 0;
|
||||
virtual void PopDebugGroup() = 0;
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/FullscreenUI.h"
|
||||
#include "Frontend/ImGuiManager.h"
|
||||
#include "ImGui/FullscreenUI.h"
|
||||
#include "ImGui/ImGuiManager.h"
|
||||
#include "GS/Renderers/Common/GSRenderer.h"
|
||||
#include "GS/GSCapture.h"
|
||||
#include "GS/GSGL.h"
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "Host.h"
|
||||
#include "PerformanceMetrics.h"
|
||||
#include "pcsx2/Config.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
@@ -34,6 +33,7 @@
|
||||
#include "common/Timer.h"
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
@@ -76,7 +76,7 @@ u32 GSTexture::GetCompressedBytesPerBlock(Format format)
|
||||
1, // Invalid
|
||||
4, // Color/RGBA8
|
||||
8, // HDRColor/RGBA16
|
||||
32, // DepthStencil
|
||||
4, // DepthStencil
|
||||
1, // UNorm8/R8
|
||||
2, // UInt16/R16UI
|
||||
4, // UInt32/R32UI
|
||||
@@ -103,6 +103,19 @@ u32 GSTexture::GetCompressedBlockSize(Format format)
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 GSTexture::CalcUploadPitch(Format format, u32 width)
|
||||
{
|
||||
if (format >= Format::BC1 && format <= Format::BC7)
|
||||
width = Common::AlignUpPow2(width, 4) / 4;
|
||||
|
||||
return width * GetCompressedBytesPerBlock(format);
|
||||
}
|
||||
|
||||
u32 GSTexture::CalcUploadPitch(u32 width) const
|
||||
{
|
||||
return CalcUploadPitch(m_format, width);
|
||||
}
|
||||
|
||||
u32 GSTexture::CalcUploadRowLengthFromPitch(u32 pitch) const
|
||||
{
|
||||
return CalcUploadRowLengthFromPitch(m_format, pitch);
|
||||
|
||||
@@ -106,11 +106,13 @@ public:
|
||||
|
||||
static u32 GetCompressedBytesPerBlock(Format format);
|
||||
static u32 GetCompressedBlockSize(Format format);
|
||||
static u32 CalcUploadPitch(Format format, u32 width);
|
||||
static u32 CalcUploadRowLengthFromPitch(Format format, u32 pitch);
|
||||
static u32 CalcUploadSize(Format format, u32 height, u32 pitch);
|
||||
|
||||
u32 GetCompressedBytesPerBlock() const;
|
||||
u32 GetCompressedBlockSize() const;
|
||||
u32 CalcUploadPitch(u32 width) const;
|
||||
u32 CalcUploadRowLengthFromPitch(u32 pitch) const;
|
||||
u32 CalcUploadSize(u32 height, u32 pitch) const;
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ bool GSDevice11::Create()
|
||||
}
|
||||
}
|
||||
|
||||
SetFeatures();
|
||||
SetFeatures(dxgi_adapter.get());
|
||||
|
||||
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/dx11/tfx.fx");
|
||||
if (!shader.has_value())
|
||||
@@ -532,7 +532,7 @@ void GSDevice11::Destroy()
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSDevice11::SetFeatures()
|
||||
void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
|
||||
{
|
||||
// Check all three formats, since the feature means any can be used.
|
||||
m_features.dxt_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC1_UNORM) &&
|
||||
@@ -542,7 +542,21 @@ void GSDevice11::SetFeatures()
|
||||
m_features.bptc_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC7_UNORM);
|
||||
|
||||
const D3D_FEATURE_LEVEL feature_level = m_dev->GetFeatureLevel();
|
||||
m_features.vs_expand = (feature_level >= D3D_FEATURE_LEVEL_11_0);
|
||||
m_features.vs_expand = (!GSConfig.DisableVertexShaderExpand && feature_level >= D3D_FEATURE_LEVEL_11_0);
|
||||
|
||||
// NVIDIA GPUs prior to Kepler appear to have broken vertex shader buffer loading.
|
||||
if (m_features.vs_expand && (D3D::GetVendorID(adapter) == D3D::VendorID::Nvidia))
|
||||
{
|
||||
// There's nothing Fermi specific which we can query in DX11. Closest we have is typed UAV loads,
|
||||
// which is Kepler+. Anyone using Kepler should be using Vulkan anyway.
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options;
|
||||
if (SUCCEEDED(m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &options, sizeof(options))) &&
|
||||
!options.TypedUAVLoadAdditionalFormats)
|
||||
{
|
||||
Console.Warning("Disabling VS expand due to potentially buggy NVIDIA driver.");
|
||||
m_features.vs_expand = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GSDevice11::HasSurface() const
|
||||
@@ -602,7 +616,7 @@ bool GSDevice11::CreateSwapChain()
|
||||
m_is_exclusive_fullscreen = false;
|
||||
}
|
||||
|
||||
m_using_flip_model_swap_chain = !EmuConfig.GS.UseBlitSwapChain || m_is_exclusive_fullscreen;
|
||||
m_using_flip_model_swap_chain = !GSConfig.UseBlitSwapChain || m_is_exclusive_fullscreen;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
||||
swap_chain_desc.Width = static_cast<u32>(client_rc.right - client_rc.left);
|
||||
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
NUM_TIMESTAMP_QUERIES = 5,
|
||||
};
|
||||
|
||||
void SetFeatures();
|
||||
void SetFeatures(IDXGIAdapter1* adapter);
|
||||
|
||||
bool CreateSwapChain();
|
||||
bool CreateSwapChainRTV();
|
||||
@@ -313,7 +313,7 @@ public:
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t) override;
|
||||
void ClearStencil(GSTexture* t, u8 c) override;
|
||||
void ClearStencil(GSTexture* t, u8 c);
|
||||
|
||||
void PushDebugGroup(const char* fmt, ...) override;
|
||||
void PopDebugGroup() override;
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GS/Renderers/DX12/D3D12Context.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/General.h"
|
||||
#include "common/ScopedGuard.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "D3D12MemAlloc.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -665,45 +668,6 @@ bool D3D12Context::AllocatePreinitializedGPUBuffer(u32 size, ID3D12Resource** gp
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 D3D12::GetTexelSize(DXGI_FORMAT format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||
case DXGI_FORMAT_BC1_UNORM:
|
||||
case DXGI_FORMAT_BC2_UNORM:
|
||||
case DXGI_FORMAT_BC3_UNORM:
|
||||
case DXGI_FORMAT_BC7_UNORM:
|
||||
return 16;
|
||||
|
||||
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
||||
return 4;
|
||||
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_R8G8B8A8_SNORM:
|
||||
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
|
||||
case DXGI_FORMAT_R32_UINT:
|
||||
case DXGI_FORMAT_R32_SINT:
|
||||
return 4;
|
||||
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||
case DXGI_FORMAT_B5G6R5_UNORM:
|
||||
case DXGI_FORMAT_R16_UINT:
|
||||
case DXGI_FORMAT_R16_SINT:
|
||||
return 2;
|
||||
|
||||
case DXGI_FORMAT_A8_UNORM:
|
||||
case DXGI_FORMAT_R8_UNORM:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
pxFailRel("Unknown format");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void D3D12::SetObjectName(ID3D12Object* object, const char* name)
|
||||
|
||||
@@ -217,8 +217,6 @@ extern std::unique_ptr<D3D12Context> g_d3d12_context;
|
||||
|
||||
namespace D3D12
|
||||
{
|
||||
u32 GetTexelSize(DXGI_FORMAT format);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void SetObjectName(ID3D12Object* object, const char* name);
|
||||
|
||||
@@ -1,508 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GS/Renderers/DX12/D3D12Texture.h"
|
||||
#include "GS/Renderers/DX12/D3D12Context.h"
|
||||
|
||||
#include "common/Align.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "D3D12MemAlloc.h"
|
||||
|
||||
D3D12Texture::D3D12Texture() = default;
|
||||
|
||||
D3D12Texture::D3D12Texture(ID3D12Resource* resource, D3D12_RESOURCE_STATES state)
|
||||
: m_resource(std::move(resource))
|
||||
{
|
||||
const D3D12_RESOURCE_DESC desc = GetDesc();
|
||||
m_width = static_cast<u32>(desc.Width);
|
||||
m_height = desc.Height;
|
||||
m_levels = desc.MipLevels;
|
||||
m_format = desc.Format;
|
||||
}
|
||||
|
||||
D3D12Texture::D3D12Texture(D3D12Texture&& texture)
|
||||
: m_resource(std::move(texture.m_resource))
|
||||
, m_allocation(std::move(texture.m_allocation))
|
||||
, m_srv_descriptor(texture.m_srv_descriptor)
|
||||
, m_write_descriptor(texture.m_write_descriptor)
|
||||
, m_width(texture.m_width)
|
||||
, m_height(texture.m_height)
|
||||
, m_levels(texture.m_levels)
|
||||
, m_format(texture.m_format)
|
||||
, m_state(texture.m_state)
|
||||
, m_write_descriptor_type(texture.m_write_descriptor_type)
|
||||
{
|
||||
texture.m_srv_descriptor = {};
|
||||
texture.m_write_descriptor = {};
|
||||
texture.m_width = 0;
|
||||
texture.m_height = 0;
|
||||
texture.m_levels = 0;
|
||||
texture.m_format = DXGI_FORMAT_UNKNOWN;
|
||||
texture.m_state = D3D12_RESOURCE_STATE_COMMON;
|
||||
texture.m_write_descriptor_type = WriteDescriptorType::None;
|
||||
}
|
||||
|
||||
D3D12Texture::~D3D12Texture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
D3D12Texture& D3D12Texture::operator=(D3D12Texture&& texture)
|
||||
{
|
||||
Destroy();
|
||||
m_resource = std::move(texture.m_resource);
|
||||
m_allocation = std::move(texture.m_allocation);
|
||||
m_srv_descriptor = texture.m_srv_descriptor;
|
||||
m_write_descriptor = texture.m_write_descriptor;
|
||||
m_width = texture.m_width;
|
||||
m_height = texture.m_height;
|
||||
m_levels = texture.m_levels;
|
||||
m_format = texture.m_format;
|
||||
m_state = texture.m_state;
|
||||
m_write_descriptor_type = texture.m_write_descriptor_type;
|
||||
texture.m_srv_descriptor = {};
|
||||
texture.m_write_descriptor = {};
|
||||
texture.m_width = 0;
|
||||
texture.m_height = 0;
|
||||
texture.m_levels = 0;
|
||||
texture.m_format = DXGI_FORMAT_UNKNOWN;
|
||||
texture.m_state = D3D12_RESOURCE_STATE_COMMON;
|
||||
texture.m_write_descriptor_type = WriteDescriptorType::None;
|
||||
return *this;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC D3D12Texture::GetDesc() const
|
||||
{
|
||||
return m_resource->GetDesc();
|
||||
}
|
||||
|
||||
bool D3D12Texture::Create(u32 width, u32 height, u32 levels, DXGI_FORMAT format, DXGI_FORMAT srv_format,
|
||||
DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format, D3D12_RESOURCE_FLAGS flags, u32 alloc_flags)
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = levels;
|
||||
desc.Format = format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
desc.Flags = flags;
|
||||
|
||||
D3D12_CLEAR_VALUE optimized_clear_value = {};
|
||||
D3D12_RESOURCE_STATES state;
|
||||
if (rtv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
optimized_clear_value.Format = rtv_format;
|
||||
state = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
}
|
||||
else if (dsv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
optimized_clear_value.Format = dsv_format;
|
||||
state = D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
}
|
||||
|
||||
D3D12MA::ALLOCATION_DESC allocationDesc = {};
|
||||
allocationDesc.Flags = static_cast<D3D12MA::ALLOCATION_FLAGS>(alloc_flags) | D3D12MA::ALLOCATION_FLAG_WITHIN_BUDGET;
|
||||
allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
ComPtr<ID3D12Resource> resource;
|
||||
ComPtr<D3D12MA::Allocation> allocation;
|
||||
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocationDesc, &desc, state,
|
||||
(rtv_format != DXGI_FORMAT_UNKNOWN || dsv_format != DXGI_FORMAT_UNKNOWN) ? &optimized_clear_value : nullptr,
|
||||
allocation.put(), IID_PPV_ARGS(resource.put()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// OOM isn't fatal.
|
||||
if (hr != E_OUTOFMEMORY)
|
||||
Console.Error("Create texture failed: 0x%08X", hr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12DescriptorHandle srv_descriptor, write_descriptor;
|
||||
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
|
||||
if (srv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (!CreateSRVDescriptor(resource.get(), levels, srv_format, &srv_descriptor))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rtv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
pxAssert(dsv_format == DXGI_FORMAT_UNKNOWN && !(flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS));
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::RTV;
|
||||
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (dsv_format != DXGI_FORMAT_UNKNOWN && !(flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS))
|
||||
{
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::DSV;
|
||||
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||
{
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::UAV;
|
||||
if (!CreateUAVDescriptor(resource.get(), dsv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Destroy(true);
|
||||
|
||||
m_resource = std::move(resource);
|
||||
m_allocation = std::move(allocation);
|
||||
m_srv_descriptor = std::move(srv_descriptor);
|
||||
m_write_descriptor = std::move(write_descriptor);
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_levels = levels;
|
||||
m_format = format;
|
||||
m_state = state;
|
||||
m_write_descriptor_type = write_descriptor_type;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::Adopt(ComPtr<ID3D12Resource> texture, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
|
||||
DXGI_FORMAT dsv_format, D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
const D3D12_RESOURCE_DESC desc(texture->GetDesc());
|
||||
|
||||
D3D12DescriptorHandle srv_descriptor, write_descriptor;
|
||||
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
|
||||
if (srv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (!CreateSRVDescriptor(texture.get(), desc.MipLevels, srv_format, &srv_descriptor))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rtv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
pxAssert(dsv_format == DXGI_FORMAT_UNKNOWN);
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::RTV;
|
||||
if (!CreateRTVDescriptor(texture.get(), rtv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (dsv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::DSV;
|
||||
if (!CreateDSVDescriptor(texture.get(), dsv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||
{
|
||||
write_descriptor_type = D3D12Texture::WriteDescriptorType::UAV;
|
||||
if (!CreateUAVDescriptor(texture.get(), srv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_resource = std::move(texture);
|
||||
m_allocation.reset();
|
||||
m_srv_descriptor = std::move(srv_descriptor);
|
||||
m_write_descriptor = std::move(write_descriptor);
|
||||
m_write_descriptor_type = write_descriptor_type;
|
||||
m_width = static_cast<u32>(desc.Width);
|
||||
m_height = desc.Height;
|
||||
m_levels = desc.MipLevels;
|
||||
m_format = desc.Format;
|
||||
m_state = state;
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12Texture::Destroy(bool defer /* = true */)
|
||||
{
|
||||
if (defer)
|
||||
{
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_srv_descriptor);
|
||||
|
||||
switch (m_write_descriptor_type)
|
||||
{
|
||||
case D3D12Texture::WriteDescriptorType::RTV:
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetRTVHeapManager(), &m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::DSV:
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDSVHeapManager(), &m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::UAV:
|
||||
g_d3d12_context->DeferDescriptorDestruction(
|
||||
g_d3d12_context->GetDescriptorHeapManager(), &m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_d3d12_context->DeferResourceDestruction(m_allocation.get(), m_resource.get());
|
||||
m_resource.reset();
|
||||
m_allocation.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&m_srv_descriptor);
|
||||
|
||||
switch (m_write_descriptor_type)
|
||||
{
|
||||
case D3D12Texture::WriteDescriptorType::RTV:
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::DSV:
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::UAV:
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&m_write_descriptor);
|
||||
break;
|
||||
case D3D12Texture::WriteDescriptorType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_resource.reset();
|
||||
m_allocation.reset();
|
||||
}
|
||||
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_levels = 0;
|
||||
m_format = DXGI_FORMAT_UNKNOWN;
|
||||
m_write_descriptor_type = WriteDescriptorType::None;
|
||||
}
|
||||
|
||||
void D3D12Texture::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_state, state);
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
void D3D12Texture::TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 level,
|
||||
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const
|
||||
{
|
||||
const D3D12_RESOURCE_BARRIER barrier = {D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||
{{m_resource.get(), level, before_state, after_state}}};
|
||||
cmdlist->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* D3D12Texture::BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y,
|
||||
u32 width, u32 height, void** out_data, u32* out_data_pitch)
|
||||
{
|
||||
const u32 copy_pitch = Common::AlignUpPow2(width * D3D12::GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const u32 upload_size = copy_pitch * height;
|
||||
|
||||
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
||||
{
|
||||
DevCon.WriteLn(
|
||||
"Executing command buffer while waiting for %u bytes (%ux%u) in upload buffer", upload_size, width, height);
|
||||
g_d3d12_context->ExecuteCommandList(D3D12Context::WaitType::None);
|
||||
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(
|
||||
upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
|
||||
{
|
||||
Console.Error("Failed to reserve %u bytes for %ux%u upload", upload_size, width, height);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// cmdlist change
|
||||
cmdlist = g_d3d12_context->GetInitCommandList();
|
||||
}
|
||||
|
||||
*out_data = g_d3d12_context->GetTextureStreamBuffer().GetCurrentHostPointer();
|
||||
*out_data_pitch = copy_pitch;
|
||||
return cmdlist;
|
||||
}
|
||||
|
||||
void D3D12Texture::EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height)
|
||||
{
|
||||
const u32 copy_pitch = Common::AlignUpPow2(width * D3D12::GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const u32 upload_size = copy_pitch * height;
|
||||
|
||||
D3D12StreamBuffer& sb = g_d3d12_context->GetTextureStreamBuffer();
|
||||
const u32 sb_offset = sb.GetCurrentOffset();
|
||||
sb.CommitMemory(upload_size);
|
||||
|
||||
CopyFromBuffer(cmdlist, level, x, y, width, height, copy_pitch, sb.GetBuffer(), sb_offset);
|
||||
}
|
||||
|
||||
void D3D12Texture::CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height,
|
||||
u32 pitch, ID3D12Resource* buffer, u32 buffer_offset)
|
||||
{
|
||||
D3D12_TEXTURE_COPY_LOCATION src;
|
||||
src.pResource = buffer;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint.Offset = buffer_offset;
|
||||
src.PlacedFootprint.Footprint.Width = width;
|
||||
src.PlacedFootprint.Footprint.Height = height;
|
||||
src.PlacedFootprint.Footprint.Depth = 1;
|
||||
src.PlacedFootprint.Footprint.RowPitch = pitch;
|
||||
src.PlacedFootprint.Footprint.Format = m_format;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dst;
|
||||
dst.pResource = m_resource.get();
|
||||
dst.SubresourceIndex = level;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
|
||||
const D3D12_BOX src_box{0u, 0u, 0u, width, height, 1u};
|
||||
const D3D12_RESOURCE_STATES old_state = m_state;
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
cmdlist->CopyTextureRegion(&dst, x, y, 0, &src, &src_box);
|
||||
TransitionToState(cmdlist, old_state);
|
||||
}
|
||||
|
||||
static ID3D12Resource* CreateStagingBuffer(u32 height, const void* data, u32 pitch, u32 upload_pitch, u32 upload_size)
|
||||
{
|
||||
wil::com_ptr_nothrow<ID3D12Resource> resource;
|
||||
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation;
|
||||
|
||||
const D3D12MA::ALLOCATION_DESC allocation_desc = {D3D12MA::ALLOCATION_FLAG_NONE, D3D12_HEAP_TYPE_UPLOAD};
|
||||
const D3D12_RESOURCE_DESC resource_desc = {D3D12_RESOURCE_DIMENSION_BUFFER, 0, upload_size, 1, 1, 1,
|
||||
DXGI_FORMAT_UNKNOWN, {1, 0}, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_RESOURCE_FLAG_NONE};
|
||||
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocation_desc, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, allocation.put(), IID_PPV_ARGS(resource.put()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Console.Error("CreateResource() for upload staging buffer failed: %08X", hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* map;
|
||||
const D3D12_RANGE read_range = {};
|
||||
hr = resource->Map(0, &read_range, &map);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Console.Error("Map() for upload staging buffer failed: %08X", hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringUtil::StrideMemCpy(map, upload_pitch, data, pitch, std::min(pitch, upload_pitch), height);
|
||||
|
||||
const D3D12_RANGE write_range = {0u, upload_size};
|
||||
resource->Unmap(0, &write_range);
|
||||
|
||||
// queue them for destruction, since the upload happens in this cmdlist
|
||||
g_d3d12_context->DeferResourceDestruction(allocation.get(), resource.get());
|
||||
|
||||
// AddRef()'ed by the defer above.
|
||||
return resource.get();
|
||||
}
|
||||
|
||||
bool D3D12Texture::LoadData(
|
||||
ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
|
||||
{
|
||||
const u32 texel_size = D3D12::GetTexelSize(m_format);
|
||||
const u32 upload_pitch = Common::AlignUpPow2(width * texel_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const u32 upload_size = upload_pitch * height;
|
||||
if (upload_size >= g_d3d12_context->GetTextureStreamBuffer().GetSize())
|
||||
{
|
||||
ID3D12Resource* staging_buffer = CreateStagingBuffer(height, data, pitch, upload_pitch, upload_size);
|
||||
if (!staging_buffer)
|
||||
return false;
|
||||
|
||||
CopyFromBuffer(cmdlist, level, x, y, width, height, upload_pitch, staging_buffer, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* write_ptr;
|
||||
u32 write_pitch;
|
||||
if (!(cmdlist = BeginStreamUpdate(cmdlist, level, x, y, width, height, &write_ptr, &write_pitch)))
|
||||
return false;
|
||||
|
||||
StringUtil::StrideMemCpy(write_ptr, write_pitch, data, pitch, std::min(pitch, upload_pitch), height);
|
||||
EndStreamUpdate(cmdlist, level, x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::CreateSRVDescriptor(
|
||||
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
|
||||
format, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
|
||||
desc.Texture2D.MipLevels = levels;
|
||||
|
||||
g_d3d12_context->GetDevice()->CreateShaderResourceView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetRTVHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_RENDER_TARGET_VIEW_DESC desc = {format, D3D12_RTV_DIMENSION_TEXTURE2D};
|
||||
g_d3d12_context->GetDevice()->CreateRenderTargetView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDSVHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, D3D12_DSV_FLAG_NONE};
|
||||
g_d3d12_context->GetDevice()->CreateDepthStencilView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate UAV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {format, D3D12_UAV_DIMENSION_TEXTURE2D};
|
||||
g_d3d12_context->GetDevice()->CreateUnorderedAccessView(resource, nullptr, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GS/Renderers/DX12/D3D12DescriptorHeapManager.h"
|
||||
|
||||
namespace D3D12MA
|
||||
{
|
||||
class Allocation;
|
||||
}
|
||||
|
||||
class D3D12StreamBuffer;
|
||||
|
||||
class D3D12Texture final
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
using ComPtr = wil::com_ptr_nothrow<T>;
|
||||
|
||||
D3D12Texture();
|
||||
D3D12Texture(ID3D12Resource* resource, D3D12_RESOURCE_STATES state);
|
||||
D3D12Texture(D3D12Texture&& texture);
|
||||
D3D12Texture(const D3D12Texture&) = delete;
|
||||
~D3D12Texture();
|
||||
|
||||
__fi ID3D12Resource* GetResource() const { return m_resource.get(); }
|
||||
__fi D3D12MA::Allocation* GetAllocation() const { return m_allocation.get(); }
|
||||
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
|
||||
__fi const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
|
||||
__fi D3D12_RESOURCE_STATES GetState() const { return m_state; }
|
||||
|
||||
__fi u32 GetWidth() const { return m_width; }
|
||||
__fi u32 GetHeight() const { return m_height; }
|
||||
__fi u32 GetLevels() const { return m_levels; }
|
||||
__fi DXGI_FORMAT GetFormat() const { return m_format; }
|
||||
|
||||
__fi operator ID3D12Resource*() const { return m_resource.get(); }
|
||||
__fi operator bool() const { return static_cast<bool>(m_resource); }
|
||||
|
||||
bool Create(u32 width, u32 height, u32 levels, DXGI_FORMAT format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
|
||||
DXGI_FORMAT dsv_format, D3D12_RESOURCE_FLAGS flags, u32 alloc_flags = 0);
|
||||
bool Adopt(ComPtr<ID3D12Resource> texture, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
|
||||
D3D12_RESOURCE_STATES state);
|
||||
|
||||
D3D12_RESOURCE_DESC GetDesc() const;
|
||||
|
||||
void Destroy(bool defer = true);
|
||||
|
||||
void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
|
||||
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 level, D3D12_RESOURCE_STATES before_state,
|
||||
D3D12_RESOURCE_STATES after_state) const;
|
||||
|
||||
D3D12Texture& operator=(const D3D12Texture&) = delete;
|
||||
D3D12Texture& operator=(D3D12Texture&& texture);
|
||||
|
||||
// NOTE: Does not handle compressed formats.
|
||||
ID3D12GraphicsCommandList* BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width,
|
||||
u32 height, void** out_data, u32* out_data_pitch);
|
||||
void EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height);
|
||||
bool LoadData(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data,
|
||||
u32 pitch);
|
||||
void CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch,
|
||||
ID3D12Resource* buffer, u32 buffer_offset);
|
||||
|
||||
private:
|
||||
static bool CreateSRVDescriptor(
|
||||
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
|
||||
enum class WriteDescriptorType : u8
|
||||
{
|
||||
None,
|
||||
RTV,
|
||||
DSV,
|
||||
UAV
|
||||
};
|
||||
|
||||
ComPtr<ID3D12Resource> m_resource;
|
||||
ComPtr<D3D12MA::Allocation> m_allocation;
|
||||
D3D12DescriptorHandle m_srv_descriptor = {};
|
||||
D3D12DescriptorHandle m_write_descriptor = {};
|
||||
u32 m_width = 0;
|
||||
u32 m_height = 0;
|
||||
u32 m_levels = 0;
|
||||
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
D3D12_RESOURCE_STATES m_state = D3D12_RESOURCE_STATE_COMMON;
|
||||
|
||||
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
|
||||
};
|
||||
@@ -37,11 +37,17 @@
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
|
||||
static bool IsDATMConvertShader(ShaderConvert i) { return (i == ShaderConvert::DATM_0 || i == ShaderConvert::DATM_1); }
|
||||
static bool IsDATEModePrimIDInit(u32 flag) { return flag == 1 || flag == 2; }
|
||||
static bool IsDATMConvertShader(ShaderConvert i)
|
||||
{
|
||||
return (i == ShaderConvert::DATM_0 || i == ShaderConvert::DATM_1);
|
||||
}
|
||||
static bool IsDATEModePrimIDInit(u32 flag)
|
||||
{
|
||||
return flag == 1 || flag == 2;
|
||||
}
|
||||
|
||||
static constexpr std::array<D3D12_PRIMITIVE_TOPOLOGY, 3> s_primitive_topology_mapping =
|
||||
{{D3D_PRIMITIVE_TOPOLOGY_POINTLIST, D3D_PRIMITIVE_TOPOLOGY_LINELIST, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST}};
|
||||
static constexpr std::array<D3D12_PRIMITIVE_TOPOLOGY, 3> s_primitive_topology_mapping = {
|
||||
{D3D_PRIMITIVE_TOPOLOGY_POINTLIST, D3D_PRIMITIVE_TOPOLOGY_LINELIST, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST}};
|
||||
|
||||
static constexpr std::array<float, 4> s_present_clear_color = {};
|
||||
|
||||
@@ -122,13 +128,13 @@ bool GSDevice12::Create()
|
||||
if (!GSDevice::Create())
|
||||
return false;
|
||||
|
||||
m_dxgi_factory = D3D::CreateFactory(EmuConfig.GS.UseDebugDevice);
|
||||
m_dxgi_factory = D3D::CreateFactory(GSConfig.UseDebugDevice);
|
||||
if (!m_dxgi_factory)
|
||||
return false;
|
||||
|
||||
ComPtr<IDXGIAdapter1> dxgi_adapter = D3D::GetAdapterByName(m_dxgi_factory.get(), EmuConfig.GS.Adapter);
|
||||
ComPtr<IDXGIAdapter1> dxgi_adapter = D3D::GetAdapterByName(m_dxgi_factory.get(), GSConfig.Adapter);
|
||||
|
||||
if (!D3D12Context::Create(m_dxgi_factory.get(), dxgi_adapter.get(), EmuConfig.GS.UseDebugDevice))
|
||||
if (!D3D12Context::Create(m_dxgi_factory.get(), dxgi_adapter.get(), GSConfig.UseDebugDevice))
|
||||
{
|
||||
Console.Error("Failed to create D3D12 context");
|
||||
return false;
|
||||
@@ -180,9 +186,8 @@ bool GSDevice12::Create()
|
||||
if (!CreateBuffers())
|
||||
return false;
|
||||
|
||||
if (!CompileConvertPipelines() || !CompilePresentPipelines() ||
|
||||
!CompileInterlacePipelines() || !CompileMergePipelines() ||
|
||||
!CompilePostProcessingPipelines())
|
||||
if (!CompileConvertPipelines() || !CompilePresentPipelines() || !CompileInterlacePipelines() ||
|
||||
!CompileMergePipelines() || !CompilePostProcessingPipelines())
|
||||
{
|
||||
Host::ReportErrorAsync("GS", "Failed to compile utility pipelines");
|
||||
return false;
|
||||
@@ -321,12 +326,12 @@ bool GSDevice12::CreateSwapChain()
|
||||
|
||||
// Render a frame as soon as possible to clear out whatever was previously being displayed.
|
||||
EndRenderPass();
|
||||
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
|
||||
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
|
||||
ID3D12GraphicsCommandList4* cmdlist = g_d3d12_context->GetCommandList();
|
||||
m_current_swap_chain_buffer = ((m_current_swap_chain_buffer + 1) % static_cast<u32>(m_swap_chain_buffers.size()));
|
||||
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(swap_chain_buf.GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
|
||||
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_PRESENT);
|
||||
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(swap_chain_buf->GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
|
||||
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_PRESENT);
|
||||
ExecuteCommandList(false);
|
||||
m_swap_chain->Present(0, m_using_allow_tearing ? DXGI_PRESENT_ALLOW_TEARING : 0);
|
||||
return true;
|
||||
@@ -350,9 +355,11 @@ bool GSDevice12::CreateSwapChainRTV()
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12Texture tex;
|
||||
if (!tex.Adopt(std::move(backbuffer), DXGI_FORMAT_UNKNOWN, swap_chain_desc.BufferDesc.Format,
|
||||
DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_STATE_PRESENT))
|
||||
std::unique_ptr<GSTexture12> tex = GSTexture12::Adopt(std::move(backbuffer), GSTexture::Type::RenderTarget,
|
||||
GSTexture::Format::Color, swap_chain_desc.BufferDesc.Width, swap_chain_desc.BufferDesc.Height, 1,
|
||||
swap_chain_desc.BufferDesc.Format, DXGI_FORMAT_UNKNOWN, swap_chain_desc.BufferDesc.Format,
|
||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_STATE_COMMON);
|
||||
if (!tex)
|
||||
{
|
||||
m_swap_chain_buffers.clear();
|
||||
return false;
|
||||
@@ -387,8 +394,8 @@ bool GSDevice12::CreateSwapChainRTV()
|
||||
|
||||
void GSDevice12::DestroySwapChainRTVs()
|
||||
{
|
||||
for (D3D12Texture& buffer : m_swap_chain_buffers)
|
||||
buffer.Destroy(false);
|
||||
for (std::unique_ptr<GSTexture12>& buffer : m_swap_chain_buffers)
|
||||
buffer->Destroy(false);
|
||||
m_swap_chain_buffers.clear();
|
||||
m_current_swap_chain_buffer = 0;
|
||||
}
|
||||
@@ -522,12 +529,12 @@ GSDevice::PresentResult GSDevice12::BeginPresent(bool frame_skip)
|
||||
return PresentResult::FrameSkipped;
|
||||
}
|
||||
|
||||
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
|
||||
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
|
||||
|
||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(swap_chain_buf.GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
|
||||
cmdlist->OMSetRenderTargets(1, &swap_chain_buf.GetWriteDescriptor().cpu_handle, FALSE, nullptr);
|
||||
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(swap_chain_buf->GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
|
||||
cmdlist->OMSetRenderTargets(1, &swap_chain_buf->GetWriteDescriptor().cpu_handle, FALSE, nullptr);
|
||||
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
|
||||
|
||||
const D3D12_VIEWPORT vp{0.0f, 0.0f, static_cast<float>(m_window_info.surface_width),
|
||||
@@ -543,10 +550,10 @@ void GSDevice12::EndPresent()
|
||||
{
|
||||
RenderImGui();
|
||||
|
||||
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
|
||||
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
|
||||
m_current_swap_chain_buffer = ((m_current_swap_chain_buffer + 1) % static_cast<u32>(m_swap_chain_buffers.size()));
|
||||
|
||||
swap_chain_buf.TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PRESENT);
|
||||
swap_chain_buf->TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PRESENT);
|
||||
if (!g_d3d12_context->ExecuteCommandList(D3D12Context::WaitType::None))
|
||||
{
|
||||
m_device_lost = true;
|
||||
@@ -603,7 +610,7 @@ bool GSDevice12::CheckFeatures()
|
||||
m_features.clip_control = true;
|
||||
m_features.stencil_buffer = true;
|
||||
m_features.test_and_sample_depth = false;
|
||||
m_features.vs_expand = true;
|
||||
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
|
||||
|
||||
m_features.dxt_textures = g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
|
||||
g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
|
||||
@@ -643,7 +650,10 @@ void GSDevice12::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
static_cast<GSTexture12*>(t)->SetClearColor(c);
|
||||
}
|
||||
|
||||
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c) { ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255)); }
|
||||
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c)
|
||||
{
|
||||
ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255));
|
||||
}
|
||||
|
||||
void GSDevice12::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
@@ -667,34 +677,27 @@ void GSDevice12::ClearDepth(GSTexture* t)
|
||||
static_cast<GSTexture12*>(t)->SetClearDepth(0.0f);
|
||||
}
|
||||
|
||||
void GSDevice12::ClearStencil(GSTexture* t, u8 c)
|
||||
void GSDevice12::LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format,
|
||||
DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const
|
||||
{
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
EndRenderPass();
|
||||
|
||||
GSTexture12* dxt = static_cast<GSTexture12*>(t);
|
||||
dxt->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
g_d3d12_context->GetCommandList()->ClearDepthStencilView(dxt->GetRTVOrDSVHandle(), D3D12_CLEAR_FLAG_STENCIL, 0.0f, c, 0, nullptr);
|
||||
}
|
||||
|
||||
void GSDevice12::LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format, DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const
|
||||
{
|
||||
static constexpr std::array<std::array<DXGI_FORMAT, 4>, static_cast<int>(GSTexture::Format::BC7) + 1> s_format_mapping = {{
|
||||
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // Invalid
|
||||
{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN}, // Color
|
||||
{DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_UNKNOWN}, // HDRColor
|
||||
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT}, // DepthStencil
|
||||
{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN}, // UNorm8
|
||||
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN}, // UInt16
|
||||
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN}, // UInt32
|
||||
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN}, // Int32
|
||||
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC1
|
||||
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC2
|
||||
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC3
|
||||
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC7
|
||||
}};
|
||||
static constexpr std::array<std::array<DXGI_FORMAT, 4>, static_cast<int>(GSTexture::Format::BC7) + 1>
|
||||
s_format_mapping = {{
|
||||
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // Invalid
|
||||
{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_UNKNOWN}, // Color
|
||||
{DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,
|
||||
DXGI_FORMAT_UNKNOWN}, // HDRColor
|
||||
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN,
|
||||
DXGI_FORMAT_D32_FLOAT_S8X24_UINT}, // DepthStencil
|
||||
{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN}, // UNorm8
|
||||
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN}, // UInt16
|
||||
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN}, // UInt32
|
||||
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN}, // Int32
|
||||
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC1
|
||||
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC2
|
||||
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC3
|
||||
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC7
|
||||
}};
|
||||
|
||||
const auto& mapping = s_format_mapping[static_cast<int>(format)];
|
||||
if (d3d_format)
|
||||
@@ -712,16 +715,20 @@ GSTexture* GSDevice12::CreateSurface(GSTexture::Type type, int width, int height
|
||||
const u32 clamped_width = static_cast<u32>(std::clamp<int>(width, 1, D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION));
|
||||
const u32 clamped_height = static_cast<u32>(std::clamp<int>(height, 1, D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION));
|
||||
|
||||
DXGI_FORMAT d3d_format, srv_format, rtv_format, dsv_format;
|
||||
LookupNativeFormat(format, &d3d_format, &srv_format, &rtv_format, &dsv_format);
|
||||
DXGI_FORMAT dxgi_format, srv_format, rtv_format, dsv_format;
|
||||
LookupNativeFormat(format, &dxgi_format, &srv_format, &rtv_format, &dsv_format);
|
||||
|
||||
std::unique_ptr<GSTexture12> tex(GSTexture12::Create(type, clamped_width, clamped_height, levels, format, d3d_format, srv_format, rtv_format, dsv_format));
|
||||
const DXGI_FORMAT uav_format = (type == GSTexture::Type::RWTexture) ? dxgi_format : DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
std::unique_ptr<GSTexture12> tex(GSTexture12::Create(type, format, clamped_width, clamped_height, levels,
|
||||
dxgi_format, srv_format, rtv_format, dsv_format, uav_format));
|
||||
if (!tex)
|
||||
{
|
||||
// We're probably out of vram, try flushing the command buffer to release pending textures.
|
||||
PurgePool();
|
||||
ExecuteCommandListAndRestartRenderPass(true, "Couldn't allocate texture.");
|
||||
tex = GSTexture12::Create(type, clamped_width, clamped_height, levels, format, d3d_format, srv_format, rtv_format, dsv_format);
|
||||
tex = GSTexture12::Create(type, format, clamped_width, clamped_height, levels, dxgi_format, srv_format,
|
||||
rtv_format, dsv_format, uav_format);
|
||||
}
|
||||
|
||||
return tex.release();
|
||||
@@ -763,14 +770,14 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
if (dTexVK->GetType() != GSTexture::Type::DepthStencil)
|
||||
{
|
||||
dTexVK->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
g_d3d12_context->GetCommandList()->ClearRenderTargetView(dTexVK->GetRTVOrDSVHandle(),
|
||||
sTexVK->GetClearColor().v, 0, nullptr);
|
||||
g_d3d12_context->GetCommandList()->ClearRenderTargetView(
|
||||
dTexVK->GetWriteDescriptor(), sTexVK->GetClearColor().v, 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dTexVK->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
g_d3d12_context->GetCommandList()->ClearDepthStencilView(dTexVK->GetRTVOrDSVHandle(),
|
||||
D3D12_CLEAR_FLAG_DEPTH, sTexVK->GetClearDepth(), 0, 0, nullptr);
|
||||
g_d3d12_context->GetCommandList()->ClearDepthStencilView(
|
||||
dTexVK->GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, sTexVK->GetClearDepth(), 0, 0, nullptr);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -806,11 +813,9 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstloc.SubresourceIndex = 0;
|
||||
|
||||
const D3D12_BOX srcbox{static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0u,
|
||||
static_cast<UINT>(r.right), static_cast<UINT>(r.bottom), 1u};
|
||||
g_d3d12_context->GetCommandList()->CopyTextureRegion(
|
||||
&dstloc, destX, destY, 0,
|
||||
&srcloc, &srcbox);
|
||||
const D3D12_BOX srcbox{static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0u, static_cast<UINT>(r.right),
|
||||
static_cast<UINT>(r.bottom), 1u};
|
||||
g_d3d12_context->GetCommandList()->CopyTextureRegion(&dstloc, destX, destY, 0, &srcloc, &srcbox);
|
||||
|
||||
dTexVK->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
@@ -853,7 +858,8 @@ void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
m_present[static_cast<int>(shader)].get(), linear, true);
|
||||
}
|
||||
|
||||
void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
|
||||
void GSDevice12::UpdateCLUTTexture(
|
||||
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
|
||||
{
|
||||
// match merge cb
|
||||
struct Uniforms
|
||||
@@ -873,7 +879,8 @@ void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
|
||||
m_convert[static_cast<int>(shader)].get(), false, true);
|
||||
}
|
||||
|
||||
void GSDevice12::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
void GSDevice12::ConvertToIndexedTexture(
|
||||
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
{
|
||||
// match merge cb
|
||||
struct Uniforms
|
||||
@@ -1135,9 +1142,10 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
static_cast<GSTexture12*>(sTex[1])->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
OMSetRenderTargets(dTex, nullptr, darea);
|
||||
SetUtilityTexture(sTex[1], sampler);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c);
|
||||
SetUtilityRootSignature();
|
||||
SetPipeline(m_convert[static_cast<int>(ShaderConvert::COPY)].get());
|
||||
DrawStretchRect(sRect[1], PMODE.SLBG ? dRect[2] : dRect[1], dsize);
|
||||
@@ -1186,7 +1194,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
else if (!InRenderPass())
|
||||
{
|
||||
OMSetRenderTargets(dTex, nullptr, darea);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
|
||||
BeginRenderPass(
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
|
||||
}
|
||||
|
||||
if (sTex[0] && sTex[0]->GetState() == GSTexture::State::Dirty)
|
||||
@@ -1205,7 +1214,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
SetPipeline(m_convert[static_cast<int>(ShaderConvert::YUV)].get());
|
||||
SetUtilityTexture(dTex, sampler);
|
||||
OMSetRenderTargets(sTex[2], nullptr, fbarea);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
|
||||
BeginRenderPass(
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
|
||||
DrawStretchRect(full_r, dRect[2], dsize);
|
||||
}
|
||||
|
||||
@@ -1216,7 +1226,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
}
|
||||
|
||||
void GSDevice12::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
void GSDevice12::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
|
||||
{
|
||||
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
@@ -1288,9 +1299,7 @@ bool GSDevice12::CompileCASPipelines()
|
||||
if (!cas_source.has_value() || !GetCASShaderSource(&cas_source.value()))
|
||||
return false;
|
||||
|
||||
static constexpr D3D_SHADER_MACRO sharpen_only_macros[] = {
|
||||
{"CAS_SHARPEN_ONLY", "1"},
|
||||
{nullptr, nullptr}};
|
||||
static constexpr D3D_SHADER_MACRO sharpen_only_macros[] = {{"CAS_SHARPEN_ONLY", "1"}, {nullptr, nullptr}};
|
||||
|
||||
const ComPtr<ID3DBlob> cs_upscale(m_shader_cache.GetComputeShader(cas_source.value(), nullptr, "main"));
|
||||
const ComPtr<ID3DBlob> cs_sharpen(m_shader_cache.GetComputeShader(cas_source.value(), sharpen_only_macros, "main"));
|
||||
@@ -1430,8 +1439,8 @@ void GSDevice12::RenderImGui()
|
||||
SetScissor(GSVector4i(clip));
|
||||
|
||||
// Since we don't have the GSTexture...
|
||||
D3D12Texture* tex = static_cast<D3D12Texture*>(pcmd->GetTexID());
|
||||
D3D12DescriptorHandle handle = tex ? tex->GetSRVDescriptor() : m_null_texture.GetSRVDescriptor();
|
||||
GSTexture12* tex = static_cast<GSTexture12*>(pcmd->GetTexID());
|
||||
D3D12DescriptorHandle handle = tex ? tex->GetSRVDescriptor() : m_null_texture->GetSRVDescriptor();
|
||||
if (m_utility_texture_cpu != handle)
|
||||
{
|
||||
m_utility_texture_cpu = handle;
|
||||
@@ -1455,19 +1464,20 @@ void GSDevice12::RenderImGui()
|
||||
}
|
||||
}
|
||||
|
||||
bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants)
|
||||
bool GSDevice12::DoCAS(
|
||||
GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
GSTexture12* const sTex12 = static_cast<GSTexture12*>(sTex);
|
||||
GSTexture12* const dTex12 = static_cast<GSTexture12*>(dTex);
|
||||
D3D12DescriptorHandle sTexDH, dTexDH;
|
||||
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetTexture().GetSRVDescriptor(), 1) ||
|
||||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetTexture().GetWriteDescriptor(), 1))
|
||||
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetSRVDescriptor(), 1) ||
|
||||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetUAVDescriptor(), 1))
|
||||
{
|
||||
ExecuteCommandList(false, "Ran out of descriptors for CAS");
|
||||
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetTexture().GetSRVDescriptor(), 1) ||
|
||||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetTexture().GetWriteDescriptor(), 1))
|
||||
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetSRVDescriptor(), 1) ||
|
||||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetUAVDescriptor(), 1))
|
||||
{
|
||||
Console.Error("Failed to allocate CAS descriptors.");
|
||||
return false;
|
||||
@@ -1475,12 +1485,13 @@ bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, cons
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* const cmdlist = g_d3d12_context->GetCommandList();
|
||||
const D3D12_RESOURCE_STATES old_state = sTex12->GetTexture().GetState();
|
||||
sTex12->GetTexture().TransitionToState(cmdlist, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
|
||||
dTex12->GetTexture().TransitionToState(cmdlist, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
const D3D12_RESOURCE_STATES old_state = sTex12->GetResourceState();
|
||||
sTex12->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
|
||||
dTex12->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
cmdlist->SetComputeRootSignature(m_cas_root_signature.get());
|
||||
cmdlist->SetComputeRoot32BitConstants(CAS_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, NUM_CAS_CONSTANTS, constants.data(), 0);
|
||||
cmdlist->SetComputeRoot32BitConstants(
|
||||
CAS_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, NUM_CAS_CONSTANTS, constants.data(), 0);
|
||||
cmdlist->SetComputeRootDescriptorTable(CAS_ROOT_SIGNATURE_PARAM_SRC_TEXTURE, sTexDH);
|
||||
cmdlist->SetComputeRootDescriptorTable(CAS_ROOT_SIGNATURE_PARAM_DST_TEXTURE, dTexDH);
|
||||
cmdlist->SetPipelineState(sharpen_only ? m_cas_sharpen_pipeline.get() : m_cas_upscale_pipeline.get());
|
||||
@@ -1491,7 +1502,7 @@ bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, cons
|
||||
const int dispatchY = (dTex->GetHeight() + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
cmdlist->Dispatch(dispatchX, dispatchY, 1);
|
||||
|
||||
sTex12->GetTexture().TransitionToState(cmdlist, old_state);
|
||||
sTex12->TransitionToState(cmdlist, old_state);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1591,8 +1602,7 @@ bool GSDevice12::GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::S
|
||||
}};
|
||||
|
||||
const u8 index = (static_cast<u8>(ss.IsMipFilterLinear()) << 2) |
|
||||
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) |
|
||||
static_cast<u8>(ss.IsMinFilterLinear());
|
||||
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) | static_cast<u8>(ss.IsMinFilterLinear());
|
||||
sd.Filter = filters[index];
|
||||
}
|
||||
|
||||
@@ -1625,14 +1635,16 @@ void GSDevice12::ClearSamplerCache()
|
||||
m_dirty_flags |= DIRTY_FLAG_TFX_SAMPLERS;
|
||||
}
|
||||
|
||||
bool GSDevice12::GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count)
|
||||
bool GSDevice12::GetTextureGroupDescriptors(
|
||||
D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count)
|
||||
{
|
||||
if (!g_d3d12_context->GetDescriptorAllocator().Allocate(count, gpu_handle))
|
||||
return false;
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
g_d3d12_context->GetDevice()->CopyDescriptorsSimple(1, *gpu_handle, cpu_handles[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
g_d3d12_context->GetDevice()->CopyDescriptorsSimple(
|
||||
1, *gpu_handle, cpu_handles[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1645,7 +1657,8 @@ bool GSDevice12::GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, c
|
||||
src_handles[i] = cpu_handles[i];
|
||||
src_sizes[i] = 1;
|
||||
}
|
||||
g_d3d12_context->GetDevice()->CopyDescriptors(1, &dst_handle, &count, count, src_handles, src_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
g_d3d12_context->GetDevice()->CopyDescriptors(
|
||||
1, &dst_handle, &count, count, src_handles, src_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1671,14 +1684,14 @@ GSDevice12::ComPtr<ID3DBlob> GSDevice12::GetUtilityPixelShader(const std::string
|
||||
|
||||
bool GSDevice12::CreateNullTexture()
|
||||
{
|
||||
if (!m_null_texture.Create(1, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE))
|
||||
{
|
||||
m_null_texture =
|
||||
GSTexture12::Create(GSTexture::Type::Texture, GSTexture::Format::Color, 1, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
|
||||
if (!m_null_texture)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_null_texture.TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
D3D12::SetObjectName(m_null_texture.GetResource(), "Null texture");
|
||||
m_null_texture->TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
D3D12::SetObjectName(m_null_texture->GetResource(), "Null texture");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1838,15 +1851,14 @@ bool GSDevice12::CompileConvertPipelines()
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
pxAssert(!m_color_copy[i]);
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
|
||||
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, static_cast<u8>(i));
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE,
|
||||
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, static_cast<u8>(i));
|
||||
m_color_copy[i] = gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache, false);
|
||||
if (!m_color_copy[i])
|
||||
return false;
|
||||
|
||||
D3D12::SetObjectNameFormatted(m_color_copy[i].get(),
|
||||
"Color copy pipeline (r=%u, g=%u, b=%u, a=%u)", i & 1u, (i >> 1) & 1u, (i >> 2) & 1u,
|
||||
(i >> 3) & 1u);
|
||||
D3D12::SetObjectNameFormatted(m_color_copy[i].get(), "Color copy pipeline (r=%u, g=%u, b=%u, a=%u)",
|
||||
i & 1u, (i >> 1) & 1u, (i >> 2) & 1u, (i >> 3) & 1u);
|
||||
}
|
||||
}
|
||||
else if (i == ShaderConvert::HDR_INIT || i == ShaderConvert::HDR_RESOLVE)
|
||||
@@ -1863,14 +1875,16 @@ bool GSDevice12::CompileConvertPipelines()
|
||||
if (!arr[ds])
|
||||
return false;
|
||||
|
||||
D3D12::SetObjectNameFormatted(arr[ds].get(), "HDR %s/copy pipeline (ds=%u)", is_setup ? "setup" : "finish", ds);
|
||||
D3D12::SetObjectNameFormatted(
|
||||
arr[ds].get(), "HDR %s/copy pipeline (ds=%u)", is_setup ? "setup" : "finish", ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 datm = 0; datm < 2; datm++)
|
||||
{
|
||||
ComPtr<ID3DBlob> ps(GetUtilityPixelShader(*shader, datm ? "ps_stencil_image_init_1" : "ps_stencil_image_init_0"));
|
||||
ComPtr<ID3DBlob> ps(
|
||||
GetUtilityPixelShader(*shader, datm ? "ps_stencil_image_init_1" : "ps_stencil_image_init_0"));
|
||||
if (!ps)
|
||||
return false;
|
||||
|
||||
@@ -1879,8 +1893,8 @@ bool GSDevice12::CompileConvertPipelines()
|
||||
gpb.SetPixelShader(ps.get());
|
||||
gpb.SetNoDepthTestState();
|
||||
gpb.SetNoStencilState();
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ONE, D3D12_BLEND_OP_ADD,
|
||||
D3D12_BLEND_ZERO, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_COLOR_WRITE_ENABLE_RED);
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ONE, D3D12_BLEND_OP_ADD, D3D12_BLEND_ZERO,
|
||||
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_COLOR_WRITE_ENABLE_RED);
|
||||
|
||||
for (u32 ds = 0; ds < 2; ds++)
|
||||
{
|
||||
@@ -1889,7 +1903,8 @@ bool GSDevice12::CompileConvertPipelines()
|
||||
if (!m_date_image_setup_pipelines[ds][datm])
|
||||
return false;
|
||||
|
||||
D3D12::SetObjectNameFormatted(m_date_image_setup_pipelines[ds][datm].get(), "DATE image clear pipeline (ds=%u, datm=%u)", ds, datm);
|
||||
D3D12::SetObjectNameFormatted(
|
||||
m_date_image_setup_pipelines[ds][datm].get(), "DATE image clear pipeline (ds=%u, datm=%u)", ds, datm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2000,8 +2015,8 @@ bool GSDevice12::CompileMergePipelines()
|
||||
return false;
|
||||
|
||||
gpb.SetPixelShader(ps.get());
|
||||
gpb.SetBlendState(0, true, D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA,
|
||||
D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD);
|
||||
gpb.SetBlendState(0, true, D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
|
||||
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD);
|
||||
|
||||
m_merge[i] = gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache, false);
|
||||
if (!m_merge[i])
|
||||
@@ -2115,7 +2130,11 @@ void GSDevice12::DestroyResources()
|
||||
m_utility_root_signature.reset();
|
||||
m_tfx_root_signature.reset();
|
||||
|
||||
m_null_texture.Destroy(false);
|
||||
if (m_null_texture)
|
||||
{
|
||||
m_null_texture->Destroy(false);
|
||||
m_null_texture.reset();
|
||||
}
|
||||
|
||||
m_shader_cache.Close();
|
||||
}
|
||||
@@ -2262,14 +2281,13 @@ GSDevice12::ComPtr<ID3D12PipelineState> GSDevice12::CreateTFXPipeline(const Pipe
|
||||
// DepthStencil
|
||||
if (p.ds)
|
||||
{
|
||||
static const D3D12_COMPARISON_FUNC ztst[] = {
|
||||
D3D12_COMPARISON_FUNC_NEVER, D3D12_COMPARISON_FUNC_ALWAYS, D3D12_COMPARISON_FUNC_GREATER_EQUAL, D3D12_COMPARISON_FUNC_GREATER};
|
||||
static const D3D12_COMPARISON_FUNC ztst[] = {D3D12_COMPARISON_FUNC_NEVER, D3D12_COMPARISON_FUNC_ALWAYS,
|
||||
D3D12_COMPARISON_FUNC_GREATER_EQUAL, D3D12_COMPARISON_FUNC_GREATER};
|
||||
gpb.SetDepthState((p.dss.ztst != ZTST_ALWAYS || p.dss.zwe), p.dss.zwe, ztst[p.dss.ztst]);
|
||||
if (p.dss.date)
|
||||
{
|
||||
const D3D12_DEPTH_STENCILOP_DESC sos{D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP,
|
||||
p.dss.date_one ? D3D12_STENCIL_OP_ZERO : D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_COMPARISON_FUNC_EQUAL};
|
||||
p.dss.date_one ? D3D12_STENCIL_OP_ZERO : D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_EQUAL};
|
||||
gpb.SetStencilState(true, 1, 1, sos, sos);
|
||||
}
|
||||
}
|
||||
@@ -2304,8 +2322,8 @@ GSDevice12::ComPtr<ID3D12PipelineState> GSDevice12::CreateTFXPipeline(const Pipe
|
||||
}
|
||||
else
|
||||
{
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
|
||||
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, p.cms.wrgba);
|
||||
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE,
|
||||
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, p.cms.wrgba);
|
||||
}
|
||||
|
||||
ComPtr<ID3D12PipelineState> pipeline(gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache));
|
||||
@@ -2343,7 +2361,7 @@ bool GSDevice12::BindDrawPipeline(const PipelineSelector& p)
|
||||
void GSDevice12::InitializeState()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_TOTAL_TFX_TEXTURES; i++)
|
||||
m_tfx_textures[i] = m_null_texture.GetSRVDescriptor();
|
||||
m_tfx_textures[i] = m_null_texture->GetSRVDescriptor();
|
||||
m_tfx_sampler_sel = GSHWDrawConfig::SamplerSelector::Point().key;
|
||||
|
||||
InvalidateCachedState();
|
||||
@@ -2403,11 +2421,14 @@ void GSDevice12::ExecuteCommandListAndRestartRenderPass(bool wait_for_completion
|
||||
m_dirty_flags &= ~DIRTY_BASE_STATE;
|
||||
|
||||
// restart render pass
|
||||
BeginRenderPass(
|
||||
m_current_render_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_render_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_depth_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_depth_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS);
|
||||
BeginRenderPass(m_current_render_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_render_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_depth_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
m_current_depth_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2431,7 +2452,8 @@ void GSDevice12::InvalidateCachedState()
|
||||
|
||||
void GSDevice12::SetVertexBuffer(D3D12_GPU_VIRTUAL_ADDRESS buffer, size_t size, size_t stride)
|
||||
{
|
||||
if (m_vertex_buffer.BufferLocation == buffer && m_vertex_buffer.SizeInBytes == size && m_vertex_buffer.StrideInBytes == stride)
|
||||
if (m_vertex_buffer.BufferLocation == buffer && m_vertex_buffer.SizeInBytes == size &&
|
||||
m_vertex_buffer.StrideInBytes == stride)
|
||||
return;
|
||||
|
||||
m_vertex_buffer.BufferLocation = buffer;
|
||||
@@ -2486,9 +2508,9 @@ void GSDevice12::PSSetShaderResource(int i, GSTexture* sr, bool check_state)
|
||||
GSTexture12* dtex = static_cast<GSTexture12*>(sr);
|
||||
if (check_state)
|
||||
{
|
||||
if (dtex->GetTexture().GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE && InRenderPass())
|
||||
if (dtex->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE && InRenderPass())
|
||||
{
|
||||
// Console.Warning("Ending render pass due to resource transition");
|
||||
GL_INS("Ending render pass due to resource transition");
|
||||
EndRenderPass();
|
||||
}
|
||||
|
||||
@@ -2500,7 +2522,7 @@ void GSDevice12::PSSetShaderResource(int i, GSTexture* sr, bool check_state)
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = m_null_texture.GetSRVDescriptor();
|
||||
handle = m_null_texture->GetSRVDescriptor();
|
||||
}
|
||||
|
||||
if (m_tfx_textures[i] == handle)
|
||||
@@ -2543,7 +2565,7 @@ void GSDevice12::SetUtilityTexture(GSTexture* dtex, const D3D12DescriptorHandle&
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = m_null_texture.GetSRVDescriptor();
|
||||
handle = m_null_texture->GetSRVDescriptor();
|
||||
}
|
||||
|
||||
if (m_utility_texture_cpu != handle)
|
||||
@@ -2575,7 +2597,8 @@ void GSDevice12::SetUtilityTexture(GSTexture* dtex, const D3D12DescriptorHandle&
|
||||
|
||||
void GSDevice12::SetUtilityPushConstants(const void* data, u32 size)
|
||||
{
|
||||
g_d3d12_context->GetCommandList()->SetGraphicsRoot32BitConstants(UTILITY_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, (size + 3) / sizeof(u32), data, 0);
|
||||
g_d3d12_context->GetCommandList()->SetGraphicsRoot32BitConstants(
|
||||
UTILITY_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, (size + 3) / sizeof(u32), data, 0);
|
||||
}
|
||||
|
||||
void GSDevice12::UnbindTexture(GSTexture12* tex)
|
||||
@@ -2584,7 +2607,7 @@ void GSDevice12::UnbindTexture(GSTexture12* tex)
|
||||
{
|
||||
if (m_tfx_textures[i] == tex->GetSRVDescriptor())
|
||||
{
|
||||
m_tfx_textures[i] = m_null_texture.GetSRVDescriptor();
|
||||
m_tfx_textures[i] = m_null_texture->GetSRVDescriptor();
|
||||
m_dirty_flags |= DIRTY_FLAG_TFX_TEXTURES;
|
||||
}
|
||||
}
|
||||
@@ -2600,8 +2623,8 @@ void GSDevice12::UnbindTexture(GSTexture12* tex)
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
|
||||
u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height)
|
||||
void GSDevice12::RenderTextureMipmap(
|
||||
GSTexture12* texture, u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
@@ -2616,13 +2639,14 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
|
||||
ExecuteCommandList(false);
|
||||
|
||||
// Setup views. This will be a partial view for the SRV.
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = {texture.GetFormat(), D3D12_RTV_DIMENSION_TEXTURE2D};
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = {texture->GetDXGIFormat(), D3D12_RTV_DIMENSION_TEXTURE2D};
|
||||
rtv_desc.Texture2D = {dst_level, 0u};
|
||||
g_d3d12_context->GetDevice()->CreateRenderTargetView(texture.GetResource(), &rtv_desc, rtv_handle);
|
||||
g_d3d12_context->GetDevice()->CreateRenderTargetView(texture->GetResource(), &rtv_desc, rtv_handle);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {texture.GetFormat(), D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {
|
||||
texture->GetDXGIFormat(), D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
|
||||
srv_desc.Texture2D = {src_level, 1u, 0u, 0.0f};
|
||||
g_d3d12_context->GetDevice()->CreateShaderResourceView(texture.GetResource(), &srv_desc, srv_handle);
|
||||
g_d3d12_context->GetDevice()->CreateShaderResourceView(texture->GetResource(), &srv_desc, srv_handle);
|
||||
|
||||
// We need to set the descriptors up manually, because we're not going through GSTexture.
|
||||
if (!GetTextureGroupDescriptors(&m_utility_texture_gpu, &srv_handle, 1))
|
||||
@@ -2636,10 +2660,12 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
|
||||
|
||||
// *now* we don't have to worry about running out of anything.
|
||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||
if (texture.GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
|
||||
texture.TransitionSubresourceToState(cmdlist, src_level, texture.GetState(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
if (texture.GetState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
|
||||
texture.TransitionSubresourceToState(cmdlist, dst_level, texture.GetState(), D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
|
||||
texture->TransitionSubresourceToState(
|
||||
cmdlist, src_level, texture->GetResourceState(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
|
||||
texture->TransitionSubresourceToState(
|
||||
cmdlist, dst_level, texture->GetResourceState(), D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
// We set the state directly here.
|
||||
constexpr u32 MODIFIED_STATE = DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET;
|
||||
@@ -2647,7 +2673,7 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
|
||||
|
||||
// Using a render pass is probably a bit overkill.
|
||||
const D3D12_DISCARD_REGION discard_region = {0u, nullptr, dst_level, 1u};
|
||||
cmdlist->DiscardResource(texture.GetResource(), &discard_region);
|
||||
cmdlist->DiscardResource(texture->GetResource(), &discard_region);
|
||||
cmdlist->OMSetRenderTargets(1, &rtv_handle.cpu_handle, FALSE, nullptr);
|
||||
|
||||
const D3D12_VIEWPORT vp = {0.0f, 0.0f, static_cast<float>(dst_width), static_cast<float>(dst_height), 0.0f, 1.0f};
|
||||
@@ -2662,10 +2688,12 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
|
||||
GSVector4(0.0f, 0.0f, static_cast<float>(dst_width), static_cast<float>(dst_height)),
|
||||
GSVector2i(dst_width, dst_height));
|
||||
|
||||
if (texture.GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
|
||||
texture.TransitionSubresourceToState(cmdlist, src_level, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, texture.GetState());
|
||||
if (texture.GetState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
|
||||
texture.TransitionSubresourceToState(cmdlist, dst_level, D3D12_RESOURCE_STATE_RENDER_TARGET, texture.GetState());
|
||||
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
|
||||
texture->TransitionSubresourceToState(
|
||||
cmdlist, src_level, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, texture->GetResourceState());
|
||||
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
|
||||
texture->TransitionSubresourceToState(
|
||||
cmdlist, dst_level, D3D12_RESOURCE_STATE_RENDER_TARGET, texture->GetResourceState());
|
||||
|
||||
// Must destroy after current cmdlist.
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &srv_handle);
|
||||
@@ -2680,12 +2708,11 @@ bool GSDevice12::InRenderPass()
|
||||
return m_in_render_pass;
|
||||
}
|
||||
|
||||
void GSDevice12::BeginRenderPass(
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end,
|
||||
const GSVector4& clear_color /* = GSVector4::zero() */, float clear_depth /* = 0.0f */,
|
||||
u8 clear_stencil /* = 0 */)
|
||||
void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin,
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, const GSVector4& clear_color /* = GSVector4::zero() */,
|
||||
float clear_depth /* = 0.0f */, u8 clear_stencil /* = 0 */)
|
||||
{
|
||||
if (m_in_render_pass)
|
||||
EndRenderPass();
|
||||
@@ -2697,12 +2724,13 @@ void GSDevice12::BeginRenderPass(
|
||||
D3D12_RENDER_PASS_RENDER_TARGET_DESC rt = {};
|
||||
if (m_current_render_target)
|
||||
{
|
||||
rt.cpuDescriptor = m_current_render_target->GetRTVOrDSVHandle();
|
||||
rt.cpuDescriptor = m_current_render_target->GetWriteDescriptor();
|
||||
rt.EndingAccess.Type = color_end;
|
||||
rt.BeginningAccess.Type = color_begin;
|
||||
if (color_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
|
||||
{
|
||||
LookupNativeFormat(m_current_render_target->GetFormat(), nullptr, &rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr);
|
||||
LookupNativeFormat(m_current_render_target->GetFormat(), nullptr,
|
||||
&rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr);
|
||||
GSVector4::store<false>(rt.BeginningAccess.Clear.ClearValue.Color, clear_color);
|
||||
}
|
||||
}
|
||||
@@ -2710,26 +2738,27 @@ void GSDevice12::BeginRenderPass(
|
||||
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC ds = {};
|
||||
if (m_current_depth_target)
|
||||
{
|
||||
ds.cpuDescriptor = m_current_depth_target->GetRTVOrDSVHandle();
|
||||
ds.cpuDescriptor = m_current_depth_target->GetWriteDescriptor();
|
||||
ds.DepthEndingAccess.Type = depth_end;
|
||||
ds.DepthBeginningAccess.Type = depth_begin;
|
||||
if (depth_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
|
||||
{
|
||||
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr, &ds.DepthBeginningAccess.Clear.ClearValue.Format);
|
||||
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr,
|
||||
&ds.DepthBeginningAccess.Clear.ClearValue.Format);
|
||||
ds.DepthBeginningAccess.Clear.ClearValue.DepthStencil.Depth = clear_depth;
|
||||
}
|
||||
ds.StencilEndingAccess.Type = stencil_end;
|
||||
ds.StencilBeginningAccess.Type = stencil_begin;
|
||||
if (stencil_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
|
||||
{
|
||||
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr, &ds.StencilBeginningAccess.Clear.ClearValue.Format);
|
||||
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr,
|
||||
&ds.StencilBeginningAccess.Clear.ClearValue.Format);
|
||||
ds.StencilBeginningAccess.Clear.ClearValue.DepthStencil.Stencil = clear_stencil;
|
||||
}
|
||||
}
|
||||
|
||||
g_d3d12_context->GetCommandList()->BeginRenderPass(
|
||||
m_current_render_target ? 1 : 0, m_current_render_target ? &rt : nullptr,
|
||||
m_current_depth_target ? &ds : nullptr, D3D12_RENDER_PASS_FLAG_NONE);
|
||||
g_d3d12_context->GetCommandList()->BeginRenderPass(m_current_render_target ? 1 : 0,
|
||||
m_current_render_target ? &rt : nullptr, m_current_depth_target ? &ds : nullptr, D3D12_RENDER_PASS_FLAG_NONE);
|
||||
}
|
||||
|
||||
void GSDevice12::EndRenderPass()
|
||||
@@ -2745,7 +2774,6 @@ void GSDevice12::EndRenderPass()
|
||||
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
|
||||
|
||||
g_d3d12_context->GetCommandList()->EndRenderPass();
|
||||
|
||||
}
|
||||
|
||||
void GSDevice12::SetViewport(const D3D12_VIEWPORT& viewport)
|
||||
@@ -2811,12 +2839,12 @@ __ri void GSDevice12::ApplyBaseState(u32 flags, ID3D12GraphicsCommandList* cmdli
|
||||
{
|
||||
if (m_current_render_target)
|
||||
{
|
||||
cmdlist->OMSetRenderTargets(1, &m_current_render_target->GetRTVOrDSVHandle().cpu_handle, FALSE,
|
||||
m_current_depth_target ? &m_current_depth_target->GetRTVOrDSVHandle().cpu_handle : nullptr);
|
||||
cmdlist->OMSetRenderTargets(1, &m_current_render_target->GetWriteDescriptor().cpu_handle, FALSE,
|
||||
m_current_depth_target ? &m_current_depth_target->GetWriteDescriptor().cpu_handle : nullptr);
|
||||
}
|
||||
else if (m_current_depth_target)
|
||||
{
|
||||
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, &m_current_depth_target->GetRTVOrDSVHandle().cpu_handle);
|
||||
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, &m_current_depth_target->GetWriteDescriptor().cpu_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2911,8 +2939,8 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
|
||||
{
|
||||
m_current_root_signature = RootSignature::TFX;
|
||||
flags |= DIRTY_FLAG_VS_CONSTANT_BUFFER_BINDING | DIRTY_FLAG_PS_CONSTANT_BUFFER_BINDING |
|
||||
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 |
|
||||
DIRTY_FLAG_PIPELINE;
|
||||
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE |
|
||||
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_PIPELINE;
|
||||
cmdlist->SetGraphicsRootSignature(m_tfx_root_signature.get());
|
||||
}
|
||||
|
||||
@@ -2998,8 +3026,8 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, bool datm, const GSVect
|
||||
SetStencilRef(1);
|
||||
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
GSVector4::zero(), 0.0f, 0);
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, GSVector4::zero(),
|
||||
0.0f, 0);
|
||||
if (ApplyUtilityState())
|
||||
DrawPrimitive();
|
||||
|
||||
@@ -3084,9 +3112,8 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
|
||||
void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
// Destination Alpha Setup
|
||||
const bool stencil_DATE =
|
||||
(config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
|
||||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne);
|
||||
const bool stencil_DATE = (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
|
||||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne);
|
||||
if (stencil_DATE)
|
||||
SetupDATE(config.rt, config.ds, config.datm, config.drawarea);
|
||||
|
||||
@@ -3127,7 +3154,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
const GSVector2i rtsize(config.rt ? config.rt->GetSize() : config.ds->GetSize());
|
||||
const GSVector4i render_area(
|
||||
config.ps.hdr ? config.drawarea :
|
||||
GSVector4i(Common::AlignDownPow2(config.scissor.left, render_area_alignment),
|
||||
GSVector4i(Common::AlignDownPow2(config.scissor.left, render_area_alignment),
|
||||
Common::AlignDownPow2(config.scissor.top, render_area_alignment),
|
||||
std::min(Common::AlignUpPow2(config.scissor.right, render_area_alignment), rtsize.x),
|
||||
std::min(Common::AlignUpPow2(config.scissor.bottom, render_area_alignment), rtsize.y)));
|
||||
@@ -3177,8 +3204,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
{
|
||||
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 for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
|
||||
config.drawarea.width(), config.drawarea.height());
|
||||
|
||||
draw_rt_clone->SetState(GSTexture::State::Invalidated);
|
||||
@@ -3218,13 +3244,14 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
// Begin render pass if new target or out of the area.
|
||||
if (!m_in_render_pass)
|
||||
{
|
||||
BeginRenderPass(
|
||||
GetLoadOpForTexture(draw_rt),
|
||||
BeginRenderPass(GetLoadOpForTexture(draw_rt),
|
||||
draw_rt ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
GetLoadOpForTexture(draw_ds),
|
||||
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||
stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD :
|
||||
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
draw_rt ? draw_rt->GetClearColor() : GSVector4::zero(), draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
|
||||
}
|
||||
|
||||
@@ -3305,7 +3332,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
|
||||
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||
GetLoadOpForTexture(draw_ds), draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
GetLoadOpForTexture(draw_ds),
|
||||
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||
draw_rt->GetClearColor(), 0.0f, 0);
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
private:
|
||||
ComPtr<IDXGIFactory5> m_dxgi_factory;
|
||||
ComPtr<IDXGISwapChain1> m_swap_chain;
|
||||
std::vector<D3D12Texture> m_swap_chain_buffers;
|
||||
std::vector<std::unique_ptr<GSTexture12>> m_swap_chain_buffers;
|
||||
u32 m_current_swap_chain_buffer = 0;
|
||||
|
||||
bool m_allow_tearing_supported = false;
|
||||
@@ -177,7 +177,8 @@ private:
|
||||
ComPtr<ID3D12PipelineState> m_imgui_pipeline;
|
||||
|
||||
std::unordered_map<u32, ComPtr<ID3DBlob>> m_tfx_vertex_shaders;
|
||||
std::unordered_map<GSHWDrawConfig::PSSelector, ComPtr<ID3DBlob>, GSHWDrawConfig::PSSelectorHash> m_tfx_pixel_shaders;
|
||||
std::unordered_map<GSHWDrawConfig::PSSelector, ComPtr<ID3DBlob>, GSHWDrawConfig::PSSelectorHash>
|
||||
m_tfx_pixel_shaders;
|
||||
std::unordered_map<PipelineSelector, ComPtr<ID3D12PipelineState>, PipelineSelectorHash> m_tfx_pipelines;
|
||||
|
||||
ComPtr<ID3D12RootSignature> m_cas_root_signature;
|
||||
@@ -191,26 +192,31 @@ private:
|
||||
ComPtr<ID3DBlob> m_convert_vs;
|
||||
std::string m_tfx_source;
|
||||
|
||||
void LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format, DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const;
|
||||
void LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format,
|
||||
DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const;
|
||||
|
||||
bool CreateSwapChain();
|
||||
bool CreateSwapChainRTV();
|
||||
void DestroySwapChainRTVs();
|
||||
void DestroySwapChain();
|
||||
|
||||
GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
|
||||
GSTexture* CreateSurface(
|
||||
GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE,
|
||||
const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
|
||||
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
|
||||
|
||||
bool DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants) final;
|
||||
bool DoCAS(
|
||||
GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants) final;
|
||||
|
||||
bool GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::SamplerSelector ss);
|
||||
void ClearSamplerCache() final;
|
||||
bool GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count);
|
||||
bool GetTextureGroupDescriptors(
|
||||
D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count);
|
||||
|
||||
const ID3DBlob* GetTFXVertexShader(GSHWDrawConfig::VSSelector sel);
|
||||
const ID3DBlob* GetTFXPixelShader(const GSHWDrawConfig::PSSelector& sel);
|
||||
@@ -277,7 +283,6 @@ public:
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) override;
|
||||
void InvalidateRenderTarget(GSTexture* t) override;
|
||||
void ClearDepth(GSTexture* t) override;
|
||||
void ClearStencil(GSTexture* t, u8 c) override;
|
||||
|
||||
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
|
||||
|
||||
@@ -289,10 +294,13 @@ public:
|
||||
bool green, bool blue, bool alpha) override;
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
PresentShader shader, float shaderTime, bool linear) override;
|
||||
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
|
||||
void UpdateCLUTTexture(
|
||||
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM,
|
||||
GSTexture* dTex, u32 DBW, u32 DPSM) override;
|
||||
|
||||
void DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
|
||||
void DrawMultiStretchRects(
|
||||
const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
|
||||
void DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture12* dTex, ShaderConvert shader);
|
||||
|
||||
void BeginRenderPassForStretchRect(
|
||||
@@ -347,8 +355,8 @@ public:
|
||||
|
||||
// Assumes that the previous level has been transitioned to PS resource,
|
||||
// and the current level has been transitioned to RT.
|
||||
void RenderTextureMipmap(const D3D12Texture& texture,
|
||||
u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height);
|
||||
void RenderTextureMipmap(GSTexture12* texture, u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level,
|
||||
u32 src_width, u32 src_height);
|
||||
|
||||
// Ends a render pass if we're currently in one.
|
||||
// When Bind() is next called, the pass will be restarted.
|
||||
@@ -401,7 +409,8 @@ private:
|
||||
DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET | DIRTY_FLAG_PIPELINE |
|
||||
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_STENCIL_REF,
|
||||
|
||||
DIRTY_TFX_STATE = DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES | DIRTY_FLAG_TFX_SAMPLERS | DIRTY_FLAG_TFX_RT_TEXTURES,
|
||||
DIRTY_TFX_STATE =
|
||||
DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES | DIRTY_FLAG_TFX_SAMPLERS | DIRTY_FLAG_TFX_RT_TEXTURES,
|
||||
DIRTY_UTILITY_STATE = DIRTY_BASE_STATE,
|
||||
DIRTY_CONSTANT_BUFFER_STATE = DIRTY_FLAG_VS_CONSTANT_BUFFER | DIRTY_FLAG_PS_CONSTANT_BUFFER,
|
||||
};
|
||||
@@ -451,7 +460,7 @@ private:
|
||||
RootSignature m_current_root_signature = RootSignature::Undefined;
|
||||
const ID3D12PipelineState* m_current_pipeline = nullptr;
|
||||
|
||||
D3D12Texture m_null_texture;
|
||||
std::unique_ptr<GSTexture12> m_null_texture;
|
||||
|
||||
// current pipeline selector - we save this in the struct to avoid re-zeroing it every draw
|
||||
PipelineSelector m_pipeline_selector = {};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -28,99 +28,338 @@
|
||||
|
||||
#include "D3D12MemAlloc.h"
|
||||
|
||||
GSTexture12::GSTexture12(Type type, Format format, D3D12Texture texture)
|
||||
: m_texture(std::move(texture))
|
||||
GSTexture12::GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
|
||||
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<D3D12MA::Allocation> allocation,
|
||||
const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
|
||||
const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state)
|
||||
: m_resource(std::move(resource))
|
||||
, m_allocation(std::move(allocation))
|
||||
, m_srv_descriptor(srv_descriptor)
|
||||
, m_write_descriptor(write_descriptor)
|
||||
, m_uav_descriptor(uav_descriptor)
|
||||
, m_write_descriptor_type(wdtype)
|
||||
, m_dxgi_format(dxgi_format)
|
||||
, m_resource_state(resource_state)
|
||||
{
|
||||
m_type = type;
|
||||
m_format = format;
|
||||
m_size.x = m_texture.GetWidth();
|
||||
m_size.y = m_texture.GetHeight();
|
||||
m_mipmap_levels = m_texture.GetLevels();
|
||||
m_size.x = width;
|
||||
m_size.y = height;
|
||||
m_mipmap_levels = levels;
|
||||
}
|
||||
|
||||
GSTexture12::~GSTexture12()
|
||||
{
|
||||
GSDevice12::GetInstance()->UnbindTexture(this);
|
||||
Destroy(true);
|
||||
}
|
||||
|
||||
std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, u32 width, u32 height, u32 levels, Format format,
|
||||
DXGI_FORMAT d3d_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format)
|
||||
void GSTexture12::Destroy(bool defer)
|
||||
{
|
||||
GSDevice12::GetInstance()->UnbindTexture(this);
|
||||
|
||||
if (defer)
|
||||
{
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_srv_descriptor);
|
||||
|
||||
switch (m_write_descriptor_type)
|
||||
{
|
||||
case WriteDescriptorType::RTV:
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetRTVHeapManager(), &m_write_descriptor);
|
||||
break;
|
||||
case WriteDescriptorType::DSV:
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDSVHeapManager(), &m_write_descriptor);
|
||||
break;
|
||||
case WriteDescriptorType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_uav_descriptor)
|
||||
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_uav_descriptor);
|
||||
|
||||
g_d3d12_context->DeferResourceDestruction(m_allocation.get(), m_resource.get());
|
||||
m_resource.reset();
|
||||
m_allocation.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&m_srv_descriptor);
|
||||
|
||||
switch (m_write_descriptor_type)
|
||||
{
|
||||
case WriteDescriptorType::RTV:
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&m_write_descriptor);
|
||||
break;
|
||||
case WriteDescriptorType::DSV:
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&m_write_descriptor);
|
||||
break;
|
||||
case WriteDescriptorType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_uav_descriptor)
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&m_uav_descriptor);
|
||||
|
||||
m_resource.reset();
|
||||
m_allocation.reset();
|
||||
}
|
||||
|
||||
m_write_descriptor_type = WriteDescriptorType::None;
|
||||
}
|
||||
|
||||
std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int width, int height, int levels,
|
||||
DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
|
||||
DXGI_FORMAT uav_format)
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = levels;
|
||||
desc.Format = dxgi_format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
|
||||
D3D12MA::ALLOCATION_DESC allocationDesc = {};
|
||||
allocationDesc.Flags = D3D12MA::ALLOCATION_FLAG_WITHIN_BUDGET;
|
||||
allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12_CLEAR_VALUE optimized_clear_value = {};
|
||||
D3D12_RESOURCE_STATES state;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::Texture:
|
||||
{
|
||||
// This is a little annoying. basically, to do mipmap generation, we need to be a render target.
|
||||
// If it's a compressed texture, we won't be generating mips anyway, so this should be fine.
|
||||
const D3D12_RESOURCE_FLAGS flags = (levels > 1 && !IsCompressedFormat(format)) ?
|
||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET :
|
||||
D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
D3D12Texture texture;
|
||||
if (!texture.Create(
|
||||
width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, flags))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u texture", width, height);
|
||||
return std::make_unique<GSTexture12>(type, format, std::move(texture));
|
||||
desc.Flags = (levels > 1 && !IsCompressedFormat(format)) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET :
|
||||
D3D12_RESOURCE_FLAG_NONE;
|
||||
state = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::RenderTarget:
|
||||
{
|
||||
pxAssert(levels == 1);
|
||||
|
||||
// RT's tend to be larger, so we'll keep them committed for speed.
|
||||
D3D12Texture texture;
|
||||
if (!texture.Create(width, height, levels, d3d_format, srv_format, rtv_format, DXGI_FORMAT_UNKNOWN,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12MA::ALLOCATION_FLAG_COMMITTED))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u render target", width, height);
|
||||
return std::make_unique<GSTexture12>(type, format, std::move(texture));
|
||||
pxAssert(levels == 1);
|
||||
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
optimized_clear_value.Format = rtv_format;
|
||||
state = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::DepthStencil:
|
||||
{
|
||||
pxAssert(levels == 1);
|
||||
|
||||
D3D12Texture texture;
|
||||
if (!texture.Create(width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, dsv_format,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12MA::ALLOCATION_FLAG_COMMITTED))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u depth stencil", width, height);
|
||||
return std::make_unique<GSTexture12>(type, format, std::move(texture));
|
||||
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
optimized_clear_value.Format = dsv_format;
|
||||
state = D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::RWTexture:
|
||||
{
|
||||
pxAssert(levels == 1);
|
||||
|
||||
D3D12Texture texture;
|
||||
if (!texture.Create(width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12MA::ALLOCATION_FLAG_COMMITTED))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u RW texture", width, height);
|
||||
return std::make_unique<GSTexture12>(type, format, std::move(texture));
|
||||
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
if (uav_format != DXGI_FORMAT_UNKNOWN)
|
||||
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
|
||||
wil::com_ptr_nothrow<ID3D12Resource> resource;
|
||||
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation;
|
||||
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocationDesc, &desc, state,
|
||||
(type == Type::RenderTarget || type == Type::DepthStencil) ? &optimized_clear_value : nullptr, allocation.put(),
|
||||
IID_PPV_ARGS(resource.put()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// OOM isn't fatal.
|
||||
if (hr != E_OUTOFMEMORY)
|
||||
Console.Error("Create texture failed: 0x%08X", hr);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor;
|
||||
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
|
||||
if (srv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (!CreateSRVDescriptor(resource.get(), levels, srv_format, &srv_descriptor))
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::Texture:
|
||||
{
|
||||
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d texture", width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::RenderTarget:
|
||||
{
|
||||
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d render target", width, height);
|
||||
write_descriptor_type = WriteDescriptorType::RTV;
|
||||
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::DepthStencil:
|
||||
{
|
||||
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d depth stencil", width, height);
|
||||
write_descriptor_type = WriteDescriptorType::DSV;
|
||||
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::RWTexture:
|
||||
{
|
||||
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d RW texture", width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (uav_format != DXGI_FORMAT_UNKNOWN && !CreateUAVDescriptor(resource.get(), dsv_format, &uav_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&write_descriptor);
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
|
||||
return std::unique_ptr<GSTexture12>(
|
||||
new GSTexture12(type, format, width, height, levels, dxgi_format, std::move(resource), std::move(allocation),
|
||||
srv_descriptor, write_descriptor, uav_descriptor, write_descriptor_type, state));
|
||||
}
|
||||
|
||||
std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resource> resource, Type type, Format format,
|
||||
int width, int height, int levels, DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
|
||||
DXGI_FORMAT dsv_format, DXGI_FORMAT uav_format, D3D12_RESOURCE_STATES resource_state)
|
||||
{
|
||||
const D3D12_RESOURCE_DESC desc = resource->GetDesc();
|
||||
|
||||
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor;
|
||||
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
|
||||
if (srv_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (!CreateSRVDescriptor(resource.get(), desc.MipLevels, srv_format, &srv_descriptor))
|
||||
return {};
|
||||
}
|
||||
|
||||
if (type == Type::RenderTarget)
|
||||
{
|
||||
write_descriptor_type = WriteDescriptorType::RTV;
|
||||
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else if (type == Type::DepthStencil)
|
||||
{
|
||||
write_descriptor_type = WriteDescriptorType::DSV;
|
||||
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (uav_format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
if (!CreateUAVDescriptor(resource.get(), srv_format, &uav_descriptor))
|
||||
{
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&write_descriptor);
|
||||
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return std::unique_ptr<GSTexture12>(new GSTexture12(type, format, static_cast<u32>(desc.Width), desc.Height,
|
||||
desc.MipLevels, desc.Format, std::move(resource), {}, srv_descriptor, write_descriptor, uav_descriptor,
|
||||
write_descriptor_type, resource_state));
|
||||
}
|
||||
|
||||
bool GSTexture12::CreateSRVDescriptor(
|
||||
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
|
||||
format, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
|
||||
desc.Texture2D.MipLevels = levels;
|
||||
|
||||
g_d3d12_context->GetDevice()->CreateShaderResourceView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSTexture12::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetRTVHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_RENDER_TARGET_VIEW_DESC desc = {format, D3D12_RTV_DIMENSION_TEXTURE2D};
|
||||
g_d3d12_context->GetDevice()->CreateRenderTargetView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSTexture12::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDSVHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate SRV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, D3D12_DSV_FLAG_NONE};
|
||||
g_d3d12_context->GetDevice()->CreateDepthStencilView(resource, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSTexture12::CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
|
||||
{
|
||||
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
|
||||
{
|
||||
Console.Error("Failed to allocate UAV descriptor");
|
||||
return false;
|
||||
}
|
||||
|
||||
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {format, D3D12_UAV_DIMENSION_TEXTURE2D};
|
||||
g_d3d12_context->GetDevice()->CreateUnorderedAccessView(resource, nullptr, &desc, dh->cpu_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* GSTexture12::GetNativeHandle() const
|
||||
{
|
||||
return const_cast<D3D12Texture*>(&m_texture);
|
||||
return const_cast<GSTexture12*>(this);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* GSTexture12::GetCommandBufferForUpdate()
|
||||
@@ -198,7 +437,7 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
|
||||
srcloc.PlacedFootprint.Footprint.Width = width;
|
||||
srcloc.PlacedFootprint.Footprint.Height = height;
|
||||
srcloc.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcloc.PlacedFootprint.Footprint.Format = m_texture.GetFormat();
|
||||
srcloc.PlacedFootprint.Footprint.Format = m_dxgi_format;
|
||||
srcloc.PlacedFootprint.Footprint.RowPitch = upload_pitch;
|
||||
|
||||
// If the texture is larger than half our streaming buffer size, use a separate buffer.
|
||||
@@ -235,10 +474,10 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
|
||||
GL_PUSH("GSTexture12::Update({%d,%d} %dx%d Lvl:%u", r.x, r.y, r.width(), r.height(), layer);
|
||||
|
||||
// first time the texture is used? don't leave it undefined
|
||||
if (m_texture.GetState() == D3D12_RESOURCE_STATE_COMMON)
|
||||
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
else if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
m_texture.TransitionSubresourceToState(cmdlist, layer, m_texture.GetState(), D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
if (m_resource_state == D3D12_RESOURCE_STATE_COMMON)
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
else if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
TransitionSubresourceToState(cmdlist, layer, m_resource_state, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
// if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear
|
||||
if (m_type == Type::RenderTarget)
|
||||
@@ -250,7 +489,7 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
|
||||
}
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstloc;
|
||||
dstloc.pResource = m_texture.GetResource();
|
||||
dstloc.pResource = m_resource.get();
|
||||
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstloc.SubresourceIndex = layer;
|
||||
|
||||
@@ -258,8 +497,8 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
|
||||
cmdlist->CopyTextureRegion(&dstloc, Common::AlignDownPow2((u32)r.x, block_size),
|
||||
Common::AlignDownPow2((u32)r.y, block_size), 0, &srcloc, &srcbox);
|
||||
|
||||
if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
m_texture.TransitionSubresourceToState(cmdlist, layer, D3D12_RESOURCE_STATE_COPY_DEST, m_texture.GetState());
|
||||
if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
TransitionSubresourceToState(cmdlist, layer, D3D12_RESOURCE_STATE_COPY_DEST, m_resource_state);
|
||||
|
||||
if (m_type == Type::Texture)
|
||||
m_needs_mipmaps_generated |= (layer == 0);
|
||||
@@ -273,11 +512,9 @@ bool GSTexture12::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||
return false;
|
||||
|
||||
// map for writing
|
||||
m_map_area = r ? *r : GSVector4i(0, 0, m_texture.GetWidth(), m_texture.GetHeight());
|
||||
m_map_area = r ? *r : GetRect();
|
||||
m_map_level = layer;
|
||||
|
||||
m.pitch = Common::AlignUpPow2(
|
||||
m_map_area.width() * D3D12::GetTexelSize(m_texture.GetFormat()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
m.pitch = Common::AlignUpPow2(CalcUploadPitch(m_map_area.width()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
|
||||
// see note in Update() for the reason why.
|
||||
const u32 required_size = CalcUploadSize(m_map_area.height(), m.pitch);
|
||||
@@ -300,14 +537,12 @@ bool GSTexture12::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||
void GSTexture12::Unmap()
|
||||
{
|
||||
// this can't handle blocks/compressed formats at the moment.
|
||||
pxAssert(m_map_level < m_texture.GetLevels() && !IsCompressedFormat());
|
||||
pxAssert(m_map_level < m_mipmap_levels && !IsCompressedFormat());
|
||||
g_perfmon.Put(GSPerfMon::TextureUploads, 1);
|
||||
|
||||
// TODO: non-tightly-packed formats
|
||||
const u32 width = static_cast<u32>(m_map_area.width());
|
||||
const u32 height = static_cast<u32>(m_map_area.height());
|
||||
const u32 pitch = Common::AlignUpPow2(
|
||||
m_map_area.width() * D3D12::GetTexelSize(m_texture.GetFormat()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const u32 width = m_map_area.width();
|
||||
const u32 height = m_map_area.height();
|
||||
const u32 pitch = Common::AlignUpPow2(CalcUploadPitch(width), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const u32 required_size = CalcUploadSize(height, pitch);
|
||||
D3D12StreamBuffer& buffer = g_d3d12_context->GetTextureStreamBuffer();
|
||||
const u32 buffer_offset = buffer.GetCurrentOffset();
|
||||
@@ -318,11 +553,10 @@ void GSTexture12::Unmap()
|
||||
m_map_area.height(), m_map_level);
|
||||
|
||||
// first time the texture is used? don't leave it undefined
|
||||
if (m_texture.GetState() == D3D12_RESOURCE_STATE_COMMON)
|
||||
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
else if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
m_texture.TransitionSubresourceToState(
|
||||
cmdlist, m_map_level, m_texture.GetState(), D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
if (m_resource_state == D3D12_RESOURCE_STATE_COMMON)
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
else if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
TransitionSubresourceToState(cmdlist, m_map_level, m_resource_state, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
// if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear
|
||||
if (m_type == Type::RenderTarget)
|
||||
@@ -340,20 +574,19 @@ void GSTexture12::Unmap()
|
||||
srcloc.PlacedFootprint.Footprint.Width = width;
|
||||
srcloc.PlacedFootprint.Footprint.Height = height;
|
||||
srcloc.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcloc.PlacedFootprint.Footprint.Format = m_texture.GetFormat();
|
||||
srcloc.PlacedFootprint.Footprint.Format = m_dxgi_format;
|
||||
srcloc.PlacedFootprint.Footprint.RowPitch = pitch;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstloc;
|
||||
dstloc.pResource = m_texture.GetResource();
|
||||
dstloc.pResource = m_resource.get();
|
||||
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstloc.SubresourceIndex = m_map_level;
|
||||
|
||||
const D3D12_BOX srcbox{0u, 0u, 0u, width, height, 1};
|
||||
cmdlist->CopyTextureRegion(&dstloc, m_map_area.x, m_map_area.y, 0, &srcloc, &srcbox);
|
||||
|
||||
if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
m_texture.TransitionSubresourceToState(
|
||||
cmdlist, m_map_level, D3D12_RESOURCE_STATE_COPY_DEST, m_texture.GetState());
|
||||
if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
|
||||
TransitionSubresourceToState(cmdlist, m_map_level, D3D12_RESOURCE_STATE_COPY_DEST, m_resource_state);
|
||||
|
||||
if (m_type == Type::Texture)
|
||||
m_needs_mipmaps_generated |= (m_map_level == 0);
|
||||
@@ -372,7 +605,7 @@ void GSTexture12::GenerateMipmap()
|
||||
const int dst_height = std::max<int>(m_size.y >> dst_level, 1);
|
||||
|
||||
GSDevice12::GetInstance()->RenderTextureMipmap(
|
||||
m_texture, dst_level, dst_width, dst_height, src_level, src_width, src_height);
|
||||
this, dst_level, dst_width, dst_height, src_level, src_width, src_height);
|
||||
}
|
||||
|
||||
SetUsedThisCommandBuffer();
|
||||
@@ -381,16 +614,39 @@ void GSTexture12::GenerateMipmap()
|
||||
void GSTexture12::Swap(GSTexture* tex)
|
||||
{
|
||||
GSTexture::Swap(tex);
|
||||
std::swap(m_texture, static_cast<GSTexture12*>(tex)->m_texture);
|
||||
std::swap(m_resource, static_cast<GSTexture12*>(tex)->m_resource);
|
||||
std::swap(m_allocation, static_cast<GSTexture12*>(tex)->m_allocation);
|
||||
std::swap(m_srv_descriptor, static_cast<GSTexture12*>(tex)->m_srv_descriptor);
|
||||
std::swap(m_write_descriptor, static_cast<GSTexture12*>(tex)->m_write_descriptor);
|
||||
std::swap(m_write_descriptor_type, static_cast<GSTexture12*>(tex)->m_write_descriptor_type);
|
||||
std::swap(m_dxgi_format, static_cast<GSTexture12*>(tex)->m_dxgi_format);
|
||||
std::swap(m_resource_state, static_cast<GSTexture12*>(tex)->m_resource_state);
|
||||
std::swap(m_use_fence_counter, static_cast<GSTexture12*>(tex)->m_use_fence_counter);
|
||||
std::swap(m_clear_value, static_cast<GSTexture12*>(tex)->m_clear_value);
|
||||
std::swap(m_map_area, static_cast<GSTexture12*>(tex)->m_map_area);
|
||||
std::swap(m_map_level, static_cast<GSTexture12*>(tex)->m_map_level);
|
||||
std::swap(m_map_area, static_cast<GSTexture12*>(tex)->m_map_area);
|
||||
}
|
||||
|
||||
void GSTexture12::TransitionToState(D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
m_texture.TransitionToState(g_d3d12_context->GetCommandList(), state);
|
||||
TransitionToState(g_d3d12_context->GetCommandList(), state);
|
||||
}
|
||||
|
||||
void GSTexture12::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
if (m_resource_state == state)
|
||||
return;
|
||||
|
||||
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_resource_state, state);
|
||||
m_resource_state = state;
|
||||
}
|
||||
|
||||
void GSTexture12::TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, int level,
|
||||
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const
|
||||
{
|
||||
const D3D12_RESOURCE_BARRIER barrier = {D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||
{{m_resource.get(), static_cast<u32>(level), before_state, after_state}}};
|
||||
cmdlist->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
void GSTexture12::CommitClear()
|
||||
@@ -407,14 +663,14 @@ void GSTexture12::CommitClear(ID3D12GraphicsCommandList* cmdlist)
|
||||
{
|
||||
if (IsDepthStencil())
|
||||
{
|
||||
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||
cmdlist->ClearDepthStencilView(
|
||||
m_texture.GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, m_clear_value.depth, 0, 0, nullptr);
|
||||
GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, m_clear_value.depth, 0, 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(m_texture.GetWriteDescriptor(), m_clear_value.color, 0, nullptr);
|
||||
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
cmdlist->ClearRenderTargetView(GetWriteDescriptor(), m_clear_value.color, 0, nullptr);
|
||||
}
|
||||
|
||||
SetState(GSTexture::State::Dirty);
|
||||
@@ -498,7 +754,7 @@ void GSDownloadTexture12::CopyFromTexture(
|
||||
dstloc.pResource = m_buffer.get();
|
||||
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
dstloc.PlacedFootprint.Offset = copy_offset;
|
||||
dstloc.PlacedFootprint.Footprint.Format = tex12->GetNativeFormat();
|
||||
dstloc.PlacedFootprint.Footprint.Format = tex12->GetDXGIFormat();
|
||||
dstloc.PlacedFootprint.Footprint.Width = drc.width();
|
||||
dstloc.PlacedFootprint.Footprint.Height = drc.height();
|
||||
dstloc.PlacedFootprint.Footprint.Depth = 1;
|
||||
@@ -506,8 +762,7 @@ void GSDownloadTexture12::CopyFromTexture(
|
||||
|
||||
const D3D12_RESOURCE_STATES old_layout = tex12->GetResourceState();
|
||||
if (old_layout != D3D12_RESOURCE_STATE_COPY_SOURCE)
|
||||
tex12->GetTexture().TransitionSubresourceToState(
|
||||
cmdlist, src_level, old_layout, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
tex12->TransitionSubresourceToState(cmdlist, src_level, old_layout, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
// TODO: Rules for depth buffers here?
|
||||
const D3D12_BOX srcbox{static_cast<UINT>(src.left), static_cast<UINT>(src.top), 0u, static_cast<UINT>(src.right),
|
||||
@@ -515,8 +770,7 @@ void GSDownloadTexture12::CopyFromTexture(
|
||||
cmdlist->CopyTextureRegion(&dstloc, 0, 0, 0, &srcloc, &srcbox);
|
||||
|
||||
if (old_layout != D3D12_RESOURCE_STATE_COPY_SOURCE)
|
||||
tex12->GetTexture().TransitionSubresourceToState(
|
||||
cmdlist, src_level, D3D12_RESOURCE_STATE_COPY_SOURCE, old_layout);
|
||||
tex12->TransitionSubresourceToState(cmdlist, src_level, D3D12_RESOURCE_STATE_COPY_SOURCE, old_layout);
|
||||
|
||||
m_copy_fence_value = g_d3d12_context->GetCurrentFenceValue();
|
||||
m_needs_flush = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
@@ -18,23 +18,35 @@
|
||||
#include "GS/GS.h"
|
||||
#include "GS/Renderers/Common/GSTexture.h"
|
||||
#include "GS/Renderers/DX12/D3D12Context.h"
|
||||
#include "GS/Renderers/DX12/D3D12Texture.h"
|
||||
#include "GS/Renderers/DX12/D3D12DescriptorHeapManager.h"
|
||||
|
||||
#include "common/RedtapeWilCom.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace D3D12MA
|
||||
{
|
||||
class Allocation;
|
||||
}
|
||||
|
||||
class GSTexture12 final : public GSTexture
|
||||
{
|
||||
public:
|
||||
GSTexture12(Type type, Format format, D3D12Texture texture);
|
||||
~GSTexture12() override;
|
||||
|
||||
static std::unique_ptr<GSTexture12> Create(Type type, u32 width, u32 height, u32 levels, Format format,
|
||||
DXGI_FORMAT d3d_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format);
|
||||
static std::unique_ptr<GSTexture12> Create(Type type, Format format, int width, int height, int levels,
|
||||
DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
|
||||
DXGI_FORMAT uav_format);
|
||||
static std::unique_ptr<GSTexture12> Adopt(wil::com_ptr_nothrow<ID3D12Resource> resource, Type type, Format format,
|
||||
int width, int height, int levels, DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
|
||||
DXGI_FORMAT dsv_format, DXGI_FORMAT uav_format, D3D12_RESOURCE_STATES resource_state);
|
||||
|
||||
__fi D3D12Texture& GetTexture() { return m_texture; }
|
||||
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_texture.GetSRVDescriptor(); }
|
||||
__fi const D3D12DescriptorHandle& GetRTVOrDSVHandle() const { return m_texture.GetWriteDescriptor(); }
|
||||
__fi D3D12_RESOURCE_STATES GetResourceState() const { return m_texture.GetState(); }
|
||||
__fi DXGI_FORMAT GetNativeFormat() const { return m_texture.GetFormat(); }
|
||||
__fi ID3D12Resource* GetResource() const { return m_texture.GetResource(); }
|
||||
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
|
||||
__fi const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
|
||||
__fi const D3D12DescriptorHandle& GetUAVDescriptor() const { return m_uav_descriptor; }
|
||||
__fi D3D12_RESOURCE_STATES GetResourceState() const { return m_resource_state; }
|
||||
__fi DXGI_FORMAT GetDXGIFormat() const { return m_dxgi_format; }
|
||||
__fi ID3D12Resource* GetResource() const { return m_resource.get(); }
|
||||
|
||||
void* GetNativeHandle() const override;
|
||||
|
||||
@@ -48,22 +60,55 @@ public:
|
||||
void CommitClear();
|
||||
void CommitClear(ID3D12GraphicsCommandList* cmdlist);
|
||||
|
||||
void Destroy(bool defer = true);
|
||||
|
||||
void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
|
||||
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, int level, D3D12_RESOURCE_STATES before_state,
|
||||
D3D12_RESOURCE_STATES after_state) const;
|
||||
|
||||
// Call when the texture is bound to the pipeline, or read from in a copy.
|
||||
__fi void SetUsedThisCommandBuffer() { m_use_fence_counter = g_d3d12_context->GetCurrentFenceValue(); }
|
||||
|
||||
private:
|
||||
enum class WriteDescriptorType : u8
|
||||
{
|
||||
None,
|
||||
RTV,
|
||||
DSV
|
||||
};
|
||||
|
||||
GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
|
||||
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<D3D12MA::Allocation> allocation,
|
||||
const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
|
||||
const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state);
|
||||
|
||||
static bool CreateSRVDescriptor(
|
||||
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
|
||||
|
||||
ID3D12GraphicsCommandList* GetCommandBufferForUpdate();
|
||||
ID3D12Resource* AllocateUploadStagingBuffer(const void* data, u32 pitch, u32 upload_pitch, u32 height) const;
|
||||
void CopyTextureDataForUpload(void* dst, const void* src, u32 pitch, u32 upload_pitch, u32 height) const;
|
||||
|
||||
D3D12Texture m_texture;
|
||||
wil::com_ptr_nothrow<ID3D12Resource> m_resource;
|
||||
wil::com_ptr_nothrow<D3D12MA::Allocation> m_allocation;
|
||||
|
||||
D3D12DescriptorHandle m_srv_descriptor = {};
|
||||
D3D12DescriptorHandle m_write_descriptor = {};
|
||||
D3D12DescriptorHandle m_uav_descriptor = {};
|
||||
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
|
||||
|
||||
DXGI_FORMAT m_dxgi_format = DXGI_FORMAT_UNKNOWN;
|
||||
D3D12_RESOURCE_STATES m_resource_state = D3D12_RESOURCE_STATE_COMMON;
|
||||
|
||||
// Contains the fence counter when the texture was last used.
|
||||
// When this matches the current fence counter, the texture was used this command buffer.
|
||||
u64 m_use_fence_counter = 0;
|
||||
|
||||
int m_map_level = std::numeric_limits<int>::max();
|
||||
GSVector4i m_map_area = GSVector4i::zero();
|
||||
u32 m_map_level = UINT32_MAX;
|
||||
};
|
||||
|
||||
class GSDownloadTexture12 final : public GSDownloadTexture
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user