Compare commits

...
126 Commits
Author SHA1 Message Date
Christian Kennyandrefractionpcsx2 791f2a63ac 3rdparty: Upgrade xbyak to 6.00 2021-11-22 15:37:44 +00:00
refractionpcsx2 1917f2b98a GS: Re-remove part of Clamp Repeat opt.
This is kind of not needed, it's handled above really.
2021-11-22 10:35:19 +00:00
Connor McLaughlinandlightningterror 78b74f1115 GLLoader: Remove glCopyTextureSubImage2D() wrapper
Not needed anymore.
2021-11-22 05:53:44 +01:00
Connor McLaughlinandlightningterror 8ea24d9ff9 GS/OpenGL: Use shader+draw for CopyRectConv 2021-11-22 05:53:44 +01:00
Ty Lamontagneandlightningterror f36d5fdbdf Debugger: Format search hits with proper specifier 2021-11-21 22:00:49 +01:00
RedDevilusandrefractionpcsx2 d421fc6e6f GUI: Bring back F6 string (Aspect Ratio)
Fixes regression from https://github.com/PCSX2/pcsx2/pull/4140
2021-11-21 20:28:23 +00:00
refractionpcsx2 90c4c9e96b Build: Fix clang
Stupid thing, the actions builds were fine!
2021-11-21 18:43:37 +00:00
refractionpcsx2 0a79892923 microVU: Preserve XGKIck cycles in delay slot
Also added handling for xgkick sync on single instructions
2021-11-21 17:18:34 +00:00
refractionpcsx2 d88f638fbc GS: Redo the Texture min/max opt 2021-11-21 17:18:11 +00:00
Christian Kennyandrefractionpcsx2 d29121a871 Core: Reset game loaded/started variables on recompiler shutdown. 2021-11-21 03:25:37 +00:00
Christian Kennyandrefractionpcsx2 5b8e983478 ELFHeader: Detect CRC properly for PSX games, improve formatting of game serial output. 2021-11-21 03:25:37 +00:00
Christian Kennyandrefractionpcsx2 24d47cb10b Don't update saveslot info if VM isn't running yet 2021-11-21 03:25:37 +00:00
Christian Kennyandrefractionpcsx2 ae7b84a85f Savestates: Use folders for organizing savestates per game. 2021-11-21 03:25:37 +00:00
Mrlinkwiiandrefractionpcsx2 161240045f Gamedb: add various fixes for various games and removal of patches 2021-11-21 03:03:21 +00:00
refractionpcsx2 fe85fc9d25 GIF: Modify fifo read behaviour
Fixes some glitching in Need for Speed Underground 2
2021-11-21 03:01:03 +00:00
arcum42andGitHub b8a2cd1b06 PAD: Call one joint pad header in most of pcsx2, not two. (#4985)
Add Gamepad.h

Cleanup.

Remove the Windows version of PAD.h as well.

Update CMakeLists.txt

Revert language changes.
2021-11-20 18:57:58 -08:00
refractionpcsx2 eee51828cb Build: Remove old unused cheatscpp.h file 2021-11-21 00:22:34 +00:00
refractionpcsx2 1eddd9017b 3rd Party: Update rogue file to correct license.
Got missed in an update as they switched to auto generation, but the license was switched prior to us last updating the library. See this commit: https://github.com/libsndfile/libsamplerate/commit/819c6a8d680d7385ce54f5e0d4ff62266d349d05#diff-dcf9d0451a6397210424fc9699e209255660a4d3b3072c2f1b35048df8df4092
2021-11-20 23:33:48 +00:00
tellowkrinkleandGitHub 9c0582a103 wx: Fix pxExplore on macOS (#4989)
* wx: Fix `pxExplore` on macOS

Trying to open file urls in a browser does not actually launch a file explorer in macOS

* wx: Remove pxExplore/pxLaunch

Was barely used
2021-11-19 18:35:50 -08:00
arcum42andGitHub 6cd8b34abb Update the FAQ, as well as some general cleanup. (#5033)
* Update the FAQ, as well as some general cleanup.

* A few more adjustments.

* Change indentation.

* Minor changes.

* Remove the information about the time, which was incorrect.

* Life is like a hurricane...

* Modify Windows controller information.

* Add more ways to contribute.
2021-11-19 16:22:44 -08:00
Ty Lamontagneandrefractionpcsx2 47075bec49 Debugger: Make memory dialog transparent
Was supposed to do this in my initial memory search pr but ended up removing while fighting with git accidentally.
2021-11-19 00:53:05 +00:00
lightningterror 8eb6cbd400 GS-gui: Change blending option from None to Minimum.
None doesn't actually fully disable sw blending, so the option is a bit inaccurate, rename it to Minimum instead.

Also slightly update tooltip.
2021-11-17 22:44:51 +01:00
TellowKrinkleandtellowkrinkle 8f394b5c3f GHActions:macos: Remove gtk3 dependency 2021-11-17 14:23:15 -06:00
TellowKrinkleandtellowkrinkle 2245315b60 CMake: Remove gtk dep on macOS
We only need gio now
2021-11-17 14:23:15 -06:00
Connor McLaughlinandrefractionpcsx2 0d40661b33 VSProps: Set MultiProcessorCompilation in CodeGen props 2021-11-16 10:08:20 +00:00
refractionpcsx2 e015b91ed1 CDVD: Don't allow DMA read if DMA isn't running 2021-11-16 09:31:34 +00:00
PCSX2 Botandlightningterror de577709d9 pad-linux: Update to latest controller database. 2021-11-15 17:19:19 +01:00
refractionpcsx2 52c6d79975 VS: Organise filter confusion between GS and GIF files 2021-11-14 21:57:33 +00:00
refractionpcsx2 512064f1b5 GS: Only reload Auto MIPs on TEX base change 2021-11-14 21:57:33 +00:00
Ty Lamontagneandrefractionpcsx2 a396b50610 Debugger: Allow access to all of 0xBXXXXXXX 2021-11-14 20:19:33 +00:00
TellowKrinkleandtellowkrinkle 67299fcd9f Core: Remove __packed macro 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle f7476dfb63 Core: Replace alignment macros with alignas 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle 87f7672dbf GS: Remove windows includes from GS.h 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle 648a958290 GS: Split GS.h into multiple smaller headers 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle ed90e2fcf9 GS: Header cleanup 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle b74be70ffc GS: Switch integer typedefs to match rest of pcsx2
Had to capitalize the names of some struct params that had the same names
2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle 2351431d71 Misc: Remove custom countof macros in favor of std::size 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle 7435f76609 Misc: Move GS preprocessor defs to main PCSX2 file 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle d2c1a4a7fb Core: Add header for PCSX2-specific preprocessor definitions 2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle e37fbfddc3 Misc: Better GCC defs
Less warnings about fastcall being unsupported, proper __assume implementation
2021-11-14 13:52:20 -06:00
TellowKrinkleandtellowkrinkle 8ab884a89e Misc: Format Pcsx2Defs.h 2021-11-14 13:52:20 -06:00
Mrlinkwiiandrefractionpcsx2 42f438146c GameDB: add ee-rounding and vu-rounding to various entries 2021-11-14 16:31:25 +00:00
TellowKrinkleandtellowkrinkle 08b1b350db wx: Remove wxString implicit conversion to std::string on windows
Can be lossy, and no one likes a lossy implicit conversion
2021-11-13 18:44:26 -06:00
TellowKrinkleandtellowkrinkle cbcd9b5004 wx: Remove wxString implicit constructor from std::string
On windows, it uses the current system's character encoding instead of utf-8, which breaks a lot of things.  We should avoid it.
2021-11-13 18:44:26 -06:00
TellowKrinkleandtellowkrinkle 162a0bbe46 CMake: Fix duplicate definition of WavFile on Windows 2021-11-13 18:44:26 -06:00
refractionpcsx2 69d50e583e GameDB: Patches for MX Vs ATV Unleashed SPS 2021-11-13 18:51:11 +00:00
orbeaandrefractionpcsx2 40a8384087 Update libchdr
Fixes https://github.com/PCSX2/pcsx2/issues/5009
2021-11-13 01:11:37 +00:00
lightningterror 6053b2b5c9 GS-wx: Adjust some checkboxes to be in alphabetical order. 2021-11-12 20:32:18 +01:00
TellowKrinkleandlightningterror 7e17497c1e GS: Require hardware renderer for hacks in wx config 2021-11-12 20:15:07 +01:00
TellowKrinkleandlightningterror b573be918e wx:GS: Grow notebook with GS settings pane 2021-11-12 20:15:07 +01:00
TellowKrinkleandlightningterror 2fada14a65 GS: Fix Half Pixel Offset and Half Screen Fix config swap 2021-11-12 20:15:07 +01:00
TellowKrinkleandtellowkrinkle cf64a2bc8e GS: Rename accurate date config option 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 39fd3479b7 Core: Add dev mode config 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 536133289f wx:GS: Pad all the things 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 3f280649a9 GS: Make spinners full width in wx config
Lines up nicer with other elements
2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 6c80aa8c98 GS: Add D3D11 blend mode selector to wx config 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 65c39f600f GS: Renderer and upscale prerequisites for wx config 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 3b5a9f6c6a GS: More generic prerequisite checking for wx config 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle 665db4bdad wx: Stop tripping wx3.1+ asserts in gs config 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle b34e7fa303 GS: Add X and Y labels to wx settings texture offset 2021-11-11 18:18:28 -06:00
kojinandtellowkrinkle abc0458d4f GS: remove image header from wx settings dialog 2021-11-11 18:18:28 -06:00
kojinandtellowkrinkle 1e35398a84 GS: new wx config dialog working on windows 2021-11-11 18:18:28 -06:00
kojinandtellowkrinkle be3253bf87 d3d: abstract some dxgi functionality
- adapters are now referenced by index instead of string matching, hopefully this will make a few things easier
- add a setting to enable dxgi/device debugging (instead of hiding it behind a compiler macro)
- improve logging
- remove some d3d cruft from gsutils
2021-11-11 18:18:28 -06:00
arcum42andtellowkrinkle 241a762d04 GS: Switch to wx config dialog 2021-11-11 18:18:28 -06:00
TellowKrinkleandtellowkrinkle b944687191 GS: Clean up wx config code 2021-11-11 18:18:28 -06:00
arcum42andtellowkrinkle 736c66ee31 GS: Add tooltips to the wx settings dialog 2021-11-11 18:18:28 -06:00
arcum42andtellowkrinkle d96f31d01b GS: Add new wx version of GS settings dialog 2021-11-11 18:18:28 -06:00
Mrlinkwiiandrefractionpcsx2 e30c096d87 GameDB:add 'GIFFIFOHack' to 'Gunfighter 2 - Legend of Jesse James' 2021-11-11 09:15:35 +00:00
Ty Lamontagneandrefractionpcsx2 be71b98c55 Debugger: Update enums and fix 32 bit support
Also move bitcast to a proper location
2021-11-11 00:41:40 +00:00
Ty Lamontagneandrefractionpcsx2 6bec3162f6 Debugger: Use bit_cast where needed, cleanup some stuff 2021-11-11 00:41:40 +00:00
Ty Lamontagneandrefractionpcsx2 c863876dee Debugger: Implement CtrlMemorySearch 2021-11-11 00:41:40 +00:00
TellowKrinkleandrefractionpcsx2 f5d0542f06 DEV9-GUI: Rearrange config interface
Fixes HDD Size ticks from 1 to 10 (40,50,60,...) and less squished together.
2021-11-11 00:40:23 +00:00
RedDevilusandrefractionpcsx2 b1650eb503 PCSX2-GUI: Fix Groupboxes to align correctly
Make things look more symmetrical and structured.
Affects Audio Settings (SPU2) , Gamepad Settings (PAD) + Network and HDD Settings (DEV9).
For audio settings the slider will no longer do 0.5 steps when you change from TimeStretch. Reduce max audio latency from 750 to 200 (less is better if your PC can handle it).
Windows SPU2 codebase is in dire need of a rehaul on how it handles this behaviour (not convert it multiple times).
2021-11-11 00:40:23 +00:00
Mrlinkwiiandrefractionpcsx2 82b090e234 GameDB: add nearest rounding to 'Hitman - Contracts' and various fixes 2021-11-10 14:14:52 +00:00
lightningterror 7f1e416d31 GS-ogl: Remove device, driver checks in GLLoader.
Duplicate, it is already handled elsewhere.

Also cleanup some stuff.
2021-11-10 02:27:18 +01:00
Ty Lamontagneandlightningterror 4312bf711c Debugger: Fix breakpoint window on linux 2021-11-09 18:07:46 +01:00
Ty Lamontagneandlightningterror f8061448d1 Debugger: Reset breakpoint skip on savestate load 2021-11-09 18:06:54 +01:00
PCSX2 Botandlightningterror e934bec4b7 pad-linux: Update to latest controller database. 2021-11-08 17:27:08 +01:00
TellowKrinkleandrefractionpcsx2 4e5d7ba8ef GS:SW: Fix fog on x64 avx2 2021-11-08 09:19:05 +00:00
TellowKrinkleandrefractionpcsx2 59fd815c3d GS: Faster GSOffset::PAHelper 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 b901c6af71 GS: Switch back to row+column for pixel lookups
Code for the full calculation was way too complicated to run for every pixel in a loop
2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 b2fb6c7804 GS: Don't calculate a pageOffset per bp 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 84c5f8f738 GS: Remove rowOffset 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 39c7f11b98 GS: Pixel loop optimizations 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 86a2d73931 GS: Clean up old GSOffset remnants 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 8eb50c3517 GS: Switch to new non-cached GSOffset 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 d9defb19f9 GS: Add new GSOffset class 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 874804bcfd GS: Add block/page loop functions to GSSwizzleInfo 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 b0f9662811 GS: Add srav and blend backwards compat to GSVector4i 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 24850823a2 GS: Use new swizzle calculation class 2021-11-07 03:44:31 +00:00
TellowKrinkleandrefractionpcsx2 951604475b GS: Add class for swizzle calculations 2021-11-07 03:44:31 +00:00
Ty Lamontagneandrefractionpcsx2 74f3bb2aa9 Debugger: Make the register list DPI aware 2021-11-07 03:43:55 +00:00
Tyler Wildingandrefractionpcsx2 4442b798c9 CDVD: set the correct RTC year when input recording 2021-11-07 02:21:01 +00:00
Tyler Wildingandrefractionpcsx2 f10a8de2c1 input-rec: Use a constant RTC for power-on recordings 2021-11-06 16:24:53 +00:00
Tokman5andrefractionpcsx2 329b29269b GameDB: Add and fix Power Pros series 2021-11-06 16:23:02 +00:00
Mrlinkwiiandrefractionpcsx2 5b3ffe6bab GameDB: add EE clamping to 'Shadow of Zorro' and 'Evil Twin - Cyprien's Chronicles'
GameDB: add EE clamping to 'Shadow of Zorro' and 'Evil Twin - Cyprien's Chronicles'
2021-11-06 16:20:04 +00:00
JoeyandGitHub fb14500b41 pad-linux: Abort 'set all btns' on escape key + gui fixes (#4809) 2021-11-06 00:44:08 -07:00
TellowKrinkleandtellowkrinkle ad29594d08 Use correct clock for GS fps calculations on unix 2021-11-05 23:11:53 -05:00
tellowkrinkle 37e2142cca Common: Fix Darwin thread times
Percentages will now actually be percentages instead of permille (units of 1/1000)
Was caused by trying to match Windows's returns of 100ns units, but then reporting 1µs units from `GetThreadTicksPerSecond()`
2021-11-05 23:11:53 -05:00
tellowkrinkle 1e5f1de12c CMake: Increase deployment target to 10.13
Allows use of throwing `optional` and `variant` methods
2021-11-05 23:11:53 -05:00
tellowkrinkle 0f93dbcd5e USB: Make save state non-required
Fixes save state loading for systems using a null USB plugin (macOS, BSD)
2021-11-05 23:11:53 -05:00
RedDevilusandrefractionpcsx2 e415d85dbe GameDB: Add and fix SingStar Entries
I noticed we had a ton of missing SingStar serial + minor other fixes.
2021-11-05 15:59:29 +00:00
Mrlinkwiiandrefractionpcsx2 4c8bf53e69 CI:Add build date to program log of nightly builds 2021-11-05 01:16:08 +00:00
refractionpcsx2 83fcd4bd1f SPU: Kind of revert last ADMA change. Clear as reading.
This is a temporary measure while we run some hardware tests, the previous change broke Burnout 3's engine sounds.
2021-11-04 20:13:18 +00:00
TellowKrinkleandrefractionpcsx2 bfd960ad1b GHActions:Linux: Upgrade to Clang 9 2021-11-04 20:11:15 +00:00
qurious-pixelandrefractionpcsx2 6b81808ecc gcc compatibility for older distros
Add compatibility layer for using newer gcc on older distros.
- use AppImageKit-checkrt
- copy build system stdc++ and gcc_s
2021-11-04 20:11:15 +00:00
TellowKrinkleandrefractionpcsx2 c615a6f6e2 GHActions:Linux: Upgrade to GCC 10 2021-11-04 20:11:15 +00:00
TellowKrinkleandrefractionpcsx2 40b522b42f GHActions:Linux: Remove unneccessary packages 2021-11-04 20:11:15 +00:00
TellowKrinkleandrefractionpcsx2 f2655b763f GHActions:Linux: Clean up setup scripts 2021-11-04 20:11:15 +00:00
TellowKrinkleandrefractionpcsx2 fd145e65aa GS: Remove virtual destructor from GSAlignedClass
No point, and made it not a standard layout type
2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 6596b7f27e GS: Enable AVX2 on x64 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 9d767838d6 GS: Remove old DrawScanline code generators 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 f55219bb1b GS: Replace 6 DrawScanline code generators with one merged one 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 805b647c73 GS: Remove old SetupPrim code generators 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 fd0351ca8f GS: Replace 6 SetupPrim code generators with one merged one 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 ed5a7802f3 Common: Add non-constant offsetof macro 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 44f8317b7e GS: Add new code generator for easy native-isa codegen 2021-11-04 19:32:27 +00:00
TellowKrinkleandrefractionpcsx2 0200933ddd GS: Don't catch code generation exceptions
If codegen throws an exception, it ends up just crashing when you jump to the incompletely-generated code which is kind of useless
2021-11-04 19:32:27 +00:00
lightningterror f712b2b63a GSDeviceOGL: Fix Wunused-private-field warnings. 2021-11-04 11:18:26 +01:00
Tyler Wildingandrefractionpcsx2 71923e7cba actions: cleanup discord embed links and add release body 2021-11-03 23:46:45 +00:00
refractionpcsx2 532d14611c GS: Properly loop when reading 32bit CLUT from offset 2021-11-03 18:24:57 +00:00
refractionpcsx2 3a91a07d51 GS: Fix up CLUT offset handling in 32bit I8 mode 2021-11-03 18:24:57 +00:00
refractionpcsx2 6a8287ea9f EE JIT: Backup shift on LDR/L if rs==rt 2021-11-03 18:03:09 +00:00
Tyler Wildingandlightningterror dc051541bd actions: create automatic controller db updating workflow 2021-11-03 16:40:36 +01:00
lightningterror 3265c2a614 GS-ogl: Put GL_ARB_get_texture_sub_image code under a define.
Code is currently disabled, no need to check for the extension.
2021-11-03 16:37:55 +01:00
lightningterror f798401e93 GS-ogl: Remove checks for extensions we don't yet use.
They serve no purpose, no need to check unless we actually use them

GL_ARB_compute_shader,
GL_ARB_shader_storage_buffer_object,
GL_ARB_texture_view,
GL_ARB_vertex_attrib_binding,
GL_ARB_multi_bind
2021-11-03 16:37:55 +01:00
322 changed files with 16289 additions and 27306 deletions
+1 -1
View File
@@ -99,7 +99,7 @@ jobs:
run: |
# To save time, only brew update if running the install without it fails
function do-install() {
brew install sound-touch portaudio wxmac gtk+3 sdl2 libsamplerate
brew install sound-touch portaudio wxmac sdl2 libsamplerate
}
if ! do-install; then
brew update
@@ -0,0 +1 @@
*.txt
@@ -0,0 +1,38 @@
import os
relevant_categories = [
"# Mac OS X",
"# Linux"
]
header_lines = []
new_db_contents = []
def is_relevant_category(line):
for category in relevant_categories:
if category in line:
return True
return False
with open("./game_controller_db.txt") as file:
lines = file.readlines()
finished_header = False
processing_section = False
for line in lines:
if finished_header is False:
header_lines.append(line)
if line == "\n":
finished_header = True
if processing_section and line == "\n":
processing_section = False
new_db_contents.append("\n")
if is_relevant_category(line) and processing_section is False:
processing_section = True
new_db_contents.append(line)
elif processing_section:
new_db_contents.append(line)
os.remove("./game_controller_db.txt")
with open("./game_controller_db.txt", "w") as f:
f.writelines(header_lines)
f.writelines(new_db_contents)
+7 -1
View File
@@ -37,11 +37,15 @@ mkdir -p squashfs-root/usr/share/icons && cp ./squashfs-root/PCSX2.png ./squashf
mkdir -p squashfs-root/usr/share/icons/hicolor/scalable/apps && cp ./squashfs-root/PCSX2.png ./squashfs-root/usr/share/icons/hicolor/scalable/apps
mkdir -p squashfs-root/usr/share/pixmaps && cp ./squashfs-root/PCSX2.png ./squashfs-root/usr/share/pixmaps
mkdir -p squashfs-root/usr/lib/
mkdir -p squashfs-root/usr/optional/libstdc++
mkdir -p squashfs-root/usr/optional/libgcc_s
cp ./.github/workflows/scripts/linux/AppRun "$GITHUB_WORKSPACE"/squashfs-root/AppRun
curl -sSfL "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-$APPARCH" -o "$GITHUB_WORKSPACE"/squashfs-root/AppRun-patched
curl -sSfL "https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/AppRun-patched-$APPARCH" -o "$GITHUB_WORKSPACE"/squashfs-root/AppRun-patched
curl -sSfL "https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/exec-$APPARCH.so" -o "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/exec.so
chmod a+x ./squashfs-root/AppRun
chmod a+x ./squashfs-root/runtime
chmod a+x ./squashfs-root/AppRun-patched
chmod a+x ./squashfs-root/usr/optional/exec.so
echo "$name" > "$GITHUB_WORKSPACE"/squashfs-root/version.txt
mkdir -p "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
cp -r "$GITHUB_WORKSPACE"/bin/Langs "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/
@@ -49,6 +53,8 @@ cp "$GITHUB_WORKSPACE"/bin/docs/{Configuration_Guide.pdf,PCSX2_FAQ.pdf} "$GITHUB
cp "$GITHUB_WORKSPACE"/bin/cheats_ws.zip "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
cp ./bin/GameIndex.yaml "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/GameIndex.yaml
cp /usr/lib/$LIBARCH/libthai.so.0 "$GITHUB_WORKSPACE"/squashfs-root/usr/lib/
cp --dereference /usr/lib/"$LIBARCH"/libstdc++.so.6 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libstdc++/libstdc++.so.6
cp --dereference /lib/"$LIBARCH"/libgcc_s.so.1 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libgcc_s/libgcc_s.so.1
export UPD_INFO="gh-releases-zsync|PCSX2|pcsx2|latest|$name.AppImage.zsync"
export OUTPUT="$name.AppImage"
/tmp/squashfs-root/AppRun --appdir="$GITHUB_WORKSPACE"/squashfs-root/ --plugin gtk -d "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.desktop -i "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.png --output appimage
@@ -3,8 +3,8 @@
set -e
if [ "${COMPILER}" = "gcc" ]; then
export CC=gcc
export CXX=g++
export CC=gcc-10
export CXX=g++-10
else
export CC=clang
export CXX=clang++
@@ -6,100 +6,42 @@ set -e
declare -a BUILD_PACKAGES=(
"ccache"
"cmake"
"g++-8-multilib"
"ninja-build"
)
declare -a GCC_PACKAGES=(
# Nothing Unique Needed
)
declare -a CLANG_PACKAGES=(
"clang-format"
"clang-tidy"
"clang-tools"
"clang"
"clangd-10"
"libc++-dev"
"libc++1"
"libc++abi-dev"
"libc++abi1"
"libclang-dev"
"libclang1"
"liblldb-10-dev"
"libllvm-10-ocaml-dev"
"libomp-dev"
"libomp5"
"lld"
"lldb"
"llvm-dev"
"llvm-runtime"
"llvm"
"python3-clang-10"
)
# Packages - PCSX2
declare -a PCSX2_PACKAGES=(
"curl"
"fuse"
"gettext"
"libaio-dev"
"libasound2-dev"
"libatk1.0-dev"
"libatk-bridge2.0-dev"
"libbz2-dev"
"libcairo2-dev"
"libcggl"
"libdbus-1-dev"
"libegl1-mesa-dev"
"libfontconfig1-dev"
"libgdk-pixbuf2.0-dev"
"libgirepository-1.0-1"
"libgl-dev"
"libgl1-mesa-dev"
"libgl1-mesa-dri"
"libgl1"
"libgles2-mesa-dev"
"libglew-dev"
"libglib2.0-dev"
"libglu1-mesa-dev"
"libglu1-mesa"
"libglvnd-dev"
"libglx-mesa0"
"libglx0"
"libgtk-3-dev"
"libgtk2.0-dev"
"libharfbuzz-dev"
"libibus-1.0-dev"
"libjack-jackd2-dev"
"libjpeg-dev"
"libllvm10"
"liblzma-dev"
"liblzma5"
"libpango1.0-dev"
"libpcap0.8-dev"
"libpng-dev"
"libportaudiocpp0"
"libpulse-dev"
"librsvg2-dev"
"libsdl1.2-dev"
"libsdl2-dev"
"libsamplerate0-dev"
"libsoundtouch-dev"
"libwxgtk3.0-dev"
"libwxgtk3.0-gtk3-0v5"
"libwxgtk3.0-gtk3-dev"
"libx11-xcb-dev"
"libxext-dev"
"libxft-dev"
"libxml2-dev"
"nvidia-cg-toolkit"
"pkg-config"
"portaudio19-dev"
"python"
"zlib1g-dev"
)
if [ "${COMPILER}" = "gcc" ]; then
BUILD_PACKAGES+=("g++-10-multilib")
else
BUILD_PACKAGES+=("clang-9")
PCSX2_PACKAGES+=("libstdc++-10-dev")
fi
# - https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md
ARCH=""
echo "${PLATFORM}"
@@ -111,41 +53,14 @@ fi
sudo apt-get -qq update
# Install packages needed for building
BUILD_PACKAGE_STR=""
for i in "${BUILD_PACKAGES[@]}"; do
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
done
if [ "${COMPILER}" = "gcc" ]; then
for i in "${GCC_PACKAGES[@]}"; do
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
done
else
for i in "${CLANG_PACKAGES[@]}"; do
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
done
fi
echo "Will install the following packages for building - ${BUILD_PACKAGE_STR}"
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
#sudo apt remove gcc-9 g++-9
sudo apt-get -y install ${BUILD_PACKAGE_STR}
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo apt-get -y install "${BUILD_PACKAGES[@]}"
# Install packages needed by pcsx2
PCSX2_PACKAGES_STR=""
for i in "${PCSX2_PACKAGES[@]}"; do
PCSX2_PACKAGES_STR="${PCSX2_PACKAGES_STR} ${i}${ARCH}"
done
if [ "${PLATFORM}" == "x86" ]; then
echo "Installing workaround attempt"
sudo apt-get -y install libgcc-s1:i386
fi
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES_STR}"
sudo apt-get -y install ${PCSX2_PACKAGES_STR}
PCSX2_PACKAGES=("${PCSX2_PACKAGES[@]/%/"${ARCH}"}")
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES[*]}"
sudo apt-get -y install "${PCSX2_PACKAGES[@]}"
cd /tmp
curl -sSfLO https://github.com/NixOS/patchelf/releases/download/0.12/patchelf-0.12.tar.bz2
@@ -11,9 +11,21 @@ for (var i = 0; i < assets.length; i++) {
continue;
}
if (asset.name.includes("windows")) {
windowsAssetLinks += `- [${asset.name}](${asset.browser_download_url})\n`
let friendlyName = asset.name;
try {
friendlyName = asset.name.split("windows-")[1].split(".7z")[0].replace("-", " ");
} catch (e) {
console.log(e);
}
windowsAssetLinks += `- [${friendlyName}](${asset.browser_download_url})\n`
} else if (asset.name.includes("linux")) {
linuxAssetLinks += `- [${asset.name}](${asset.browser_download_url})\n`
let friendlyName = asset.name;
try {
friendlyName = asset.name.split("linux-")[1].split(".AppImage")[0].replace("-", " ");
} catch (e) {
console.log(e);
}
linuxAssetLinks += `- [${friendlyName}](${asset.browser_download_url})\n`
}
}
@@ -24,7 +36,8 @@ const embed = new MessageEmbed()
.addFields(
{ name: 'Version', value: github.context.payload.release.tag_name, inline: true },
{ name: 'Release Link', value: `[Github Release](${github.context.payload.release.html_url})`, inline: true },
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true }
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
{ name: 'Included Changes', value: github.context.payload.release.body, inline: false }
);
if (windowsAssetLinks != "") {
@@ -0,0 +1,29 @@
name: 🏭 Update Controller Database
on:
schedule:
- cron: "0 16 * * 1" # every monday @ 12pm EST - https://crontab.guru/#0_16_*_*_1
jobs:
update-controller-db:
if: github.repository == 'PCSX2/pcsx2'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Get Latest DB and Prepare DB File
run: |
cd .github/workflows/scripts/controller-db/
wget -O game_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
python ./update-db.py
mv ./game_controller_db.txt ${{github.workspace}}/pcsx2/PAD/Linux/res/game_controller_db.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
title: "pad-linux: Update to latest controller database"
commit-message: "pad-linux: Update to latest controller database."
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Weekly automatic update of SDL Controller DB for Linux / Mac OS"
reviewers: lightningterror
+5 -14
View File
@@ -1,19 +1,9 @@
/*
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
*/
/*
@@ -38,6 +28,7 @@
** following #pragma disables the warning.
*/
#pragma warning(disable: 4305)
/*----------------------------------------------------------------------------
+6 -1
View File
@@ -1319,7 +1319,7 @@ public:
wxString(const wxStdWideString& str)
{ assign(str.c_str(), str.length()); }
#endif
#ifndef _WIN32 // PCSX2: We don't want to accidentally interpret utf-8 std::strings as something else!
#if !wxUSE_UNICODE // ANSI build
// FIXME-UTF8: do this in UTF8 build #if wxUSE_UTF8_LOCALE_ONLY, too
wxString(const std::string& str) : m_impl(str) {}
@@ -1327,6 +1327,7 @@ public:
wxString(const std::string& str)
{ assign(str.c_str(), str.length()); }
#endif
#endif
#endif // wxUSE_STD_STRING
// Also always provide explicit conversions to std::[w]string in any case,
@@ -1620,13 +1621,17 @@ public:
// messages for the code which relies on implicit conversion to char* in
// STL build
#if !wxUSE_STD_STRING_CONV_IN_WXSTRING
#ifndef _WIN32 // PCSX2: std::string conversion removal
operator const char*() const { return c_str(); }
#endif
operator const wchar_t*() const { return c_str(); }
#ifndef _WIN32 // PCSX2: std::string conversion removal
// implicit conversion to untyped pointer for compatibility with previous
// wxWidgets versions: this is the same as conversion to const char * so it
// may fail!
operator const void*() const { return c_str(); }
#endif
#endif // !wxUSE_STD_STRING_CONV_IN_WXSTRING
// identical to c_str(), for MFC compatibility
+2
View File
@@ -230,6 +230,7 @@ public:
wxString GetString() const;
#if wxUSE_STD_STRING
#ifndef _WIN32 // PCSX2: std::string conversion removal
wxVariant(const std::string& val, const wxString& name = wxEmptyString);
bool operator==(const std::string& value) const
{ return operator==(wxString(value)); }
@@ -238,6 +239,7 @@ public:
wxVariant& operator=(const std::string& value)
{ return operator=(wxString(value)); }
operator std::string() const { return (operator wxString()).ToStdString(); }
#endif
wxVariant(const wxStdWideString& val, const wxString& name = wxEmptyString);
bool operator==(const wxStdWideString& value) const
+2
View File
@@ -981,11 +981,13 @@ wxVariant::wxVariant(const wxScopedWCharBuffer& val, const wxString& name)
}
#if wxUSE_STD_STRING
#ifndef _WIN32 // PCSX2: std::string conversion removal
wxVariant::wxVariant(const std::string& val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
#endif
wxVariant::wxVariant(const wxStdWideString& val, const wxString& name)
{
+47
View File
@@ -0,0 +1,47 @@
Copyright (c) 2007 MITSUNARI Shigeo
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Neither the name of the copyright owner nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満た
す場合に限り、再頒布および使用が許可されます。
ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項
を含めること。
バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作
権表示、本条件一覧、および下記免責条項を含めること。
書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進
に、著作権者の名前またはコントリビューターの名前を使用してはならない。
本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供さ
れており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性
に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。
著作権者もコントリビューターも、事由のいかんを問わず、 損害発生の原因いかんを
問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為で
あるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、
本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の
喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)直接
損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、
一切責任を負わないものとします。
+985 -548
View File
File diff suppressed because it is too large Load Diff
+999 -645
View File
File diff suppressed because it is too large Load Diff
+506 -199
View File
@@ -1,36 +1,17 @@
/* Copyright (c) 2007 MITSUNARI Shigeo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the copyright owner nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef XBYAK_XBYAK_UTIL_H_
#define XBYAK_XBYAK_UTIL_H_
// We want to keep this file similar to the original xbyak
// clang-format off
#ifdef XBYAK_ONLY_CLASS_CPU
#include <stdint.h>
#include <stdlib.h>
#include <algorithm>
#include <assert.h>
#ifndef XBYAK_THROW
#define XBYAK_THROW(x) ;
#define XBYAK_THROW_RET(x, y) return y;
#endif
#else
#include <string.h>
/**
utility class and functions for Xbyak
@@ -39,7 +20,13 @@
@note this header is UNDER CONSTRUCTION!
*/
#include "xbyak.h"
#endif // XBYAK_ONLY_CLASS_CPU
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
#define XBYAK_INTEL_CPU_SPECIFIC
#endif
#ifdef XBYAK_INTEL_CPU_SPECIFIC
#ifdef _MSC_VER
#if (_MSC_VER < 1400) && defined(XBYAK32)
static inline __declspec(naked) void __cpuid(int[4], int)
@@ -78,35 +65,44 @@
#endif
#endif
#endif
#endif
#ifdef _MSC_VER
extern "C" unsigned __int64 __xgetbv(int);
#ifdef XBYAK_USE_VTUNE
// -I /opt/intel/vtune_amplifier/include/ -L /opt/intel/vtune_amplifier/lib64 -ljitprofiling -ldl
#include <jitprofiling.h>
#ifdef _MSC_VER
#pragma comment(lib, "libittnotify.lib")
#endif
#ifdef __linux__
#include <dlfcn.h>
#endif
#endif
#ifdef __linux__
#define XBYAK_USE_PERF
#endif
namespace Xbyak { namespace util {
/* GCC uses AVX/SSE4 operation to handle the uint64 type.
*
* It is quite annoying because the purpose of the code is to test the support
* of AVX/SSEn
*
* So far, we don't need other ISA on i386 so I hacked the code to limit the
* type to 32 bits. If we want to support AVX512 we might need to shuffle the
* code a bit.
*
* Extra note: it would be waste to use AVX512 on 32 bits, registers are
* limited to 8 instead of 32.
*/
typedef enum {
SmtLevel = 1,
CoreLevel = 2
} IntelCpuTopologyLevel;
/**
CPU detection class
*/
class Cpu {
#ifdef XBYAK64
uint64 type_;
#else
uint32 type_;
#endif
uint64_t type_;
//system topology
bool x2APIC_supported_;
static const size_t maxTopologyLevels = 2;
unsigned int numCores_[maxTopologyLevels];
static const unsigned int maxNumberCacheLevels = 10;
unsigned int dataCacheSize_[maxNumberCacheLevels];
unsigned int coresSharignDataCache_[maxNumberCacheLevels];
unsigned int dataCacheLevels_;
unsigned int get32bitAsBE(const char *x) const
{
return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
@@ -117,7 +113,7 @@ class Cpu {
}
void setFamily()
{
unsigned int data[4];
unsigned int data[4] = {};
getCpuid(1, data);
stepping = data[0] & mask(4);
model = (data[0] >> 4) & mask(4);
@@ -136,6 +132,96 @@ class Cpu {
displayModel = model;
}
}
unsigned int extractBit(unsigned int val, unsigned int base, unsigned int end)
{
return (val >> base) & ((1u << (end - base)) - 1);
}
void setNumCores()
{
if ((type_ & tINTEL) == 0) return;
unsigned int data[4] = {};
/* CAUTION: These numbers are configuration as shipped by Intel. */
getCpuidEx(0x0, 0, data);
if (data[0] >= 0xB) {
/*
if leaf 11 exists(x2APIC is supported),
we use it to get the number of smt cores and cores on socket
leaf 0xB can be zeroed-out by a hypervisor
*/
x2APIC_supported_ = true;
for (unsigned int i = 0; i < maxTopologyLevels; i++) {
getCpuidEx(0xB, i, data);
IntelCpuTopologyLevel level = (IntelCpuTopologyLevel)extractBit(data[2], 8, 15);
if (level == SmtLevel || level == CoreLevel) {
numCores_[level - 1] = extractBit(data[1], 0, 15);
}
}
/*
Fallback values in case a hypervisor has 0xB leaf zeroed-out.
*/
numCores_[SmtLevel - 1] = (std::max)(1u, numCores_[SmtLevel - 1]);
numCores_[CoreLevel - 1] = (std::max)(numCores_[SmtLevel - 1], numCores_[CoreLevel - 1]);
} else {
/*
Failed to deremine num of cores without x2APIC support.
TODO: USE initial APIC ID to determine ncores.
*/
numCores_[SmtLevel - 1] = 0;
numCores_[CoreLevel - 1] = 0;
}
}
void setCacheHierarchy()
{
if ((type_ & tINTEL) == 0) return;
const unsigned int NO_CACHE = 0;
const unsigned int DATA_CACHE = 1;
// const unsigned int INSTRUCTION_CACHE = 2;
const unsigned int UNIFIED_CACHE = 3;
unsigned int smt_width = 0;
unsigned int logical_cores = 0;
unsigned int data[4] = {};
if (x2APIC_supported_) {
smt_width = numCores_[0];
logical_cores = numCores_[1];
}
/*
Assumptions:
the first level of data cache is not shared (which is the
case for every existing architecture) and use this to
determine the SMT width for arch not supporting leaf 11.
when leaf 4 reports a number of core less than numCores_
on socket reported by leaf 11, then it is a correct number
of cores not an upperbound.
*/
for (int i = 0; dataCacheLevels_ < maxNumberCacheLevels; i++) {
getCpuidEx(0x4, i, data);
unsigned int cacheType = extractBit(data[0], 0, 4);
if (cacheType == NO_CACHE) break;
if (cacheType == DATA_CACHE || cacheType == UNIFIED_CACHE) {
unsigned int actual_logical_cores = extractBit(data[0], 14, 25) + 1;
if (logical_cores != 0) { // true only if leaf 0xB is supported and valid
actual_logical_cores = (std::min)(actual_logical_cores, logical_cores);
}
assert(actual_logical_cores != 0);
dataCacheSize_[dataCacheLevels_] =
(extractBit(data[1], 22, 31) + 1)
* (extractBit(data[1], 12, 21) + 1)
* (extractBit(data[1], 0, 11) + 1)
* (data[2] + 1);
if (cacheType == DATA_CACHE && smt_width == 0) smt_width = actual_logical_cores;
assert(smt_width != 0);
coresSharignDataCache_[dataCacheLevels_] = (std::max)(actual_logical_cores / smt_width, 1u);
dataCacheLevels_++;
}
}
}
public:
int model;
int family;
@@ -144,42 +230,76 @@ public:
int extFamily;
int displayFamily; // family + extFamily
int displayModel; // model + extModel
unsigned int getNumCores(IntelCpuTopologyLevel level) const {
if (!x2APIC_supported_) XBYAK_THROW_RET(ERR_X2APIC_IS_NOT_SUPPORTED, 0)
switch (level) {
case SmtLevel: return numCores_[level - 1];
case CoreLevel: return numCores_[level - 1] / numCores_[SmtLevel - 1];
default: XBYAK_THROW_RET(ERR_X2APIC_IS_NOT_SUPPORTED, 0)
}
}
unsigned int getDataCacheLevels() const { return dataCacheLevels_; }
unsigned int getCoresSharingDataCache(unsigned int i) const
{
if (i >= dataCacheLevels_) XBYAK_THROW_RET(ERR_BAD_PARAMETER, 0)
return coresSharignDataCache_[i];
}
unsigned int getDataCacheSize(unsigned int i) const
{
if (i >= dataCacheLevels_) XBYAK_THROW_RET(ERR_BAD_PARAMETER, 0)
return dataCacheSize_[i];
}
/*
data[] = { eax, ebx, ecx, edx }
*/
static inline void getCpuid(unsigned int eaxIn, unsigned int data[4])
{
#ifdef _MSC_VER
#ifdef XBYAK_INTEL_CPU_SPECIFIC
#ifdef _MSC_VER
__cpuid(reinterpret_cast<int*>(data), eaxIn);
#else
#else
__cpuid(eaxIn, data[0], data[1], data[2], data[3]);
#endif
#else
(void)eaxIn;
(void)data;
#endif
}
static inline void getCpuidEx(unsigned int eaxIn, unsigned int ecxIn, unsigned int data[4])
{
#ifdef _MSC_VER
#ifdef XBYAK_INTEL_CPU_SPECIFIC
#ifdef _MSC_VER
__cpuidex(reinterpret_cast<int*>(data), eaxIn, ecxIn);
#else
#else
__cpuid_count(eaxIn, ecxIn, data[0], data[1], data[2], data[3]);
#endif
#else
(void)eaxIn;
(void)ecxIn;
(void)data;
#endif
}
static inline uint64 getXfeature()
static inline uint64_t getXfeature()
{
#ifdef _MSC_VER
return __xgetbv(0);
#else
#ifdef XBYAK_INTEL_CPU_SPECIFIC
#ifdef _MSC_VER
return _xgetbv(0);
#else
unsigned int eax, edx;
// xgetvb is not support on gcc 4.2
// __asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
__asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
return ((uint64)edx << 32) | eax;
return ((uint64_t)edx << 32) | eax;
#endif
#else
return 0;
#endif
}
#ifdef XBYAK64
typedef uint64 Type;
#else
typedef uint32 Type;
#endif
typedef uint64_t Type;
static const Type NONE = 0;
static const Type tMMX = 1 << 0;
static const Type tMMX2 = 1 << 1;
@@ -192,7 +312,6 @@ public:
static const Type tSSE42 = 1 << 8;
static const Type tPOPCNT = 1 << 9;
static const Type tAESNI = 1 << 10;
static const Type tSSE5 = 1 << 11;
static const Type tOSXSAVE = 1 << 12;
static const Type tPCLMULQDQ = 1 << 13;
static const Type tAVX = 1 << 14;
@@ -200,7 +319,6 @@ public:
static const Type t3DN = 1 << 16;
static const Type tE3DN = 1 << 17;
static const Type tSSE4a = 1 << 18;
static const Type tRDTSCP = 1 << 19;
static const Type tAVX2 = 1 << 20;
static const Type tBMI1 = 1 << 21; // andn, bextr, blsi, blsmsk, blsr, tzcnt
@@ -215,111 +333,184 @@ public:
static const Type tADX = 1 << 28; // adcx, adox
static const Type tRDSEED = 1 << 29; // rdseed
static const Type tSMAP = 1 << 30; // stac
#ifdef XBYAK64
static const Type tHLE = uint64(1) << 31; // xacquire, xrelease, xtest
static const Type tRTM = uint64(1) << 32; // xbegin, xend, xabort
static const Type tF16C = uint64(1) << 33; // vcvtph2ps, vcvtps2ph
static const Type tMOVBE = uint64(1) << 34; // mobve
static const Type tAVX512F = uint64(1) << 35;
static const Type tAVX512DQ = uint64(1) << 36;
static const Type tAVX512IFMA = uint64(1) << 37;
static const Type tAVX512PF = uint64(1) << 38;
static const Type tAVX512ER = uint64(1) << 39;
static const Type tAVX512CD = uint64(1) << 40;
static const Type tAVX512BW = uint64(1) << 41;
static const Type tAVX512VL = uint64(1) << 42;
static const Type tAVX512VBMI = uint64(1) << 43;
#endif
static const Type tHLE = uint64_t(1) << 31; // xacquire, xrelease, xtest
static const Type tRTM = uint64_t(1) << 32; // xbegin, xend, xabort
static const Type tF16C = uint64_t(1) << 33; // vcvtph2ps, vcvtps2ph
static const Type tMOVBE = uint64_t(1) << 34; // mobve
static const Type tAVX512F = uint64_t(1) << 35;
static const Type tAVX512DQ = uint64_t(1) << 36;
static const Type tAVX512_IFMA = uint64_t(1) << 37;
static const Type tAVX512IFMA = tAVX512_IFMA;
static const Type tAVX512PF = uint64_t(1) << 38;
static const Type tAVX512ER = uint64_t(1) << 39;
static const Type tAVX512CD = uint64_t(1) << 40;
static const Type tAVX512BW = uint64_t(1) << 41;
static const Type tAVX512VL = uint64_t(1) << 42;
static const Type tAVX512_VBMI = uint64_t(1) << 43;
static const Type tAVX512VBMI = tAVX512_VBMI; // changed by Intel's manual
static const Type tAVX512_4VNNIW = uint64_t(1) << 44;
static const Type tAVX512_4FMAPS = uint64_t(1) << 45;
static const Type tPREFETCHWT1 = uint64_t(1) << 46;
static const Type tPREFETCHW = uint64_t(1) << 47;
static const Type tSHA = uint64_t(1) << 48;
static const Type tMPX = uint64_t(1) << 49;
static const Type tAVX512_VBMI2 = uint64_t(1) << 50;
static const Type tGFNI = uint64_t(1) << 51;
static const Type tVAES = uint64_t(1) << 52;
static const Type tVPCLMULQDQ = uint64_t(1) << 53;
static const Type tAVX512_VNNI = uint64_t(1) << 54;
static const Type tAVX512_BITALG = uint64_t(1) << 55;
static const Type tAVX512_VPOPCNTDQ = uint64_t(1) << 56;
static const Type tAVX512_BF16 = uint64_t(1) << 57;
static const Type tAVX512_VP2INTERSECT = uint64_t(1) << 58;
static const Type tAMX_TILE = uint64_t(1) << 59;
static const Type tAMX_INT8 = uint64_t(1) << 60;
static const Type tAMX_BF16 = uint64_t(1) << 61;
static const Type tAVX_VNNI = uint64_t(1) << 62;
static const Type tAVX512_FP16 = uint64_t(1) << 11;
// 18, 63
Cpu()
: type_(NONE)
, x2APIC_supported_(false)
, numCores_()
, dataCacheSize_()
, coresSharignDataCache_()
, dataCacheLevels_(0)
{
unsigned int data[4];
unsigned int data[4] = {};
const unsigned int& EAX = data[0];
const unsigned int& EBX = data[1];
const unsigned int& ECX = data[2];
const unsigned int& EDX = data[3];
getCpuid(0, data);
const unsigned int maxNum = data[0];
const unsigned int maxNum = EAX;
static const char intel[] = "ntel";
static const char amd[] = "cAMD";
if (data[2] == get32bitAsBE(amd)) {
if (ECX == get32bitAsBE(amd)) {
type_ |= tAMD;
getCpuid(0x80000001, data);
if (data[3] & (1U << 31)) type_ |= t3DN;
if (data[3] & (1U << 15)) type_ |= tCMOV;
if (data[3] & (1U << 30)) type_ |= tE3DN;
if (data[3] & (1U << 22)) type_ |= tMMX2;
if (data[3] & (1U << 27)) type_ |= tRDTSCP;
}
if (data[2] == get32bitAsBE(intel)) {
type_ |= tINTEL;
getCpuid(0x80000001, data);
if (data[3] & (1U << 27)) type_ |= tRDTSCP;
if (data[2] & (1U << 5)) type_ |= tLZCNT;
}
getCpuid(1, data);
if (data[2] & (1U << 0)) type_ |= tSSE3;
if (data[2] & (1U << 9)) type_ |= tSSSE3;
if (data[2] & (1U << 19)) type_ |= tSSE41;
if (data[2] & (1U << 20)) type_ |= tSSE42;
#ifdef XBYAK64
if (data[2] & (1U << 22)) type_ |= tMOVBE;
if (data[2] & (1U << 29)) type_ |= tF16C;
#endif
if (data[2] & (1U << 23)) type_ |= tPOPCNT;
if (data[2] & (1U << 25)) type_ |= tAESNI;
if (data[2] & (1U << 1)) type_ |= tPCLMULQDQ;
if (data[2] & (1U << 27)) type_ |= tOSXSAVE;
if (data[2] & (1U << 30)) type_ |= tRDRAND;
if (EDX & (1U << 31)) {
type_ |= t3DN;
// 3DNow! implies support for PREFETCHW on AMD
type_ |= tPREFETCHW;
}
if (data[3] & (1U << 15)) type_ |= tCMOV;
if (data[3] & (1U << 23)) type_ |= tMMX;
if (data[3] & (1U << 25)) type_ |= tMMX2 | tSSE;
if (data[3] & (1U << 26)) type_ |= tSSE2;
if (EDX & (1U << 29)) {
// Long mode implies support for PREFETCHW on AMD
type_ |= tPREFETCHW;
}
}
if (ECX == get32bitAsBE(intel)) {
type_ |= tINTEL;
}
// Extended flags information
getCpuid(0x80000000, data);
if (EAX >= 0x80000001) {
getCpuid(0x80000001, data);
if (EDX & (1U << 31)) type_ |= t3DN;
if (EDX & (1U << 30)) type_ |= tE3DN;
if (EDX & (1U << 27)) type_ |= tRDTSCP;
if (EDX & (1U << 22)) type_ |= tMMX2;
if (EDX & (1U << 15)) type_ |= tCMOV;
if (ECX & (1U << 5)) type_ |= tLZCNT;
if (ECX & (1U << 8)) type_ |= tPREFETCHW;
}
getCpuid(1, data);
if (ECX & (1U << 0)) type_ |= tSSE3;
if (ECX & (1U << 9)) type_ |= tSSSE3;
if (ECX & (1U << 19)) type_ |= tSSE41;
if (ECX & (1U << 20)) type_ |= tSSE42;
if (ECX & (1U << 22)) type_ |= tMOVBE;
if (ECX & (1U << 23)) type_ |= tPOPCNT;
if (ECX & (1U << 25)) type_ |= tAESNI;
if (ECX & (1U << 1)) type_ |= tPCLMULQDQ;
if (ECX & (1U << 27)) type_ |= tOSXSAVE;
if (ECX & (1U << 30)) type_ |= tRDRAND;
if (ECX & (1U << 29)) type_ |= tF16C;
if (EDX & (1U << 15)) type_ |= tCMOV;
if (EDX & (1U << 23)) type_ |= tMMX;
if (EDX & (1U << 25)) type_ |= tMMX2 | tSSE;
if (EDX & (1U << 26)) type_ |= tSSE2;
if (type_ & tOSXSAVE) {
// check XFEATURE_ENABLED_MASK[2:1] = '11b'
uint64 bv = getXfeature();
uint64_t bv = getXfeature();
if ((bv & 6) == 6) {
if (data[2] & (1U << 28)) type_ |= tAVX;
if (data[2] & (1U << 12)) type_ |= tFMA;
#ifdef XBYAK64
if (((bv >> 5) & 7) == 7) {
getCpuid(7, data);
if (data[1] & (1U << 16)) type_ |= tAVX512F;
if (ECX & (1U << 28)) type_ |= tAVX;
if (ECX & (1U << 12)) type_ |= tFMA;
// do *not* check AVX-512 state on macOS because it has on-demand AVX-512 support
#if !defined(__APPLE__)
if (((bv >> 5) & 7) == 7)
#endif
{
getCpuidEx(7, 0, data);
if (EBX & (1U << 16)) type_ |= tAVX512F;
if (type_ & tAVX512F) {
getCpuidEx(7, 0, data);
if (data[1] & (1U << 17)) type_ |= tAVX512DQ;
if (data[1] & (1U << 21)) type_ |= tAVX512IFMA;
if (data[1] & (1U << 26)) type_ |= tAVX512PF;
if (data[1] & (1U << 27)) type_ |= tAVX512ER;
if (data[1] & (1U << 28)) type_ |= tAVX512CD;
if (data[1] & (1U << 30)) type_ |= tAVX512BW;
if (data[1] & (1U << 31)) type_ |= tAVX512VL;
if (data[2] & (1U << 1)) type_ |= tAVX512VBMI;
if (EBX & (1U << 17)) type_ |= tAVX512DQ;
if (EBX & (1U << 21)) type_ |= tAVX512_IFMA;
if (EBX & (1U << 26)) type_ |= tAVX512PF;
if (EBX & (1U << 27)) type_ |= tAVX512ER;
if (EBX & (1U << 28)) type_ |= tAVX512CD;
if (EBX & (1U << 30)) type_ |= tAVX512BW;
if (EBX & (1U << 31)) type_ |= tAVX512VL;
if (ECX & (1U << 1)) type_ |= tAVX512_VBMI;
if (ECX & (1U << 6)) type_ |= tAVX512_VBMI2;
if (ECX & (1U << 8)) type_ |= tGFNI;
if (ECX & (1U << 9)) type_ |= tVAES;
if (ECX & (1U << 10)) type_ |= tVPCLMULQDQ;
if (ECX & (1U << 11)) type_ |= tAVX512_VNNI;
if (ECX & (1U << 12)) type_ |= tAVX512_BITALG;
if (ECX & (1U << 14)) type_ |= tAVX512_VPOPCNTDQ;
if (EDX & (1U << 2)) type_ |= tAVX512_4VNNIW;
if (EDX & (1U << 3)) type_ |= tAVX512_4FMAPS;
if (EDX & (1U << 8)) type_ |= tAVX512_VP2INTERSECT;
if ((type_ & tAVX512BW) && (EDX & (1U << 23))) type_ |= tAVX512_FP16;
}
}
#endif
}
}
if (maxNum >= 7) {
getCpuidEx(7, 0, data);
if (type_ & tAVX && data[1] & 0x20) type_ |= tAVX2;
if (data[1] & (1U << 3)) type_ |= tBMI1;
if (data[1] & (1U << 8)) type_ |= tBMI2;
if (data[1] & (1U << 9)) type_ |= tENHANCED_REP;
if (data[1] & (1U << 18)) type_ |= tRDSEED;
if (data[1] & (1U << 19)) type_ |= tADX;
if (data[1] & (1U << 20)) type_ |= tSMAP;
#ifdef XBYAK64
if (data[1] & (1U << 4)) type_ |= tHLE;
if (data[1] & (1U << 11)) type_ |= tRTM;
#endif
const uint32_t maxNumSubLeaves = EAX;
if (type_ & tAVX && (EBX & (1U << 5))) type_ |= tAVX2;
if (EBX & (1U << 3)) type_ |= tBMI1;
if (EBX & (1U << 8)) type_ |= tBMI2;
if (EBX & (1U << 9)) type_ |= tENHANCED_REP;
if (EBX & (1U << 18)) type_ |= tRDSEED;
if (EBX & (1U << 19)) type_ |= tADX;
if (EBX & (1U << 20)) type_ |= tSMAP;
if (EBX & (1U << 4)) type_ |= tHLE;
if (EBX & (1U << 11)) type_ |= tRTM;
if (EBX & (1U << 14)) type_ |= tMPX;
if (EBX & (1U << 29)) type_ |= tSHA;
if (ECX & (1U << 0)) type_ |= tPREFETCHWT1;
if (EDX & (1U << 24)) type_ |= tAMX_TILE;
if (EDX & (1U << 25)) type_ |= tAMX_INT8;
if (EDX & (1U << 22)) type_ |= tAMX_BF16;
if (maxNumSubLeaves >= 1) {
getCpuidEx(7, 1, data);
if (EAX & (1U << 4)) type_ |= tAVX_VNNI;
if (type_ & tAVX512F) {
if (EAX & (1U << 5)) type_ |= tAVX512_BF16;
}
}
}
setFamily();
setNumCores();
setCacheHierarchy();
}
void putFamily()
void putFamily() const
{
#ifndef XBYAK_ONLY_CLASS_CPU
printf("family=%d, model=%X, stepping=%d, extFamily=%d, extModel=%X\n",
family, model, stepping, extFamily, extModel);
printf("display:family=%X, model=%X\n", displayFamily, displayModel);
#endif
}
bool has(Type type) const
{
@@ -327,16 +518,22 @@ public:
}
};
#ifndef XBYAK_ONLY_CLASS_CPU
class Clock {
public:
static inline uint64 getRdtsc()
static inline uint64_t getRdtsc()
{
#ifdef _MSC_VER
#ifdef XBYAK_INTEL_CPU_SPECIFIC
#ifdef _MSC_VER
return __rdtsc();
#else
#else
unsigned int eax, edx;
__asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx));
return ((uint64)edx << 32) | eax;
return ((uint64_t)edx << 32) | eax;
#endif
#else
// TODO: Need another impl of Clock or rdtsc-equivalent for non-x86 cpu
return 0;
#endif
}
Clock()
@@ -354,10 +551,10 @@ public:
count_++;
}
int getCount() const { return count_; }
uint64 getClock() const { return clock_; }
uint64_t getClock() const { return clock_; }
void clear() { count_ = 0; clock_ = 0; }
private:
uint64 clock_;
uint64_t clock_;
int count_;
};
@@ -366,7 +563,7 @@ const int UseRCX = 1 << 6;
const int UseRDX = 1 << 7;
class Pack {
static const size_t maxTblNum = 10;
static const size_t maxTblNum = 15;
const Xbyak::Reg64 *tbl_[maxTblNum];
size_t n_;
public:
@@ -375,9 +572,14 @@ public:
Pack(const Pack& rhs)
: n_(rhs.n_)
{
if (n_ > maxTblNum) throw Error(ERR_INTERNAL);
for (size_t i = 0; i < n_; i++) tbl_[i] = rhs.tbl_[i];
}
Pack& operator=(const Pack& rhs)
{
n_ = rhs.n_;
for (size_t i = 0; i < n_; i++) tbl_[i] = rhs.tbl_[i];
return *this;
}
Pack(const Xbyak::Reg64& t0)
{ n_ = 1; tbl_[0] = &t0; }
Pack(const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
@@ -400,9 +602,9 @@ public:
{ n_ = 10; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; tbl_[8] = &t8; tbl_[9] = &t9; }
Pack& append(const Xbyak::Reg64& t)
{
if (n_ == 10) {
if (n_ == maxTblNum) {
fprintf(stderr, "ERR Pack::can't append\n");
throw Error(ERR_BAD_PARAMETER);
XBYAK_THROW_RET(ERR_BAD_PARAMETER, *this)
}
tbl_[n_++] = &t;
return *this;
@@ -411,7 +613,7 @@ public:
{
if (n > maxTblNum) {
fprintf(stderr, "ERR Pack::init bad n=%d\n", (int)n);
throw Error(ERR_BAD_PARAMETER);
XBYAK_THROW(ERR_BAD_PARAMETER)
}
n_ = n;
for (size_t i = 0; i < n; i++) {
@@ -421,8 +623,8 @@ public:
const Xbyak::Reg64& operator[](size_t n) const
{
if (n >= n_) {
fprintf(stderr, "ERR Pack bad n=%d\n", (int)n);
throw Error(ERR_BAD_PARAMETER);
fprintf(stderr, "ERR Pack bad n=%d(%d)\n", (int)n, (int)n_);
XBYAK_THROW_RET(ERR_BAD_PARAMETER, rax)
}
return *tbl_[n];
}
@@ -435,7 +637,7 @@ public:
if (num == size_t(-1)) num = n_ - pos;
if (pos + num > n_) {
fprintf(stderr, "ERR Pack::sub bad pos=%d, num=%d\n", (int)pos, (int)num);
throw Error(ERR_BAD_PARAMETER);
XBYAK_THROW_RET(ERR_BAD_PARAMETER, Pack())
}
Pack pack;
pack.n_ = num;
@@ -463,6 +665,7 @@ class StackFrame {
static const int rcxPos = 3;
static const int rdxPos = 2;
#endif
static const int maxRegNum = 14; // maxRegNum = 16 - rsp - rax
Xbyak::CodeGenerator *code_;
int pNum_;
int tNum_;
@@ -472,7 +675,7 @@ class StackFrame {
int P_;
bool makeEpilog_;
Xbyak::Reg64 pTbl_[4];
Xbyak::Reg64 tTbl_[10];
Xbyak::Reg64 tTbl_[maxRegNum];
Pack p_;
Pack t_;
StackFrame(const StackFrame&);
@@ -484,7 +687,7 @@ public:
make stack frame
@param sf [in] this
@param pNum [in] num of function parameter(0 <= pNum <= 4)
@param tNum [in] num of temporary register(0 <= tNum <= 10, with UseRCX, UseRDX)
@param tNum [in] num of temporary register(0 <= tNum, with UseRCX, UseRDX) #{pNum + tNum [+rcx] + [rdx]} <= 14
@param stackSizeByte [in] local stack size
@param makeEpilog [in] automatically call close() if true
@@ -509,29 +712,19 @@ public:
, t(t_)
{
using namespace Xbyak;
if (pNum < 0 || pNum > 4) throw Error(ERR_BAD_PNUM);
if (pNum < 0 || pNum > 4) XBYAK_THROW(ERR_BAD_PNUM)
const int allRegNum = pNum + tNum_ + (useRcx_ ? 1 : 0) + (useRdx_ ? 1 : 0);
if (allRegNum < pNum || allRegNum > 14) throw Error(ERR_BAD_TNUM);
if (tNum_ < 0 || allRegNum > maxRegNum) XBYAK_THROW(ERR_BAD_TNUM)
const Reg64& _rsp = code->rsp;
const AddressFrame& _ptr = code->ptr;
saveNum_ = (std::max)(0, allRegNum - noSaveNum);
const int *tbl = getOrderTbl() + noSaveNum;
P_ = saveNum_ + (stackSizeByte + 7) / 8;
if (P_ > 0 && (P_ & 1) == 0) P_++; // here (rsp % 16) == 8, then increment P_ for 16 byte alignment
for (int i = 0; i < saveNum_; i++) {
code->push(Reg64(tbl[i]));
}
P_ = (stackSizeByte + 7) / 8;
if (P_ > 0 && (P_ & 1) == (saveNum_ & 1)) P_++; // (rsp % 16) == 8, then increment P_ for 16 byte alignment
P_ *= 8;
if (P_ > 0) code->sub(_rsp, P_);
#ifdef XBYAK64_WIN
for (int i = 0; i < (std::min)(saveNum_, 4); i++) {
code->mov(_ptr [_rsp + P_ + (i + 1) * 8], Reg64(tbl[i]));
}
for (int i = 4; i < saveNum_; i++) {
code->mov(_ptr [_rsp + P_ - 8 * (saveNum_ - i)], Reg64(tbl[i]));
}
#else
for (int i = 0; i < saveNum_; i++) {
code->mov(_ptr [_rsp + P_ - 8 * (saveNum_ - i)], Reg64(tbl[i]));
}
#endif
int pos = 0;
for (int i = 0; i < pNum; i++) {
pTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
@@ -552,36 +745,18 @@ public:
{
using namespace Xbyak;
const Reg64& _rsp = code_->rsp;
const AddressFrame& _ptr = code_->ptr;
const int *tbl = getOrderTbl() + noSaveNum;
#ifdef XBYAK64_WIN
for (int i = 0; i < (std::min)(saveNum_, 4); i++) {
code_->mov(Reg64(tbl[i]), _ptr [_rsp + P_ + (i + 1) * 8]);
}
for (int i = 4; i < saveNum_; i++) {
code_->mov(Reg64(tbl[i]), _ptr [_rsp + P_ - 8 * (saveNum_ - i)]);
}
#else
for (int i = 0; i < saveNum_; i++) {
code_->mov(Reg64(tbl[i]), _ptr [_rsp + P_ - 8 * (saveNum_ - i)]);
}
#endif
if (P_ > 0) code_->add(_rsp, P_);
for (int i = 0; i < saveNum_; i++) {
code_->pop(Reg64(tbl[saveNum_ - 1 - i]));
}
if (callRet) code_->ret();
}
~StackFrame()
{
if (!makeEpilog_) return;
try {
close();
} catch (std::exception& e) {
printf("ERR:StackFrame %s\n", e.what());
exit(1);
} catch (...) {
printf("ERR:StackFrame otherwise\n");
exit(1);
}
close();
}
private:
const int *getOrderTbl() const
@@ -599,7 +774,7 @@ private:
}
int getRegIdx(int& pos) const
{
assert(pos < 14);
assert(pos < maxRegNum);
using namespace Xbyak;
const int *tbl = getOrderTbl();
int r = tbl[pos++];
@@ -616,5 +791,137 @@ private:
};
#endif
class Profiler {
int mode_;
const char *suffix_;
const void *startAddr_;
#ifdef XBYAK_USE_PERF
FILE *fp_;
#endif
public:
enum {
None = 0,
Perf = 1,
VTune = 2
};
Profiler()
: mode_(None)
, suffix_("")
, startAddr_(0)
#ifdef XBYAK_USE_PERF
, fp_(0)
#endif
{
}
// append suffix to funcName
void setNameSuffix(const char *suffix)
{
suffix_ = suffix;
}
void setStartAddr(const void *startAddr)
{
startAddr_ = startAddr;
}
void init(int mode)
{
mode_ = None;
switch (mode) {
default:
case None:
return;
case Perf:
#ifdef XBYAK_USE_PERF
close();
{
const int pid = getpid();
char name[128];
snprintf(name, sizeof(name), "/tmp/perf-%d.map", pid);
fp_ = fopen(name, "a+");
if (fp_ == 0) {
fprintf(stderr, "can't open %s\n", name);
return;
}
}
mode_ = Perf;
#endif
return;
case VTune:
#ifdef XBYAK_USE_VTUNE
dlopen("dummy", RTLD_LAZY); // force to load dlopen to enable jit profiling
if (iJIT_IsProfilingActive() != iJIT_SAMPLING_ON) {
fprintf(stderr, "VTune profiling is not active\n");
return;
}
mode_ = VTune;
#endif
return;
}
}
~Profiler()
{
close();
}
void close()
{
#ifdef XBYAK_USE_PERF
if (fp_ == 0) return;
fclose(fp_);
fp_ = 0;
#endif
}
void set(const char *funcName, const void *startAddr, size_t funcSize) const
{
if (mode_ == None) return;
#if !defined(XBYAK_USE_PERF) && !defined(XBYAK_USE_VTUNE)
(void)funcName;
(void)startAddr;
(void)funcSize;
#endif
#ifdef XBYAK_USE_PERF
if (mode_ == Perf) {
if (fp_ == 0) return;
fprintf(fp_, "%llx %zx %s%s", (long long)startAddr, funcSize, funcName, suffix_);
/*
perf does not recognize the function name which is less than 3,
so append '_' at the end of the name if necessary
*/
size_t n = strlen(funcName) + strlen(suffix_);
for (size_t i = n; i < 3; i++) {
fprintf(fp_, "_");
}
fprintf(fp_, "\n");
fflush(fp_);
}
#endif
#ifdef XBYAK_USE_VTUNE
if (mode_ != VTune) return;
char className[] = "";
char fileName[] = "";
iJIT_Method_Load jmethod = {};
jmethod.method_id = iJIT_GetNewMethodID();
jmethod.class_file_name = className;
jmethod.source_file_name = fileName;
jmethod.method_load_address = const_cast<void*>(startAddr);
jmethod.method_size = funcSize;
jmethod.line_number_size = 0;
char buf[128];
snprintf(buf, sizeof(buf), "%s%s", funcName, suffix_);
jmethod.method_name = buf;
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
#endif
}
/*
for continuous set
funcSize = endAddr - <previous set endAddr>
*/
void set(const char *funcName, const void *endAddr)
{
set(funcName, startAddr_, (size_t)endAddr - (size_t)startAddr_);
startAddr_ = endAddr;
}
};
#endif // XBYAK_ONLY_CLASS_CPU
} } // end of util
#endif
+493 -137
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -220,7 +220,9 @@ 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(NOT MSVC)
if(MSVC)
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
else()
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse -fno-operator-names)
endif()
@@ -328,9 +330,9 @@ endif()
# MacOS-specific things
#-------------------------------------------------------------------------------
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
if (APPLE AND ${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.14 AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 10)
if (APPLE AND ${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.14 AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 9)
# Older versions of the macOS stdlib don't have operator new(size_t, align_val_t)
# Disable use of them with this flag
# Not great, but also no worse that what we were getting before we turned on C++17
+3 -1
View File
@@ -163,7 +163,9 @@ else()
find_package(X11 REQUIRED)
make_imported_target_if_missing(X11::X11 X11)
endif()
if(UNIX)
if(APPLE)
check_lib(GIO gio-2.0 gio/gio.h)
elseif(UNIX)
# Most plugins (if not all) and PCSX2 core need gtk2, so set the required flags
if (GTK2_API)
find_package(GTK2 REQUIRED gtk)
+2 -2
View File
@@ -155,8 +155,8 @@ extern pxDoAssertFnType* pxDoAssert;
#define pxAssertMsg(cond, msg) (likely(cond))
#define pxAssertDev(cond, msg) (likely(cond))
#define pxAssumeMsg(cond, msg) (__assume(cond))
#define pxAssumeDev(cond, msg) (__assume(cond))
#define pxAssumeMsg(cond, msg) __assume(cond)
#define pxAssumeDev(cond, msg) __assume(cond)
#define pxFail(msg) \
do \
+29
View File
@@ -0,0 +1,29 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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
// An implementation of bit_cast until we get c++20
template<class T2, class T1>
T2 bit_cast(const T1& src)
{
static_assert(sizeof(T2) == sizeof(T1), "bit_cast: types must be equal size");
static_assert(std::is_pod<T1>::value, "bit_cast: source must be POD");
static_assert(std::is_pod<T2>::value, "bit_cast: destination must be POD");
T2 dst;
memcpy(&dst, &src, sizeof(T2));
return dst;
}
+22
View File
@@ -470,6 +470,28 @@ bool IConsoleWriter::Warning(const wxString fmt, ...) const
return false;
}
bool IConsoleWriter::WriteLn(ConsoleColors color, const std::string& str) const
{
ConsoleColorScope cs(color);
return WriteLn(str);
}
bool IConsoleWriter::WriteLn(const std::string& str) const
{
DoWriteLn(_addIndentation(fromUTF8(str), conlog_Indent));
return false;
}
bool IConsoleWriter::Error(const std::string& str) const
{
return WriteLn(Color_StrongRed, str);
}
bool IConsoleWriter::Warning(const std::string& str) const
{
return WriteLn(Color_StrongOrange, str);
}
// --------------------------------------------------------------------------------------
// ConsoleColorScope / ConsoleIndentScope
+5
View File
@@ -125,6 +125,11 @@ struct IConsoleWriter
bool WriteLn(const wxString fmt, ...) const;
bool Error(const wxString fmt, ...) const;
bool Warning(const wxString fmt, ...) const;
bool WriteLn(ConsoleColors color, const std::string& str) const;
bool WriteLn(const std::string& str) const;
bool Error(const std::string& str) const;
bool Warning(const std::string& str) const;
};
// --------------------------------------------------------------------------------------
+3 -7
View File
@@ -82,11 +82,7 @@ static u64 getthreadtime(thread_port_t thread)
(u64)info.system_time.microseconds;
}
// Returns the current timestamp (not relative to a real world clock) in
// units of 100 nanoseconds. The weird units are to mirror the Windows
// counterpart in WinThreads.cpp, which uses the GetThreadTimes() API. On
// OSX/Darwin, this is only accurate up until 1ms (and possibly less), so
// not very good.
// Returns the current timestamp (not relative to a real world clock) in microseconds
u64 Threading::GetThreadCpuTime()
{
// we could also use mach_thread_self() and mach_port_deallocate(), but
@@ -95,7 +91,7 @@ u64 Threading::GetThreadCpuTime()
// to be user-space instead. In contract,
// pthread_mach_thread_np(pthread_self()) is entirely in user-space.
u64 us = getthreadtime(pthread_mach_thread_np(pthread_self()));
return us * 10ULL;
return us;
}
u64 Threading::pxThread::GetCpuTime() const
@@ -109,7 +105,7 @@ u64 Threading::pxThread::GetCpuTime() const
return 0;
}
return getthreadtime((thread_port_t)m_native_id) * 10ULL;
return getthreadtime((thread_port_t)m_native_id);
}
void Threading::pxThread::_platform_specific_OnStartInThread()
+1
View File
@@ -270,6 +270,7 @@ extern const wxChar* __fastcall pxExpandMsg(const wxChar* message);
extern const wxChar* __fastcall pxGetTranslation(const wxChar* message);
extern bool pxIsEnglish(int id);
extern wxString fromUTF8(const std::string& str);
extern wxString fromUTF8(const char* src);
extern wxString fromAscii(const char* src);
+2 -2
View File
@@ -274,7 +274,7 @@ void IniLoader::Entry(const wxString& var, std::string& value, const std::string
if (m_Config)
{
wxString temp;
m_Config->Read(var, &temp, wxString(default_value));
m_Config->Read(var, &temp, fromUTF8(default_value));
value = temp.ToStdString();
}
else if (&value != &default_value)
@@ -443,5 +443,5 @@ void IniSaver::Entry(const wxString& var, std::string& value, const std::string&
{
if (!m_Config)
return;
m_Config->Write(var, wxString(value));
m_Config->Write(var, fromUTF8(value));
}
+1 -1
View File
@@ -28,7 +28,7 @@ __noinline void memset_sse_a(void* dest, const size_t size)
if (data != 0)
{
static __aligned16 const u8 loadval[8] = {data, data, data, data, data, data, data, data};
alignas(16) static const u8 loadval[8] = {data, data, data, data, data, data, data, data};
srcreg = _mm_loadh_pi(_mm_load_ps((float*)loadval), (__m64*)loadval);
}
else
+93 -92
View File
@@ -15,28 +15,27 @@
#pragma once
// clang-format off
#ifdef __CYGWIN__
#define __linux__
#define __linux__
#endif
// make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
#if !defined(__POSIX__)
#define __POSIX__ 1
#endif
#ifndef __POSIX__
#define __POSIX__ 1
#endif
#endif
#include "Pcsx2Types.h"
#include "common/emitter/x86_intrin.h"
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with
// that as well. >_<
#ifndef ArraySize
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#endif
// The C++ standard doesn't allow `offsetof` to be used on non-constant values (e.g. `offsetof(class, field[i])`)
// Use this in those situations
#define OFFSETOF(a, b) (reinterpret_cast<size_t>(&(static_cast<a*>(0)->b)))
// --------------------------------------------------------------------------------------
// Dev / Debug conditionals - Consts for using if() statements instead of uglier #ifdef.
@@ -47,53 +46,37 @@
// some tight loops it will likely make debug builds unusably slow.
//
#ifdef PCSX2_DEVBUILD
static const bool IsDevBuild = true;
static const bool IsDevBuild = true;
#else
static const bool IsDevBuild = false;
static const bool IsDevBuild = false;
#endif
#ifdef PCSX2_DEBUG
static const bool IsDebugBuild = true;
static const bool IsDebugBuild = true;
#else
static const bool IsDebugBuild = false;
static const bool IsDebugBuild = false;
#endif
#ifdef PCSX2_DEBUG
#define pxDebugCode(code) code
#define pxDebugCode(code) code
#else
#define pxDebugCode(code)
#define pxDebugCode(code)
#endif
#ifdef PCSX2_DEVBUILD
#define pxDevelCode(code) code
#define pxDevelCode(code) code
#else
#define pxDevelCode(code)
#define pxDevelCode(code)
#endif
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
#define pxReleaseCode(code)
#define pxNonReleaseCode(code) code
#define pxReleaseCode(code)
#define pxNonReleaseCode(code) code
#else
#define pxReleaseCode(code) code
#define pxNonReleaseCode(code)
#define pxReleaseCode(code) code
#define pxNonReleaseCode(code)
#endif
// --------------------------------------------------------------------------------------
// __aligned / __aligned16 / __pagealigned
// --------------------------------------------------------------------------------------
// GCC Warning! The GCC linker (LD) typically fails to assure alignment of class members.
// If you want alignment to be assured, the variable must either be a member of a struct
// or a static global.
//
// __pagealigned is equivalent to __aligned(0x1000), and is used to align a dynarec code
// buffer to a page boundary (allows the use of execution-enabled mprotect).
//
// General Performance Warning: Any function that specifies alignment on a local (stack)
// variable will have to align the stack frame on enter, and restore it on exit (adds
// overhead). Furthermore, compilers cannot inline functions that have aligned local
// vars. So use local var alignment with much caution.
//
// Defines the memory page size for the target platform at compilation. All supported platforms
// (which means Intel only right now) have a 4k granularity.
#define PCSX2_PAGESIZE 0x1000
@@ -104,27 +87,14 @@ static const int __pagesize = PCSX2_PAGESIZE;
// --------------------------------------------------------------------------------------
#ifdef _MSC_VER
// Using these breaks compat with VC2005; so we're not using it yet.
//# define __pack_begin __pragma(pack(1))
//# define __pack_end __pragma(pack())
#define __noinline __declspec(noinline)
#define __noreturn __declspec(noreturn)
// This is the 2005/earlier compatible packing define, which must be used in conjunction
// with #ifdef _MSC_VER/#pragma pack() directives (ugly).
#define __packed
// Don't know if there are Visual C++ equivalents of these.
#define likely(x) (!!(x))
#define unlikely(x) (!!(x))
#define __aligned(alig) __declspec(align(alig))
#define __aligned16 __declspec(align(16))
#define __aligned32 __declspec(align(32))
#define __pagealigned __declspec(align(PCSX2_PAGESIZE))
#define __noinline __declspec(noinline)
#define __noreturn __declspec(noreturn)
// Don't know if there are Visual C++ equivalents of these.
#define likely(x) (!!(x))
#define unlikely(x) (!!(x))
#define CALLBACK __stdcall
#define CALLBACK __stdcall
#else
@@ -132,41 +102,35 @@ static const int __pagesize = PCSX2_PAGESIZE;
// GCC / Intel Compilers Section
// --------------------------------------------------------------------------------------
#ifndef __packed
#define __packed __attribute__((packed))
#endif
#ifndef __aligned
#define __aligned(alig) __attribute__((aligned(alig)))
#endif
#define __aligned16 __attribute__((aligned(16)))
#define __aligned32 __attribute__((aligned(32)))
#define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE)))
#define __assume(cond) do { if (!(cond)) __builtin_unreachable(); } while(0)
#define CALLBACK __attribute__((stdcall))
#define __assume(cond) ((void)0) // GCC has no equivalent for __assume
#define CALLBACK __attribute__((stdcall))
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
// warnings when a static inlined function isn't used in the scope of a single file (which
// happens *by design* like all the friggen time >_<)
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
// warnings when a static inlined function isn't used in the scope of a single file (which
// happens *by design* like all the friggen time >_<)
#ifndef __fastcall
#define __fastcall __attribute__((fastcall))
#endif
#define __vectorcall __fastcall
#define _inline __inline__ __attribute__((unused))
#ifdef NDEBUG
#define __forceinline __attribute__((always_inline, unused))
#else
#define __forceinline __attribute__((unused))
#endif
#ifndef __noinline
#define __noinline __attribute__((noinline))
#endif
#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#ifndef __fastcall
#ifndef _M_X86_32
#define __fastcall // Attribute not available, and x86_32 is pretty much the only cc that passes literally everything in registers
#else
#define __fastcall __attribute__((fastcall))
#endif
#endif
#define __vectorcall __fastcall
#define _inline __inline__ __attribute__((unused))
#ifdef NDEBUG
#define __forceinline __attribute__((always_inline, unused))
#else
#define __forceinline __attribute__((unused))
#endif
#ifndef __noinline
#define __noinline __attribute__((noinline))
#endif
#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// --------------------------------------------------------------------------------------
@@ -181,11 +145,48 @@ static const int __pagesize = PCSX2_PAGESIZE;
// environment.
//
#ifdef PCSX2_DEVBUILD
#define __releaseinline
#define __releaseinline
#else
#define __releaseinline __forceinline
#define __releaseinline __forceinline
#endif
#define __ri __releaseinline
#define __fi __forceinline
#define __fc __fastcall
// Makes sure that if anyone includes xbyak, it doesn't do anything bad
#define XBYAK_ENABLE_OMITTED_OPERAND
#ifdef __x86_64__
#define _M_AMD64
#endif
#ifndef RESTRICT
#ifdef __INTEL_COMPILER
#define RESTRICT restrict
#elif defined(_MSC_VER)
#define RESTRICT __restrict
#elif defined(__GNUC__)
#define RESTRICT __restrict__
#else
#define RESTRICT
#endif
#endif
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#ifdef __cpp_constinit
#define CONSTINIT constinit
#elif __has_attribute(require_constant_initialization)
#define CONSTINIT __attribute__((require_constant_initialization))
#else
#define CONSTINIT
#endif
#define ASSERT assert
+5
View File
@@ -31,6 +31,11 @@ __fi wxString fromUTF8(const char* src)
return wxString(src, wxMBConvUTF8());
}
__fi wxString fromUTF8(const std::string& str)
{
return wxString(str.data(), wxMBConvUTF8(), str.size());
}
__fi wxString fromAscii(const char* src)
{
return wxString::FromAscii(src);
+1 -1
View File
@@ -23,7 +23,7 @@
#pragma comment(lib, "User32.lib")
static __aligned16 LARGE_INTEGER lfreq;
alignas(16) static LARGE_INTEGER lfreq;
void InitCPUTicks()
{
+1
View File
@@ -100,6 +100,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="Align.h" />
<ClInclude Include="BitCast.h" />
<ClInclude Include="EmbeddedImage.h" />
<ClInclude Include="boost_spsc_queue.hpp" />
<ClInclude Include="FastJmp.h" />
+3
View File
@@ -291,6 +291,9 @@
<ClInclude Include="WindowInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BitCast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GL\Context.h">
<Filter>Header Files\GL</Filter>
</ClInclude>
+2 -2
View File
@@ -44,7 +44,7 @@ static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const
using namespace x86Emitter;
__aligned16 x86capabilities x86caps;
alignas(16) x86capabilities x86caps;
x86capabilities::x86capabilities()
: isIdentified(false)
@@ -87,7 +87,7 @@ void x86capabilities::SIMD_EstablishMXCSRmask()
MXCSR_Mask.bitmask = 0xFFFF; // SSE2 features added
}
__aligned16 u8 targetFXSAVE[512];
alignas(16) u8 targetFXSAVE[512];
// Work for recent enough GCC/CLANG/MSVC 2012
_fxsave(&targetFXSAVE);
+1 -1
View File
@@ -209,4 +209,4 @@ union SSE_MXCSR
extern SSE_MXCSR MXCSR_Mask;
extern __aligned16 x86capabilities x86caps;
alignas(16) extern x86capabilities x86caps;
+1 -1
View File
@@ -1186,7 +1186,7 @@ const xRegister32
xWrite8(0xC8 | to->Id);
}
static __aligned16 u64 xmm_data[iREGCNT_XMM * 2];
alignas(16) static u64 xmm_data[iREGCNT_XMM * 2];
__emitinline void xStoreReg(const xRegisterSSE& src)
{
+1
View File
@@ -10,6 +10,7 @@
<PreprocessorDefinitions>PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemDefinitionGroup>
</Project>
+1
View File
@@ -14,6 +14,7 @@
<PreprocessorDefinitions>PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemDefinitionGroup>
</Project>
+1
View File
@@ -19,6 +19,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OptimizeReferences>true</OptimizeReferences>
-1
View File
@@ -8,7 +8,6 @@
<WholeProgramOptimization>false</WholeProgramOptimization>
<StringPooling>true</StringPooling>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
+73 -9
View File
@@ -29,6 +29,10 @@
#include "Elfheader.h"
#include "ps2/BiosTools.h"
#ifndef DISABLE_RECORDING
#include "Recording/InputRecording.h"
#endif
// This typically reflects the Sony-assigned serial code for the Disc, if one exists.
// (examples: SLUS-2113, etc).
// If the disc is homebrew then it probably won't have a valid serial; in which case
@@ -377,10 +381,10 @@ s32 cdvdWriteConfig(const u8* config)
static MutexRecursive Mutex_NewDiskCB;
// Sets ElfCRC to the CRC of the game bound to the CDVD source.
static __fi ElfObject* loadElf(const wxString filename)
static __fi ElfObject* loadElf(const wxString filename, bool isPSXElf)
{
if (filename.StartsWith(L"host"))
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')));
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')), isPSXElf);
// Mimic PS2 behavior!
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
@@ -404,7 +408,7 @@ static __fi ElfObject* loadElf(const wxString filename)
IsoFSCDVD isofs;
IsoFile file(isofs, fixedname);
return new ElfObject(fixedname, file);
return new ElfObject(fixedname, file, isPSXElf);
}
static __fi void _reloadElfInfo(wxString elfpath)
@@ -423,8 +427,8 @@ static __fi void _reloadElfInfo(wxString elfpath)
fname = elfpath.AfterLast(':');
if (fname.Matches(L"????_???.??*"))
DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2);
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath, false));
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath));
elfptr->loadHeaders();
ElfCRC = elfptr->getCRC();
@@ -439,6 +443,36 @@ static __fi void _reloadElfInfo(wxString elfpath)
// binary).
}
static __fi void _reloadPSXElfInfo(wxString elfpath)
{
// Now's a good time to reload the ELF info...
ScopedLock locker(Mutex_NewDiskCB);
if (elfpath == LastELF)
return;
LastELF = elfpath;
wxString fname = elfpath.AfterLast('\\');
if (!fname)
fname = elfpath.AfterLast('/');
if (!fname)
fname = elfpath.AfterLast(':');
if (fname.Matches(L"????_???.??*"))
DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2);
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath, true));
ElfCRC = elfptr->getCRC();
ElfTextRange = elfptr->getTextRange();
Console.WriteLn(Color_StrongBlue, L"PSX ELF (%s) Game CRC = 0x%08X", WX_STR(elfpath), ElfCRC);
// Note: Do not load game database info here. This code is generic and called from
// BIOS key encryption as well as eeloadReplaceOSDSYS. The first is actually still executing
// BIOS code, and patches and cheats should not be applied yet. (they are applied when
// eeGameStarting is invoked, which is when the VM starts executing the actual game ELF
// binary).
}
void cdvdReloadElfInfo(wxString elfoverride)
{
// called from context of executing VM code (recompilers), so we need to trap exceptions
@@ -461,10 +495,11 @@ void cdvdReloadElfInfo(wxString elfoverride)
// PCSX2 currently only recognizes *.elf executables in proper PS2 format.
// To support different PSX titles in the console title and for savestates, this code bypasses all the detection,
// simply using the exe name, stripped of problematic characters.
wxString fname = elfpath.AfterLast('\\').AfterLast(':'); // Also catch elf paths which lack a backslash, and only have a colon.
wxString fname2 = fname.BeforeFirst(';');
DiscSerial = fname2;
Console.SetTitle(DiscSerial);
wxString fname = elfpath.AfterLast('\\').BeforeFirst('_');
wxString fname2 = elfpath.AfterLast('_').BeforeFirst('.');
wxString fname3 = elfpath.AfterLast('.').BeforeFirst(';');
DiscSerial = fname + "-" + fname2 + fname3;
_reloadPSXElfInfo(elfpath);
return;
}
@@ -780,6 +815,34 @@ void cdvdReset()
cdvd.Action = cdvdAction_None;
cdvd.ReadTime = cdvdBlockReadTime(MODE_DVDROM);
// If we are recording, always use the same RTC setting
// for games that use the RTC to seed their RNG -- this is very important to be the same everytime!
#ifndef DISABLE_RECORDING
if (g_InputRecording.IsActive())
{
Console.WriteLn("Input Recording Active - Using Constant RTC of 04-03-2020 (DD-MM-YYYY)");
// Why not just 0 everything? Some games apparently require the date to be valid in terms of when
// the PS2 / Game actually came out. (MGS3). So set it to a value well beyond any PS2 game's release date.
cdvd.RTC.second = 0;
cdvd.RTC.minute = 0;
cdvd.RTC.hour = 0;
cdvd.RTC.day = 4;
cdvd.RTC.month = 3;
cdvd.RTC.year = 20;
}
else
{
// CDVD internally uses GMT+9. If you think the time's wrong, you're wrong.
// Set up your time zone and winter/summer in the BIOS. No PS2 BIOS I know of features automatic DST.
wxDateTime curtime(wxDateTime::GetTimeNow());
cdvd.RTC.second = (u8)curtime.GetSecond();
cdvd.RTC.minute = (u8)curtime.GetMinute();
cdvd.RTC.hour = (u8)curtime.GetHour(wxDateTime::GMT9);
cdvd.RTC.day = (u8)curtime.GetDay(wxDateTime::GMT9);
cdvd.RTC.month = (u8)curtime.GetMonth(wxDateTime::GMT9) + 1; // WX returns Jan as "0"
cdvd.RTC.year = (u8)(curtime.GetYear(wxDateTime::GMT9) - 2000);
}
#else
// CDVD internally uses GMT+9. If you think the time's wrong, you're wrong.
// Set up your time zone and winter/summer in the BIOS. No PS2 BIOS I know of features automatic DST.
wxDateTime curtime(wxDateTime::GetTimeNow());
@@ -789,6 +852,7 @@ void cdvdReset()
cdvd.RTC.day = (u8)curtime.GetDay(wxDateTime::GMT9);
cdvd.RTC.month = (u8)curtime.GetMonth(wxDateTime::GMT9) + 1; // WX returns Jan as "0"
cdvd.RTC.year = (u8)(curtime.GetYear(wxDateTime::GMT9) - 2000);
#endif
g_GameStarted = false;
g_GameLoading = false;
@@ -879,7 +943,7 @@ int cdvdReadSector()
CDVD_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16);
bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) * 4;
if (bcr < cdvd.BlockSize)
if (bcr < cdvd.BlockSize || !(HW_DMA3_CHCR & 0x01000000))
{
CDVD_LOG("READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize);
if (HW_DMA3_CHCR & 0x01000000)
+1 -1
View File
@@ -376,7 +376,7 @@ bool DoCDVDopen()
return true;
}
wxString somepick(Path::GetFilenameWithoutExt(m_SourceFilename[CurrentSourceType]));
wxString somepick(Path::GetFilenameWithoutExt(fromUTF8(m_SourceFilename[CurrentSourceType])));
//FWIW Disc serial availability doesn't seem reliable enough, sometimes it's there and sometime it's just null
//Shouldn't the serial be available all time? Potentially need to look into Elfreloadinfo() reliability
//TODO: Add extra fallback case for CRC.
+1 -1
View File
@@ -48,7 +48,7 @@ bool ChdFileReader::Open2(const wxString& fileName)
// TODO: Unicode correctness on Windows
while (CHDERR_REQUIRES_PARENT == (error = chd_open(chds[chd_depth].c_str(), CHD_OPEN_READ, NULL, &child)))
{
if (chd_depth >= static_cast<int>(ArraySize(chds) - 1))
if (chd_depth >= static_cast<int>(std::size(chds) - 1))
{
Console.Error(L"CDVD: chd_open hit recursion limit searching for parents");
return false;
+1 -1
View File
@@ -185,7 +185,7 @@ static wxString iso2indexname(const wxString& isoname)
wxDirName appRoot = // TODO: have only one of this in PCSX2. Right now have few...
(wxDirName)(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath());
//TestTemplate(appRoot, isoname, false);
return ApplyTemplate(L"gzip index", appRoot, EmuConfig.GzipIsoIndexTemplate, isoname, false);
return ApplyTemplate(L"gzip index", appRoot, fromUTF8(EmuConfig.GzipIsoIndexTemplate), isoname, false);
}
GzippedFileReader::GzippedFileReader(void)
+5 -5
View File
@@ -134,13 +134,13 @@ void ThreadedFileReader::Loop()
ThreadedFileReader::Buffer* ThreadedFileReader::GetBlockPtr(const Chunk& block)
{
for (int i = 0; i < static_cast<int>(ArraySize(m_buffer)); i++)
for (int i = 0; i < static_cast<int>(std::size(m_buffer)); i++)
{
u32 size = m_buffer[i].size.load(std::memory_order_relaxed);
u64 offset = m_buffer[i].offset;
if (size && offset <= block.offset && offset + size >= block.offset + block.length)
{
m_nextBuffer = (i + 1) % ArraySize(m_buffer);
m_nextBuffer = (i + 1) % std::size(m_buffer);
return m_buffer + i;
}
}
@@ -166,7 +166,7 @@ ThreadedFileReader::Buffer* ThreadedFileReader::GetBlockPtr(const Chunk& block)
{
buf.offset = block.offset;
buf.size.store(size, std::memory_order_release);
m_nextBuffer = (m_nextBuffer + 1) % ArraySize(m_buffer);
m_nextBuffer = (m_nextBuffer + 1) % std::size(m_buffer);
return &buf;
}
return nullptr;
@@ -214,9 +214,9 @@ bool ThreadedFileReader::TryCachedRead(void*& buffer, u64& offset, u32& size, co
m_amtRead = 0;
u64 end = 0;
bool allDone = false;
for (int i = 0; i < static_cast<int>(ArraySize(m_buffer) * 2); i++)
for (int i = 0; i < static_cast<int>(std::size(m_buffer) * 2); i++)
{
Buffer& buf = m_buffer[i % ArraySize(m_buffer)];
Buffer& buf = m_buffer[i % std::size(m_buffer)];
u32 bufsize = buf.size.load(std::memory_order_acquire);
if (!bufsize)
continue;
+26 -22
View File
@@ -182,7 +182,6 @@ set(pcsx2Sources
set(pcsx2Headers
AsyncFileReader.h
Cache.h
cheatscpp.h
Common.h
Config.h
COP0.h
@@ -214,6 +213,7 @@ set(pcsx2Headers
MemoryTypes.h
Patch.h
PathDefs.h
PCSX2Base.h
PrecompiledHeader.h
R3000A.h
R5900Exceptions.h
@@ -301,7 +301,6 @@ set(pcsx2SPU2Sources
SPU2/spu2sys.cpp
SPU2/Timestretcher.cpp
SPU2/Wavedump_wav.cpp
SPU2/WavFile.cpp
)
if(TARGET PkgConfig::PORTAUDIO)
@@ -493,7 +492,7 @@ if(WIN32)
)
set(pcsx2PADHeaders
PAD/Windows/PAD.h
PAD/Gamepad.h
PAD/Windows/PADConfig.h
PAD/Windows/DeviceEnumerator.h
PAD/Windows/Diagnostics.h
@@ -558,12 +557,12 @@ else(WIN32)
PAD/Linux/wx_dialog/GamepadConfiguration.cpp
PAD/Linux/wx_dialog/JoystickConfiguration.cpp
PAD/Linux/Config.cpp
PAD/Linux/linux.cpp
${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
)
# PAD/Linux headers
set(pcsx2PADHeaders
PAD/Gamepad.h
PAD/Linux/bitwise.h
PAD/Linux/Config.h
PAD/Linux/Device.h
@@ -572,7 +571,6 @@ else(WIN32)
PAD/Linux/SDL/joystick.h
PAD/Linux/keyboard.h
PAD/Linux/KeyStatus.h
PAD/Linux/PAD.h
PAD/Linux/state_management.h
PAD/Linux/wx_dialog/opPanel.h
PAD/Linux/wx_dialog/GamepadConfiguration.h
@@ -639,21 +637,12 @@ set(pcsx2GSSources
GS/Renderers/HW/GSTextureCache.cpp
GS/Renderers/SW/GSDrawScanline.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x64.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x64.avx.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x64.avx2.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x86.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x86.avx.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.x86.avx2.cpp
GS/Renderers/SW/GSDrawScanlineCodeGenerator.all.cpp
GS/Renderers/SW/GSNewCodeGenerator.cpp
GS/Renderers/SW/GSRasterizer.cpp
GS/Renderers/SW/GSRendererSW.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x64.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x64.avx.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x64.avx2.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x86.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x86.avx.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.x86.avx2.cpp
GS/Renderers/SW/GSSetupPrimCodeGenerator.all.cpp
GS/Renderers/SW/GSTextureCacheSW.cpp
GS/Renderers/SW/GSTextureSW.cpp
GS/Renderers/OpenGL/GLLoader.cpp
@@ -664,6 +653,7 @@ set(pcsx2GSSources
GS/Renderers/OpenGL/GSTextureCacheOGL.cpp
GS/Renderers/OpenGL/GSTextureOGL.cpp
GS/Window/GSSetting.cpp
GS/Window/GSwxDialog.cpp
)
# GS headers
@@ -678,8 +668,10 @@ set(pcsx2GSHeaders
GS/GSDrawingContext.h
GS/GSDrawingEnvironment.h
GS/GSDump.h
GS/GS_types.h
GS/GS_codegen.h
GS/GSExtra.h
GS/GSGL.h
GS/GSIntrin.h
GS/GSRegs.h
GS/GS.h
GS/GSLocalMemory.h
GS/GSLzma.h
@@ -712,11 +704,14 @@ set(pcsx2GSHeaders
GS/Renderers/HW/GSTextureCache.h
GS/Renderers/HW/GSVertexHW.h
GS/Renderers/SW/GSDrawScanlineCodeGenerator.h
GS/Renderers/SW/GSDrawScanlineCodeGenerator.all.h
GS/Renderers/SW/GSDrawScanline.h
GS/Renderers/SW/GSNewCodeGenerator.h
GS/Renderers/SW/GSRasterizer.h
GS/Renderers/SW/GSRendererSW.h
GS/Renderers/SW/GSScanlineEnvironment.h
GS/Renderers/SW/GSSetupPrimCodeGenerator.h
GS/Renderers/SW/GSSetupPrimCodeGenerator.all.h
GS/Renderers/SW/GSTextureCacheSW.h
GS/Renderers/SW/GSTextureSW.h
GS/Renderers/SW/GSVertexSW.h
@@ -731,7 +726,7 @@ set(pcsx2GSHeaders
GS/Window/GSCaptureDlg.h
GS/Window/GSDialog.h
GS/Window/GSSetting.h
GS/Window/GSSettingsDlg.h
GS/Window/GSwxDialog.h
)
if(WIN32)
@@ -796,6 +791,7 @@ if(WIN32)
)
list(APPEND pcsx2GSSources
GS/Renderers/DX11/D3D.cpp
GS/Renderers/DX11/GSDevice11.cpp
GS/Renderers/DX11/GSRendererDX11.cpp
GS/Renderers/DX11/GSTexture11.cpp
@@ -803,9 +799,9 @@ if(WIN32)
GS/Renderers/DX11/GSTextureFX11.cpp
GS/Window/GSCaptureDlg.cpp
GS/Window/GSDialog.cpp
GS/Window/GSSettingsDlg.cpp
)
list(APPEND pcsx2GSHeaders
GS/Renderers/DX11/D3D.h
GS/Renderers/DX11/GSDevice11.h
GS/Renderers/DX11/GSRendererDX11.h
GS/Renderers/DX11/GSTexture11.h
@@ -818,6 +814,7 @@ else(WIN32)
SPU2/Linux/ConfigDebug.cpp
SPU2/Linux/ConfigSoundTouch.cpp
SPU2/Linux/Dialogs.cpp
SPU2/WavFile.cpp
SPU2/wx/wxConfig.cpp
)
list(APPEND pcsx2SPU2Headers
@@ -894,7 +891,6 @@ else(WIN32)
list(APPEND pcsx2GSSources
GS/GS_res.cpp
GS/Window/GSLinuxDialog.cpp
)
list(APPEND pcsx2GSHeaders
@@ -969,6 +965,7 @@ set(pcsx2GuiSources
gui/Debugger/CtrlDisassemblyView.cpp
gui/Debugger/CtrlRegisterList.cpp
gui/Debugger/CtrlMemView.cpp
gui/Debugger/CtrlMemSearch.cpp
gui/Debugger/DebuggerLists.cpp
gui/Debugger/DisassemblyDialog.cpp
gui/Debugger/DebugEvents.cpp
@@ -1028,6 +1025,7 @@ set(pcsx2GuiHeaders
gui/Debugger/BreakpointWindow.h
gui/Debugger/CtrlDisassemblyView.h
gui/Debugger/CtrlMemView.h
gui/Debugger/CtrlMemSearch.h
gui/Debugger/CtrlRegisterList.h
gui/Debugger/DebugEvents.h
gui/Debugger/DebuggerLists.h
@@ -1468,6 +1466,12 @@ if(WIN32)
opengl32.lib
comsuppw.lib
)
elseif(APPLE)
target_link_libraries(PCSX2_FLAGS INTERFACE
PkgConfig::GIO
PCAP::PCAP
LibXml2::LibXml2
)
else()
target_link_libraries(PCSX2_FLAGS INTERFACE
GTK::gtk
+27 -19
View File
@@ -120,14 +120,17 @@ public:
auto* padding = new wxBoxSizer(wxVERTICAL);
auto* top_box = new wxBoxSizer(wxVERTICAL);
int space = wxSizerFlags().Border().GetBorderInPixels();
int two_space = wxSizerFlags().DoubleBorder().GetBorderInPixels();
// Ethernet section
auto* eth_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Ethernet"));
m_eth_enable = new wxCheckBox(this, wxID_ANY, _("Enabled"));
eth_sizer->Add(m_eth_enable);
eth_sizer->AddSpacer(5);
eth_sizer->AddSpacer(space);
auto* eth_adapter_box = new wxGridBagSizer(5, 5);
auto* eth_adapter_box = new wxGridBagSizer(space, space);
for (const AdapterEntry& adapter : PCAPAdapter::GetAdapters())
addAdapter(adapter);
#ifdef _WIN32
@@ -166,42 +169,44 @@ public:
m_dns1_address .create(6, this, eth_adapter_box, _("DNS1 Address:"));
m_dns2_address .create(7, this, eth_adapter_box, _("DNS2 Address:"));
eth_adapter_box->AddGrowableCol(1);
eth_adapter_box->AddGrowableCol(2);
eth_sizer->Add(eth_adapter_box, wxSizerFlags().Expand());
// HDD section
auto* hdd_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Hard Disk Drive"));
m_hdd_enable = new wxCheckBox(this, wxID_ANY, _("Enabled"));
hdd_sizer->Add(m_hdd_enable);
hdd_sizer->AddSpacer(5);
auto* hdd_grid = new wxFlexGridSizer(2, 0, 5);
hdd_grid->AddGrowableCol(1);
auto* hdd_file_label = new wxStaticText(this, wxID_ANY, _("HDD File:"));
auto* hdd_file_label = new wxStaticText(this, wxID_ANY, _("HDD File"));
m_hdd_file = new wxFilePickerCtrl(this, wxID_ANY, wxEmptyString, _("HDD image file"), "HDD|*.raw", wxDefaultPosition, wxDefaultSize, wxFLP_SAVE | wxFLP_USE_TEXTCTRL);
hdd_grid->Add(hdd_file_label, wxSizerFlags().Centre().Right());
hdd_grid->Add(m_hdd_file, wxSizerFlags().Expand());
auto* hdd_size_label = new wxStaticText(this, wxID_ANY, _("HDD Size (GiB):"));
auto* hdd_size_label = new wxStaticText(this, wxID_ANY, _("HDD Size (GiB)"));
auto* hdd_size_box = new wxBoxSizer(wxHORIZONTAL);
m_hdd_size_slider = new wxSlider(this, wxID_ANY, HDD_MIN_GB, HDD_MIN_GB, HDD_MAX_GB, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_MIN_MAX_LABELS | wxSL_AUTOTICKS);
m_hdd_size_slider = new wxSlider(this, wxID_ANY, HDD_MIN_GB, HDD_MIN_GB, HDD_MAX_GB, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_AUTOTICKS);
m_hdd_size_slider->SetPageSize(10);
for (int i = 15; i < HDD_MAX_GB; i += 5)
m_hdd_size_slider->SetTick(i);
m_hdd_size_slider->SetTickFreq(10);
m_hdd_size_spin = new wxSpinCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, HDD_MIN_GB, HDD_MAX_GB, HDD_MIN_GB);
m_hdd_size_spin->SetSizeHints(m_hdd_size_spin->GetSizeFromTextSize(30));
hdd_size_box->Add(m_hdd_size_slider, wxSizerFlags(1).Centre());
hdd_size_box->AddSpacer(space);
hdd_size_box->Add(m_hdd_size_spin, wxSizerFlags(0).Centre());
hdd_grid->Add(hdd_size_label, wxSizerFlags().Centre().Right());
hdd_grid->Add(hdd_size_box, wxSizerFlags().Expand());
hdd_sizer->Add(hdd_grid, wxSizerFlags().Expand());
hdd_sizer->Add(m_hdd_enable);
hdd_sizer->AddSpacer(two_space);
hdd_sizer->Add(hdd_file_label, wxSizerFlags().Left());
hdd_sizer->AddSpacer(space);
hdd_sizer->Add(m_hdd_file, wxSizerFlags().Expand());
hdd_sizer->AddSpacer(two_space);
hdd_sizer->Add(hdd_size_label, wxSizerFlags().Left());
hdd_sizer->AddSpacer(space);
hdd_sizer->Add(hdd_size_box, wxSizerFlags().Expand());
top_box->Add(eth_sizer, wxSizerFlags().Expand());
top_box->AddSpacer(space);
top_box->Add(hdd_sizer, wxSizerFlags().Expand());
top_box->AddSpacer(space);
top_box->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Right());
padding->Add(top_box, wxSizerFlags().Expand().Border(wxALL, 5));
padding->Add(top_box, wxSizerFlags().Expand().Border());
SetSizerAndFit(padding);
SetMaxSize(wxSize(wxDefaultCoord, GetMinSize().y));
@@ -275,7 +280,7 @@ public:
m_dns2_address .save(config.DNS2, config.AutoDNS2);
config.hddEnable = m_hdd_enable->GetValue();
wxStrncpy(config.Hdd, m_hdd_file->GetPath(), ArraySize(config.Hdd) - 1);
wxStrncpy(config.Hdd, m_hdd_file->GetPath(), std::size(config.Hdd) - 1);
config.HddSize = m_hdd_size_spin->GetValue() * 1024;
}
@@ -321,6 +326,9 @@ public:
}
m_eth_adapter->Set(options);
m_eth_adapter->SetSelection(selection);
// Update minimum sizes for the possibly increased dropdown size
// Nothing else seems to update the minimum size of the window
SetSizerAndFit(GetSizer(), false);
}
void OnCheck(wxCommandEvent&)
+2 -2
View File
@@ -43,10 +43,10 @@ void SaveDnsHosts()
ScopedIniGroup iniEntry(ini, groupName);
ConfigHost entry = config.EthHosts[i];
wxString url(entry.Url);
wxString url(fromUTF8(entry.Url));
ini.Entry(L"Url", url);
//TODO UTF8(?)
wxString desc(entry.Desc);
wxString desc(fromUTF8(entry.Desc));
ini.Entry(L"Desc", desc);
char addrBuff[INET_ADDRSTRLEN];
+5
View File
@@ -242,6 +242,11 @@ public:
return false;
}
bool Write(const std::string& msg) const
{
return Write(fromUTF8(msg));
}
};
// --------------------------------------------------------------------------------------
+2 -5
View File
@@ -283,7 +283,7 @@ u64 R5900DebugInterface::read64(u32 address)
u128 R5900DebugInterface::read128(u32 address)
{
__aligned16 u128 result;
alignas(16) u128 result;
if (!isValidAddress(address) || address % 16)
{
result.hi = result.lo = -1;
@@ -635,10 +635,7 @@ bool R5900DebugInterface::isValidAddress(u32 addr)
case 0xA:
case 0xB:
// [ 8000_0000 - BFFF_FFFF ] kernel
// We only need to access the EE kernel (which is 1 MB large)
if (lopart < 0x100000)
return true;
break;
return true;
case 0xF:
// [ 8000_0000 - BFFF_FFFF ] IOP or kernel stack
if (lopart >= 0xfff8000)
+54 -52
View File
@@ -9,30 +9,32 @@ urlcolor: "cyan"
## About the PCSX2 Project
### Question 1: What is the purpose of the PCSX2 project
PCSX2 intends to emulate the PlayStation 2 console, allowing PS2 games to be played on a PC. This requires having an original PlayStation 2 console to supply a BIOS dump, and of course the original games to either be played directly off the disc, or be dumped and played as ISO images.
### Question 1: What is the purpose of the PCSX2 project?
PCSX2 intends to emulate the PlayStation 2 console, allowing PS2 games to be played on a computer. This requires having an original PlayStation 2 console to supply a BIOS dump and the original games, either to be played directly off the disc or to be dumped and played as ISO/CSO images.
### Question 2: Is PCSX2 open source
PCSX2 is open source, licensed under the GNU General Public License, v3. [Source code is kept on GitHub](https://github.com/pcsx2/pcsx2).
### Question 2: Is PCSX2 open source?
PCSX2 is open source, licensed under the GNU Lesser General Public License v3.0. [Source code is kept on GitHub](https://github.com/pcsx2/pcsx2).
### Question 3: How can I help the project
### Question 3: How can I help the project?
There are a number of ways to help the project, whether it be bug reporting, game patching, or even writing code for the emulator itself. Some examples:
* Want to make changes to emulator code? [Check out the issue tracker](https://github.com/PCSX2/pcsx2/issues), or [fork the PCSX2 repository and work on your own ideas](https://github.com/PCSX2/pcsx2).
* Want to patch games? [Check out the cheats and patches forum thread for inspiration](https://forums.pcsx2.net/Thread-Post-your-PCSX2-cheats-patches-here). There are other threads to find as well, [such as those dedicated to 60 FPS patches](https://forums.pcsx2.net/Thread-60-fps-codes) or [widescreen patches](https://forums.pcsx2.net/Thread-PCSX2-Widescreen-Game-Patches).
* Want to report bugs you have discovered in your games? [Head over to the Bug Reporting section of the PCSX2 forums](https://forums.pcsx2.net/Forum-Bug-reporting). Also check out our [GitHub issue guidelines](https://github.com/PCSX2/pcsx2/wiki/How-to-create-useful-and-valid-issues) for info on how we handle GitHub issues.
* Want to update us on the compatibility of your games? [Take a look at the Public Compatibility List on the PCSX2 forums](https://forums.pcsx2.net/Forum-Public-compatibility-list)
* Want to improve the PCSX2 wiki? [Here is how to contribute](https://wiki.pcsx2.net/Help!_How_to_contribute_guide)
### Question 4: Is PCSX2 ready to run out-of-the-box
No, PCSX2 is not ready to run immediately. First, you must dump your PlayStation 2 console's BIOS using the BIOS dumper. The BIOS dumper is [available on the PCSX2 website](https://pcsx2.net/download/releases/tools.html).
### Question 4: Is PCSX2 ready to run out-of-the-box?
No, first, you must dump your PlayStation 2 console's BIOS using the BIOS dumper. The BIOS dumper is [available on the PCSX2 website](https://pcsx2.net/download/releases/tools.html).
After dumping your PlayStation 2 console's BIOS, you may launch PCSX2, step through the first time setup wizard, and then begin playing.
After dumping your PlayStation 2 console's BIOS and copying it to your computer, launch PCSX2, step through the first time setup wizard, and then you may begin playing.
<div class="page"/> <!-- Because PDFs are terrible -->
---
## Technical Details of PCSX2
### Question 5: What are the PC requirements to use PCSX2
### Question 5: What are the PC requirements to use PCSX2?
#### Minimum
@@ -50,50 +52,50 @@ After dumping your PlayStation 2 console's BIOS, you may launch PCSX2, step thro
*Note: Recommended GPU is based on 3x Internal, ~1080p resolution requirements. Higher resolutions will require stronger cards; 6x Internal, ~4K resolution will require a [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 12000 (GeForce GTX 1070 Ti). Just like CPU requirements, this is also highly game dependent. A quick reference for GPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:GPU_intensive_games)*
### Question 6: How many CPU cores can PCSX2 use
### Question 6: How many CPU cores can PCSX2 use?
By default, PCSX2 uses two cores for emulation. Enabling the MTVU speedhack allows the PS2's VU1 coprocessor to run on a third core, which is safe for most games.
Software rendering in GSdx can be set to use as many or as few rendering threads as desired. We recommend using no more than 8, or the number of cores (including hyperthreads) that your CPU has, whichever is the lower number.
Software rendering can be set to use as many or as few rendering threads as desired. We recommend using no more than 8, or the number of cores (including hyperthreads) that your CPU has, whichever is the lower number.
<div class="page"/> <!-- Because PDFs are terrible -->
### Question 7: Why isn't my CPU not using 100% of it's power
### Question 7: Why isn't my CPU not using 100% of its power?
The CPU load as reported in software such as Windows' Task Manager is usually a *summation* of CPU usage, across *all* cores. Software can only use the resources of the individual CPU cores it is actually running on, and cannot "borrow" CPU time from other cores.
### Question 8: Will SLI or Crossfire help with performance
### Question 8: Will SLI or Crossfire help with performance?
No. PCSX2 does not use or require SLI or Crossfire.
### Question 9: How do I check if a game is playable
### Question 9: How do I check if a game is playable?
The PCSX2 website has a [compatibility list](https://pcsx2.net/compatibility-list.html) with every game that has been tested.
### Question 10: Do PS1 (PSX) games work on PCSX2
### Question 10: Do PS1 (PSX) games work on PCSX2?
#### If you want to enjoy your PS1 games without issues
No, they will not work. Please use a proper PS1 emulator, such as Mednafen.
#### If you want to enjoy your PS1 games without issues:
No, they will not work without issues. Please use a proper PS1 emulator, such as Duckstation or Mednafen.
#### If you are a tinkerer and like to break things
PS1 games may work on PCSX2, but compatibility is very limited. Specific settings are often required to get a game to boot, and there are other universal problems including missing and pitch shifted audio, and severe FMV corruption. A [forum thread for PS1 compatibility](https://forums.pcsx2.net/Thread-PSX-Mode-Unofficial-Compatibility-List) is tracking some fixes and compatibility reports.
#### If you are a tinkerer and like to break things:
PS1 games may work on PCSX2, but compatibility is very limited. Specific settings are often required to get a game to boot, and there are other universal problems including missing/pitch-shifted audio and severe FMV corruption. A [forum thread for PS1 compatibility](https://forums.pcsx2.net/Thread-PSX-Mode-Unofficial-Compatibility-List) is tracking some fixes and compatibility reports.
*While we encourage discussion about PS1 games and improving compatibility, bug reports are NOT being accepted for PS1 games. Any reports for PS1 games will be closed immediately as invalid.*
### Question 11: Why does my game not work like it did in an earlier PCSX2 version
One change to the emulator may fix one game, but cause problems for another. If the issue is severe and not fixable with different settings, you can always revert back to the last known PCSX2 version to work, and report the build number that broke the game. [Development builds](https://pcsx2.net/download/development.html) are very helpful for finding the exact change that caused a regression.
### Question 11: Why does my game not work like it did in an earlier PCSX2 version?
Any change to the emulator may fix one game, but cause problems for another. If the issue is severe and not fixable with different settings, you can always revert back to the last known PCSX2 version to work, and report the build number that broke the game. [Development builds](https://pcsx2.net/download/development.html) are very helpful for finding the exact change that caused a regression.
### Question 12: Why is PCSX2 slow
The PlayStation 2 is a complex console, and this complexity substantially raises the PC requirements to emulate it at full speed, accurately. [This forum thread](https://forums.pcsx2.net/Thread-Why-is-PCSX2-slow) helps explain some of the technical reasons behind it, and our current guidelines for PC requirements are listed above.
### Question 12: Why is PCSX2 slow?
The PlayStation 2 is a complex console, and this substantially raises the PC requirements to emulate it at full speed accurately. [This forum thread](https://forums.pcsx2.net/Thread-Why-is-PCSX2-slow) helps explain some of the technical reasons behind it, and our current guidelines for PC requirements are listed above.
### Question 13: Where do I get a PS2 BIOS
### Question 13: Where do I get a PS2 BIOS?
You have to dump the BIOS files from your PlayStation 2 console. There is a BIOS dumper tool [available on the PCSX2 website](https://pcsx2.net/download/releases/tools.html) to do this. If you need a guide, check the bottom of this FAQ for links to BIOS guides.
<div class="page"/> <!-- Because PDFs are terrible -->
### Question 14: Where do I get PS2 games
### Question 14: Where do I get PS2 games?
You can use games from your personal collection of discs, purchase them from local stores that resell old games, or look online at sites like eBay or Amazon.
### Question 15: Can I use PS2 discs directly with PCSX2
### Question 15: Can I use PS2 discs directly with PCSX2?
Yes. However, some games have speed problems, because unlike the PS2 which would constantly keep the disc spinning, PCSX2 will not do the same to your PC's disc drive. It is recommended to instead dump your games to ISO images. ImgBurn is a popular software to do this with, and we recommend [installing ImgBurn by using Ninite](https://ninite.com) to avoid any issues with the ImgBurn installer.
### Question 16: How do I play a game
### Question 16: How do I play a game?
If you are using an ISO image:
1) Click the CDVD menu
@@ -104,21 +106,21 @@ If you are using an ISO image:
If you are using a disc:
1) Click the CDVD menu
2) Check that "Plugin" mode is selected.
3) Click "Plugin Menu", then "Plugin Settings". Verify your disc drive shows up in the menu.
4) Click the System menu, then Boot CDVD.
1) Click the CDVD menu
2) Check that "Disc" mode is selected.
3) Go to "Drive Selector", then select your drive.
4) Click the System menu, then Boot CDVD.
### Question 17: What is the difference between Full and Fast boot
Full boot will launch the PS2 BIOS, which will then launch the game. Some games need this for multi-language settings or times to work.
### Question 17: What is Fast Boot?
Normally, PCSX2 will launch the PS2 BIOS, which will then launch the game. Some games need this for multi-language settings or times to work.
Fast boot will directly mount and launch the game without first launching the PS2 BIOS. Though slightly faster, this may cause some multi-language games to boot into the wrong language, or games that use the clock to give inaccurate times.
Fast Boot will directly mount and launch the game without first launching the PS2 BIOS. On versions 1.6 and below, this may cause some multi-language games to boot into the wrong language.
### Question 18: How do I compile the PCSX2 source code
### Question 18: How do I compile the PCSX2 source code?
* [Windows compile guide](https://wiki.pcsx2.net/PCSX2_Documentation/Compiling_on_Windows)
* [Linux compile guide](https://wiki.pcsx2.net/PCSX2_Documentation/Compiling_on_Linux)
### Question 19: When will the next version be released
### Question 19: When will the next version be released?
It will be released when it is ready. Please don't waste your time and ours asking when.
<div class="page"/> <!-- Because PDFs are terrible -->
@@ -126,25 +128,25 @@ It will be released when it is ready. Please don't waste your time and ours aski
---
## PCSX2 Configuration
### Question 20: How do I configure the emulator
Refer to the Configuration_Guide.pdf (located in the same folder as this FAQ) for an initial setup guide and solution manual to some common known issues.
### Question 20: How do I configure PCSX2?
Refer to the Configuration_Guide.pdf (located in the same folder as this FAQ) for an initial setup guide and resolutions or workarounds to some common known issues.
### Question 21: Will framelimiter options increase my FPS
The framelimiter has a few options that allow you to alter the pacing of your games. This will directly affect the game's speed itself, NOT your framerate. Useful for speeding through sections of games, or slowing down for precision.
### Question 21: Will framelimiter options increase my FPS?
The framelimiter has a few options that allow you to alter the pacing of your games. This will directly affect the game's speed itself, NOT your framerate, and can be useful for speeding through sections of games, or slowing down for precision.
* Turbo (Tab): Bumps the framelimiter to 200%, allowing a game to run up to 2x faster than normal.
* Slowmo (Shift + Tab): Drops the framelimiter to 50%, restricting a game to 0.5x its normal speed.
* Framelimiter Disabled (F4): Completely disables the framelimiter. The game will run as fast as your PC can push it.
Some settings are greyed out; these are advanced counters that should only be modified by those who understand the effects they have on a game's playback speed and frame pacing.
Some settings are greyed out. These are advanced counters that should only be modified by those who understand the effects they have on a game's playback speed and frame pacing.
### Question 22: What is the normal speed for a PlayStation 2 game
### Question 22: What is the normal speed for a PlayStation 2 game?
* NTSC games will play at 59.94 FPS
* PAL games will play at 50 FPS
* Keep in mind that there is a difference between the internal framerate (iFPS) and what PCSX2 shows as virtual framerate (vFPS).
These framerates are what the PlayStation 2 console would push to a real TV through its video cable. A game itself, typically, internally generates only half of those frames, and repeats frames to fill the gaps. This is why a "full speed" game may not "feel like 60 FPS". The console's "speed" (meaning AI, sound, physics, *everything*) is tied to the playback framerate, which is what PCSX2 reports as its "FPS".
### Question 23: What are Gamefixes
### Question 23: What are Gamefixes?
Gamefixes are specialized fixes built into PCSX2 for specific games. Gamefixes mostly fix core emulation problems that would crash or soft lock a game, rather than graphical or performance issues. By default, the "System > Automatic Gamefixes" option is enabled, meaning any games that need gamefixes will have them automatically applied, regardless of what gamefix settings you have enabled.
Most games will not need gamefixes, however if your game is having issues, you can try manually enabling them in Emulation Settings.
@@ -153,29 +155,29 @@ Gamefixes are not FPS boosters; more often than not, they will degrade performan
<div class="page"/> <!-- Because PDFs are terrible -->
### Question 24: Are Speedhacks safe
### Question 24: Are Speedhacks safe?
As the name says, speedhacks are hacks to make things faster. They will speed up games, but risk causing stability problems or crashing some games. PCSX2 ships with some speedhacks enabled in the default "Safe" preset. This selection of speedhacks has been reviewed thoroughly and determined to be safe for nearly all games.
*Bug reports of issues caused by speedhacks will NOT be accepted, and will be immediately closed as invalid.*
### Question 25: What are all these EE/IOP and VU options
### Question 25: What are all these EE/IOP and VU options?
The PS2 EE, IOP and VU processors are substantially different from a PC CPU and require different rounding and clamping modes to do math accurately. Most games work fine on the default options, but some games might need a different setting. You can check the [PCSX2 Wiki](https://wiki.pcsx2.net/Category:Games) to see if your game needs an alternate setting, or check the [PCSX2 Forums](https://forums.pcsx2.net/) to see if anyone else has posted about it there.
### Question 26: What are PCSX2 plugins
PCSX2 uses a plugin framework for various sections of the emulator. A plugin is a small, incomplete piece of software that, when plugged in to another piece of software, provides some sort of additional function. PCSX2 uses plugins for:
### Question 26: What are PCSX2 plugins?
Older versions of PCSX2 used a plugin framework for various sections of the emulator. A plugin is a small, incomplete piece of software that, when plugged in to another piece of software, provides some sort of additional function. PCSX2 used to use plugins for:
* Video (GSdx)
* Controls (Lilypad for Windows, OnePad for Linux)
* USB (No plugin included)
Each plugin will have its own Plugin Settings menu, and can be found under the Config menu.
In newer versions, these have been merged into the main emulator, and there is no longer a way to load external plugins.
### Question 27: Why is my sound garbled up
### Question 27: Why is my sound garbled up?
PCSX2's default audio playback mode is Timestretch, which will attempt to stretch sounds out when the emulator is unable to play at full speed, to fill the gaps in the sound playback and prevent even harsher stutters. If you are unable to get the game running at full speed or an acceptable speed where timestretching does not ruin the sound, you can try changing from Timestretch to Async, but this may break games.
### Question 28: Is my controller supported
For Windows users running LilyPad, PCSX2 will ship with XInput bindings already created. This will automatically work with an Xbox One controller or any other XInput controller. Bindings can easily be made for DirectInput controllers, such as Xbox 360 controllers. PS3, PS4, or Switch Pro controllers should be set up using a compatibility software, such as Steam's Big Picture mode.
### Question 28: Is my controller supported?
For Windows users, PCSX2 will ship with XInput bindings already created. This will automatically work with an Xbox One controller or any other XInput controller. Bindings can easily be made for DirectInput and XInput controllers, such as Xbox 360 controllers. PS3, PS4, or Switch Pro controllers should be set up using third party compatibility software, such as Steam's Big Picture mode.
For Linux users running OnePad, PCSX2 will automatically detect and bind controls to any recognizable controller. If your controller is not automatically detected, you can try using Onepad Legacy to manually bind controls for it.
For Linux users, PCSX2 will automatically detect and bind controls to any recognizable controller.
<div class="page"/> <!-- Because PDFs are terrible -->
+9 -9
View File
@@ -128,7 +128,7 @@ void iDumpRegisters(u32 startpc, u32 temp)
__Log("ipu %x %x %x %x; bp: %x %x %x %x", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC);
__Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
for(i = 0; i < ArraySize(dmacs); ++i) {
for(i = 0; i < std::size(dmacs); ++i) {
DMACh* p = (DMACh*)(&eeHw[dmacs[i]]);
__Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr._u32, p->madr, p->qwc, p->tadr, p->sadr);
}
@@ -297,7 +297,7 @@ void iDumpBlock( int startpc, u8 * ptr )
memzero(used);
numused = 0;
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->regs); ++i) {
if( s_pInstCache->regs[i] & EEINST_USED ) {
used[i] = 1;
numused++;
@@ -306,7 +306,7 @@ void iDumpBlock( int startpc, u8 * ptr )
memzero(fpuused);
fpunumused = 0;
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->fpuregs); ++i) {
if( s_pInstCache->fpuregs[i] & EEINST_USED ) {
fpuused[i] = 1;
fpunumused++;
@@ -314,11 +314,11 @@ void iDumpBlock( int startpc, u8 * ptr )
}
eff.Printf( " " );
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->regs); ++i) {
if( used[i] ) eff.Printf( "%2d ", i );
}
eff.Printf( "\n" );
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->fpuregs); ++i) {
if( fpuused[i] ) eff.Printf( "%2d ", i );
}
@@ -330,10 +330,10 @@ void iDumpBlock( int startpc, u8 * ptr )
int count;
EEINST* pcur;
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->regs); ++i) {
if( used[i] ) fprintf(f, "%s ", disRNameGPR[i]);
}
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
for(uint i = 0; i < std::size(s_pInstCache->fpuregs); ++i) {
if( fpuused[i] ) fprintf(f, "%s ", i<32?"FR":"FA");
}
fprintf(f, "\n");
@@ -343,14 +343,14 @@ void iDumpBlock( int startpc, u8 * ptr )
fprintf(f, "%2d: %2.2x ", i+1, pcur->info);
count = 1;
for(uint j = 0; j < ArraySize(s_pInstCache->regs); j++) {
for(uint j = 0; j < std::size(s_pInstCache->regs); j++) {
if( used[j] ) {
fprintf(f, "%2.2x%s", pcur->regs[j], ((count%8)&&count<numused)?"_":" ");
++count;
}
}
count = 1;
for(uint j = 0; j < ArraySize(s_pInstCache->fpuregs); j++) {
for(uint j = 0; j < std::size(s_pInstCache->fpuregs); j++) {
if( fpuused[j] ) {
fprintf(f, "%2.2x%s", pcur->fpuregs[j], ((count%8)&&count<fpunumused)?"_":" ");
++count;
+11 -7
View File
@@ -25,36 +25,40 @@ u32 ElfCRC;
u32 ElfEntry;
std::pair<u32,u32> ElfTextRange;
wxString LastELF;
bool isPSXElf;
// All of ElfObjects functions.
ElfObject::ElfObject(const wxString& srcfile, IsoFile& isofile)
ElfObject::ElfObject(const wxString& srcfile, IsoFile& isofile, bool isPSXElf)
: data( wxULongLong(isofile.getLength()).GetLo(), L"ELF headers" )
, proghead( NULL )
, secthead( NULL )
, filename( srcfile )
, header( *(ELF_HEADER*)data.GetPtr() )
{
isCdvd = true;
checkElfSize(data.GetSizeInBytes());
readIso(isofile);
initElfHeaders();
initElfHeaders(isPSXElf);
}
ElfObject::ElfObject( const wxString& srcfile, uint hdrsize )
ElfObject::ElfObject( const wxString& srcfile, uint hdrsize, bool isPSXElf )
: data( wxULongLong(hdrsize).GetLo(), L"ELF headers" )
, proghead( NULL )
, secthead( NULL )
, filename( srcfile )
, header( *(ELF_HEADER*)data.GetPtr() )
{
isCdvd = false;
checkElfSize(data.GetSizeInBytes());
readFile();
initElfHeaders();
initElfHeaders(isPSXElf);
}
void ElfObject::initElfHeaders()
void ElfObject::initElfHeaders(bool isPSXElf)
{
if (isPSXElf)
{
return;
}
DevCon.WriteLn( L"Initializing Elf: %d bytes", data.GetSizeInBytes());
if ( header.e_phnum > 0 )
+4 -10
View File
@@ -19,12 +19,6 @@
#include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h"
#if 0
//2002-09-20 (Florin)
extern char args[256]; //to be filled by GUI
extern unsigned int args_ptr;
#endif
struct ELF_HEADER {
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
@@ -131,21 +125,20 @@ class ElfObject
ELF_SHR* secthead;
wxString filename;
void initElfHeaders();
void initElfHeaders(bool isPSXElf);
void readIso(IsoFile& file);
void readFile();
void checkElfSize(s64 elfsize);
public:
bool isCdvd;
ELF_HEADER& header;
// Destructor!
// C++ does all the cleanup automagically for us.
virtual ~ElfObject() = default;
ElfObject(const wxString& srcfile, IsoFile& isofile);
ElfObject( const wxString& srcfile, uint hdrsize );
ElfObject(const wxString& srcfile, IsoFile& isofile, bool isPSXElf);
ElfObject( const wxString& srcfile, uint hdrsize, bool isPSXElf );
void loadProgramHeaders();
void loadSectionHeaders();
@@ -168,5 +161,6 @@ extern u32 ElfCRC;
extern u32 ElfEntry;
extern std::pair<u32,u32> ElfTextRange;
extern wxString LastELF;
extern bool isPSXElf;
#endif
+1 -2
View File
@@ -18,7 +18,6 @@
#include <list>
#include "GS.h"
#include "Gif_Unit.h"
#include "Counters.h"
#include "Config.h"
@@ -26,7 +25,7 @@
using namespace Threading;
using namespace R5900;
__aligned16 u8 g_RealGSMem[Ps2MemSize::GSregs];
alignas(16) u8 g_RealGSMem[Ps2MemSize::GSregs];
void gsSetVideoMode(GS_VideoMode mode)
{
+2 -2
View File
@@ -21,7 +21,7 @@
#include "GS/GS.h"
extern double GetVerticalFrequency();
extern __aligned16 u8 g_RealGSMem[Ps2MemSize::GSregs];
alignas(16) extern u8 g_RealGSMem[Ps2MemSize::GSregs];
enum CSR_FifoState
{
@@ -483,7 +483,7 @@ struct MTGS_BufferedData
}
};
extern __aligned(32) MTGS_BufferedData RingBuffer;
alignas(32) extern MTGS_BufferedData RingBuffer;
// FIXME: These belong in common with other memcpy tools. Will move them there later if no one
// else beats me to it. --air
+70 -96
View File
@@ -14,8 +14,10 @@
*/
#include "PrecompiledHeader.h"
#include "GS/Window/GSwxDialog.h"
#include "GS.h"
#include "GSUtil.h"
#include "GSExtra.h"
#include "Renderers/SW/GSRendererSW.h"
#include "Renderers/Null/GSRendererNull.h"
#include "Renderers/Null/GSDeviceNull.h"
@@ -30,20 +32,11 @@
#include "Renderers/DX11/GSRendererDX11.h"
#include "Renderers/DX11/GSDevice11.h"
#include "Window/GSSettingsDlg.h"
#include "GS/Renderers/DX11/D3D.h"
static HRESULT s_hr = E_FAIL;
#else
#ifdef __APPLE__
#include <gtk/gtk.h>
#include <CoreFoundation/CoreFoundation.h>
#endif
extern bool RunLinuxDialog();
#endif
#include <fstream>
@@ -54,7 +47,7 @@ extern bool RunLinuxDialog();
#undef None
static GSRenderer* s_gs = NULL;
static uint8* s_basemem = NULL;
static u8* s_basemem = NULL;
static int s_vsync = 0;
static bool s_exclusive = true;
static std::string s_renderer_name;
@@ -67,7 +60,7 @@ static int s_new_gs_window_width = 0;
static int s_new_gs_window_height = 0;
#endif
void GSsetBaseMem(uint8* mem)
void GSsetBaseMem(u8* mem)
{
s_basemem = mem;
@@ -156,7 +149,12 @@ int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, in
renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
#ifdef _WIN32
if (renderer == GSRendererType::Default)
renderer = GSUtil::GetBestRenderer();
{
if (D3D::ShouldPreferD3D())
renderer = GSRendererType::DX1011_HW;
else
renderer = GSRendererType::OGL_HW;
}
#endif
}
@@ -270,19 +268,19 @@ int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, in
return 0;
}
void GSosdLog(const char* utf8, uint32 color)
void GSosdLog(const char* utf8, u32 color)
{
if (s_gs && s_gs->m_dev)
s_gs->m_dev->m_osd.Log(utf8);
}
void GSosdMonitor(const char* key, const char* value, uint32 color)
void GSosdMonitor(const char* key, const char* value, u32 color)
{
if (s_gs && s_gs->m_dev)
s_gs->m_dev->m_osd.Monitor(key, value);
}
int GSopen2(const WindowInfo& wi, uint32 flags)
int GSopen2(const WindowInfo& wi, u32 flags)
{
static bool stored_toggle_state = false;
const bool toggle_state = !!(flags & 4);
@@ -306,7 +304,12 @@ int GSopen2(const WindowInfo& wi, uint32 flags)
const auto config_renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
if (current_renderer == config_renderer)
current_renderer = GSUtil::GetBestRenderer();
{
if (D3D::ShouldPreferD3D())
current_renderer = GSRendererType::DX1011_HW;
else
current_renderer = GSRendererType::OGL_HW;
}
else
current_renderer = config_renderer;
}
@@ -342,7 +345,7 @@ void GSreset()
}
}
void GSgifSoftReset(uint32 mask)
void GSgifSoftReset(u32 mask)
{
try
{
@@ -353,7 +356,7 @@ void GSgifSoftReset(uint32 mask)
}
}
void GSwriteCSR(uint32 csr)
void GSwriteCSR(u32 csr)
{
try
{
@@ -364,7 +367,7 @@ void GSwriteCSR(uint32 csr)
}
}
void GSinitReadFIFO(uint8* mem)
void GSinitReadFIFO(u8* mem)
{
GL_PERF("Init Read FIFO1");
try
@@ -380,7 +383,7 @@ void GSinitReadFIFO(uint8* mem)
}
}
void GSreadFIFO(uint8* mem)
void GSreadFIFO(u8* mem)
{
try
{
@@ -395,7 +398,7 @@ void GSreadFIFO(uint8* mem)
}
}
void GSinitReadFIFO2(uint8* mem, uint32 size)
void GSinitReadFIFO2(u8* mem, u32 size)
{
GL_PERF("Init Read FIFO2");
try
@@ -411,7 +414,7 @@ void GSinitReadFIFO2(uint8* mem, uint32 size)
}
}
void GSreadFIFO2(uint8* mem, uint32 size)
void GSreadFIFO2(u8* mem, u32 size)
{
try
{
@@ -426,7 +429,7 @@ void GSreadFIFO2(uint8* mem, uint32 size)
}
}
void GSgifTransfer(const uint8* mem, uint32 size)
void GSgifTransfer(const u8* mem, u32 size)
{
try
{
@@ -437,33 +440,33 @@ void GSgifTransfer(const uint8* mem, uint32 size)
}
}
void GSgifTransfer1(uint8* mem, uint32 addr)
void GSgifTransfer1(u8* mem, u32 addr)
{
try
{
s_gs->Transfer<0>(const_cast<uint8*>(mem) + addr, (0x4000 - addr) / 16);
s_gs->Transfer<0>(const_cast<u8*>(mem) + addr, (0x4000 - addr) / 16);
}
catch (GSRecoverableError)
{
}
}
void GSgifTransfer2(uint8* mem, uint32 size)
void GSgifTransfer2(u8* mem, u32 size)
{
try
{
s_gs->Transfer<1>(const_cast<uint8*>(mem), size);
s_gs->Transfer<1>(const_cast<u8*>(mem), size);
}
catch (GSRecoverableError)
{
}
}
void GSgifTransfer3(uint8* mem, uint32 size)
void GSgifTransfer3(u8* mem, u32 size)
{
try
{
s_gs->Transfer<2>(const_cast<uint8*>(mem), size);
s_gs->Transfer<2>(const_cast<u8*>(mem), size);
}
catch (GSRecoverableError)
{
@@ -485,7 +488,7 @@ void GSvsync(int field)
}
}
uint32 GSmakeSnapshot(char* path)
u32 GSmakeSnapshot(char* path)
{
try
{
@@ -562,39 +565,12 @@ void GSconfigure()
theApp.SetConfigDir();
theApp.Init();
#ifdef _WIN32
GSDialog::InitCommonControls();
if (GSSettingsDlg().DoModal() == IDOK)
{
// Force a reload of the gs state
theApp.SetCurrentRendererType(GSRendererType::Undefined);
}
#elif defined(__APPLE__)
// Rest of macOS UI doesn't use GTK so we need to init it now
gtk_init(nullptr, nullptr);
// GTK expects us to be using its event loop, rather than Cocoa's
// If we call its stuff right now, it'll attempt to drain a static autorelease pool that was already drained by Cocoa (see https://github.com/GNOME/gtk/blob/8c1072fad1cb6a2e292fce2441b4a571f173ce0f/gdk/quartz/gdkeventloop-quartz.c#L640-L646)
// We can convince it that touching that pool would be unsafe by running all GTK calls within a CFRunLoop
// (Blocks submitted to the main queue by dispatch_async are run by its CFRunLoop)
dispatch_async(dispatch_get_main_queue(), ^{
if (RunLinuxDialog())
{
theApp.ReloadConfig();
// Force a reload of the gs state
theApp.SetCurrentRendererType(GSRendererType::Undefined);
}
});
#else
if (RunLinuxDialog())
if (RunwxDialog())
{
theApp.ReloadConfig();
// Force a reload of the gs state
theApp.SetCurrentRendererType(GSRendererType::Undefined);
}
#endif
}
catch (GSRecoverableError)
{
@@ -654,7 +630,7 @@ void GSendRecording()
pt(" - Capture ended\n");
}
void GSsetGameCRC(uint32 crc, int options)
void GSsetGameCRC(u32 crc, int options)
{
s_gs->SetGameCRC(crc, options);
}
@@ -771,15 +747,15 @@ void vmfree(void* ptr, size_t size)
}
static HANDLE s_fh = NULL;
static uint8* s_Next[8];
static u8* s_Next[8];
void* fifo_alloc(size_t size, size_t repeat)
{
ASSERT(s_fh == NULL);
if (repeat >= countof(s_Next))
if (repeat >= std::size(s_Next))
{
fprintf(stderr, "Memory mapping overflow (%zu >= %u)\n", repeat, static_cast<unsigned>(countof(s_Next)));
fprintf(stderr, "Memory mapping overflow (%zu >= %u)\n", repeat, static_cast<unsigned>(std::size(s_Next)));
return vmalloc(size * repeat, false); // Fallback to default vmalloc
}
@@ -795,8 +771,8 @@ void* fifo_alloc(size_t size, size_t repeat)
void* fifo = MapViewOfFile(s_fh, FILE_MAP_ALL_ACCESS, 0, 0, size);
for (size_t i = 1; i < repeat; i++)
{
void* base = (uint8*)fifo + size * i;
s_Next[i] = (uint8*)MapViewOfFileEx(s_fh, FILE_MAP_ALL_ACCESS, 0, 0, size, base);
void* base = (u8*)fifo + size * i;
s_Next[i] = (u8*)MapViewOfFileEx(s_fh, FILE_MAP_ALL_ACCESS, 0, 0, size, base);
errorID = ::GetLastError();
if (s_Next[i] != base)
{
@@ -833,7 +809,7 @@ void fifo_free(void* ptr, size_t size, size_t repeat)
UnmapViewOfFile(ptr);
for (size_t i = 1; i < countof(s_Next); i++)
for (size_t i = 1; i < std::size(s_Next); i++)
{
if (s_Next[i] != 0)
{
@@ -906,8 +882,8 @@ void* fifo_alloc(size_t size, size_t repeat)
for (size_t i = 1; i < repeat; i++)
{
void* base = (uint8*)fifo + size * i;
uint8* next = (uint8*)mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, s_shm_fd, 0);
void* base = (u8*)fifo + size * i;
u8* next = (u8*)mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, s_shm_fd, 0);
if (next != base)
fprintf(stderr, "Fail to mmap contiguous segment\n");
}
@@ -1106,16 +1082,16 @@ void GSApp::Init()
m_section = "Settings";
#ifdef _WIN32
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::DX1011_HW), "Direct3D 11", ""));
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::OGL_HW), "OpenGL", ""));
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::OGL_SW), "Software", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::DX1011_HW), "Direct3D 11", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::OGL_HW), "OpenGL", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::OGL_SW), "Software", ""));
#else // Linux
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::OGL_HW), "OpenGL", ""));
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::OGL_SW), "Software", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::OGL_HW), "OpenGL", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::OGL_SW), "Software", ""));
#endif
// The null renderer goes third, it has use for benchmarking purposes in a release build
m_gs_renderers.push_back(GSSetting(static_cast<uint32>(GSRendererType::Null), "Null", ""));
m_gs_renderers.push_back(GSSetting(static_cast<u32>(GSRendererType::Null), "Null", ""));
m_gs_interlace.push_back(GSSetting(0, "None", ""));
m_gs_interlace.push_back(GSSetting(1, "Weave tff", "saw-tooth"));
@@ -1145,14 +1121,14 @@ void GSApp::Init()
m_gs_dithering.push_back(GSSetting(2, "Unscaled", "Default"));
m_gs_dithering.push_back(GSSetting(1, "Scaled", ""));
m_gs_bifilter.push_back(GSSetting(static_cast<uint32>(BiFiltering::Nearest), "Nearest", ""));
m_gs_bifilter.push_back(GSSetting(static_cast<uint32>(BiFiltering::Forced_But_Sprite), "Bilinear", "Forced excluding sprite"));
m_gs_bifilter.push_back(GSSetting(static_cast<uint32>(BiFiltering::Forced), "Bilinear", "Forced"));
m_gs_bifilter.push_back(GSSetting(static_cast<uint32>(BiFiltering::PS2), "Bilinear", "PS2"));
m_gs_bifilter.push_back(GSSetting(static_cast<u32>(BiFiltering::Nearest), "Nearest", ""));
m_gs_bifilter.push_back(GSSetting(static_cast<u32>(BiFiltering::Forced_But_Sprite), "Bilinear", "Forced excluding sprite"));
m_gs_bifilter.push_back(GSSetting(static_cast<u32>(BiFiltering::Forced), "Bilinear", "Forced"));
m_gs_bifilter.push_back(GSSetting(static_cast<u32>(BiFiltering::PS2), "Bilinear", "PS2"));
m_gs_trifilter.push_back(GSSetting(static_cast<uint32>(TriFiltering::None), "None", "Default"));
m_gs_trifilter.push_back(GSSetting(static_cast<uint32>(TriFiltering::PS2), "Trilinear", ""));
m_gs_trifilter.push_back(GSSetting(static_cast<uint32>(TriFiltering::Forced), "Trilinear", "Ultra/Slow"));
m_gs_trifilter.push_back(GSSetting(static_cast<u32>(TriFiltering::None), "None", "Default"));
m_gs_trifilter.push_back(GSSetting(static_cast<u32>(TriFiltering::PS2), "Trilinear", ""));
m_gs_trifilter.push_back(GSSetting(static_cast<u32>(TriFiltering::Forced), "Trilinear", "Ultra/Slow"));
m_gs_generic_list.push_back(GSSetting(-1, "Automatic", "Default"));
m_gs_generic_list.push_back(GSSetting(0, "Force-Disabled", ""));
@@ -1185,14 +1161,14 @@ void GSApp::Init()
GSSetting(CRCHackLevel::Aggressive, "Aggressive", ""),
};
m_gs_acc_blend_level.push_back(GSSetting(0, "None", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(0, "Minimum", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(1, "Basic", "Recommended"));
m_gs_acc_blend_level.push_back(GSSetting(2, "Medium", ""));
m_gs_acc_blend_level.push_back(GSSetting(3, "High", ""));
m_gs_acc_blend_level.push_back(GSSetting(4, "Full", "Very Slow"));
m_gs_acc_blend_level.push_back(GSSetting(5, "Ultra", "Ultra Slow"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(0, "None", "Fastest"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(0, "Minimum", "Fastest"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(1, "Basic", "Recommended"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(2, "Medium", "Debug"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(3, "High", "Debug"));
@@ -1207,9 +1183,10 @@ void GSApp::Init()
// Avoid to clutter the ini file with useless options
#ifdef _WIN32
// Per OS option.
m_default_configuration["Adapter"] = "default";
m_default_configuration["adapter_index"] = "0";
m_default_configuration["CaptureFileName"] = "";
m_default_configuration["CaptureVideoCodecDisplayName"] = "";
m_default_configuration["debug_d3d"] = "0";
m_default_configuration["dx_break_on_severity"] = "0";
// D3D Blending option
m_default_configuration["accurate_blending_unit_d3d11"] = "1";
@@ -1226,7 +1203,7 @@ void GSApp::Init()
m_default_configuration["capture_threads"] = "4";
m_default_configuration["CaptureHeight"] = "480";
m_default_configuration["CaptureWidth"] = "640";
m_default_configuration["crc_hack_level"] = std::to_string(static_cast<int8>(CRCHackLevel::Automatic));
m_default_configuration["crc_hack_level"] = std::to_string(static_cast<s8>(CRCHackLevel::Automatic));
m_default_configuration["CrcHacksExclusions"] = "";
m_default_configuration["debug_glsl_shader"] = "0";
m_default_configuration["debug_opengl"] = "0";
@@ -1235,7 +1212,7 @@ void GSApp::Init()
m_default_configuration["dump"] = "0";
m_default_configuration["extrathreads"] = "2";
m_default_configuration["extrathreads_height"] = "4";
m_default_configuration["filter"] = std::to_string(static_cast<int8>(BiFiltering::PS2));
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
m_default_configuration["force_texture_clear"] = "0";
m_default_configuration["fxaa"] = "0";
m_default_configuration["interlace"] = "7";
@@ -1262,22 +1239,19 @@ void GSApp::Init()
m_default_configuration["osd_monitor_enabled"] = "0";
m_default_configuration["osd_max_log_messages"] = "2";
m_default_configuration["override_geometry_shader"] = "-1";
m_default_configuration["override_GL_ARB_compute_shader"] = "-1";
m_default_configuration["override_GL_ARB_copy_image"] = "-1";
m_default_configuration["override_GL_ARB_clear_texture"] = "-1";
m_default_configuration["override_GL_ARB_clip_control"] = "-1";
m_default_configuration["override_GL_ARB_direct_state_access"] = "-1";
m_default_configuration["override_GL_ARB_draw_buffers_blend"] = "-1";
m_default_configuration["override_GL_ARB_get_texture_sub_image"] = "-1";
m_default_configuration["override_GL_ARB_gpu_shader5"] = "-1";
m_default_configuration["override_GL_ARB_multi_bind"] = "-1";
m_default_configuration["override_GL_ARB_shader_image_load_store"] = "-1";
m_default_configuration["override_GL_ARB_shader_storage_buffer_object"] = "-1";
m_default_configuration["override_GL_ARB_sparse_texture"] = "-1";
m_default_configuration["override_GL_ARB_sparse_texture2"] = "-1";
m_default_configuration["override_GL_ARB_texture_view"] = "-1";
m_default_configuration["override_GL_ARB_vertex_attrib_binding"] = "-1";
m_default_configuration["override_GL_ARB_texture_barrier"] = "-1";
#ifdef GL_EXT_TEX_SUB_IMAGE
m_default_configuration["override_GL_ARB_get_texture_sub_image"] = "-1";
#endif
m_default_configuration["paltex"] = "0";
m_default_configuration["png_compression_level"] = std::to_string(Z_BEST_SPEED);
m_default_configuration["preload_frame_with_gs_data"] = "0";
@@ -1315,7 +1289,7 @@ void GSApp::Init()
m_default_configuration["UserHacks_TCOffsetX"] = "0";
m_default_configuration["UserHacks_TCOffsetY"] = "0";
m_default_configuration["UserHacks_TextureInsideRt"] = "0";
m_default_configuration["UserHacks_TriFilter"] = std::to_string(static_cast<int8>(TriFiltering::None));
m_default_configuration["UserHacks_TriFilter"] = std::to_string(static_cast<s8>(TriFiltering::None));
m_default_configuration["UserHacks_WildHack"] = "0";
m_default_configuration["wrap_gs_mem"] = "0";
m_default_configuration["vsync"] = "0";
@@ -1392,7 +1366,7 @@ void GSApp::SetConfigDir()
// core settings aren't populated yet, thus we do populate it if needed either when
// opening GS settings or init -- govanify
wxString iniName(L"GS.ini");
m_ini = EmuFolders::Settings.Combine(iniName).GetFullPath();
m_ini = EmuFolders::Settings.Combine(iniName).GetFullPath().ToUTF8();
}
std::string GSApp::GetConfigS(const char* entry)
@@ -1402,12 +1376,12 @@ std::string GSApp::GetConfigS(const char* entry)
if (def != m_default_configuration.end())
{
GetIniString(m_section.c_str(), entry, def->second.c_str(), buff, countof(buff), m_ini.c_str());
GetIniString(m_section.c_str(), entry, def->second.c_str(), buff, std::size(buff), m_ini.c_str());
}
else
{
fprintf(stderr, "Option %s doesn't have a default value\n", entry);
GetIniString(m_section.c_str(), entry, "", buff, countof(buff), m_ini.c_str());
GetIniString(m_section.c_str(), entry, "", buff, std::size(buff), m_ini.c_str());
}
return {buff};
+24 -1688
View File
File diff suppressed because it is too large Load Diff
-215
View File
@@ -97,130 +97,6 @@ IDR_FONT_ROBOTO RCDATA "res\\fonts-roboto\\Roboto-Regul
// Dialog
//
IDD_HACKS DIALOGEX 0, 0, 210, 289
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced Settings & Hacks"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
// Rendering Hacks:
GROUPBOX "Rendering Hacks",IDC_STATIC,7,7,196,114,0,WS_EX_TRANSPARENT
// Column one - HW Hacks
CONTROL "Auto Flush",IDC_AUTO_FLUSH_HW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,19,55,8
CONTROL "Disable Depth Emulation",IDC_TC_DEPTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,32,92,8
CONTROL "Disable Safe Features",IDC_SAFE_FEATURES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,45,85,8
// Column two - HW hacks
CONTROL "Fast Texture Invalidation",IDC_FAST_TC_INV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,106,19,93,8
CONTROL "Frame Buffer Conversion",IDC_CPU_FB_CONVERSION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,106,32,93,8
CONTROL "Memory Wrapping",IDC_MEMORY_WRAPPING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,106,45,75,8
CONTROL "Preload Frame Data",IDC_PRELOAD_GS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,106,58,80,8
// Columns end
//
RTEXT "Half-screen Fix:",IDC_HALF_SCREEN_TS_TEXT,14,73,62,8
COMBOBOX IDC_HALF_SCREEN_TS,80,70,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Trilinear Filtering:",IDC_TRI_FILTER_TEXT,16,88,60,8
COMBOBOX IDC_TRI_FILTER,80,85,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Skipdraw Range:",IDC_SKIPDRAWHACK_TEXT,14,103,62,8
EDITTEXT IDC_SKIPDRAWOFFSETEDIT,80,100,58,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SKIPDRAWOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
EDITTEXT IDC_SKIPDRAWHACKEDIT,138,100,58,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SKIPDRAWHACK,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
// Upscaling Hacks:
GROUPBOX "Upscaling Hacks",IDC_STATIC,7,124,196,75,0,WS_EX_TRANSPARENT
CONTROL "Align Sprite",IDC_ALIGN_SPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,136,55,8
CONTROL "Merge Sprite",IDC_MERGE_PP_SPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,71,136,55,8
CONTROL "Wild Arms Offset",IDC_WILDHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,136,70,8
RTEXT "Half-pixel Offset:",IDC_OFFSETHACK_TEXT,14,151,62,8
COMBOBOX IDC_OFFSETHACK,80,148,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Round Sprite:",IDC_ROUND_SPRITE_TEXT,30,166,46,8
COMBOBOX IDC_ROUND_SPRITE,80,163,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Texture Offsets:",IDC_TCOFFSET_TEXT,14,181,62,8
RTEXT "X:",IDC_TCOFFSETX_TEXT,81,181,10,8
EDITTEXT IDC_TCOFFSETX2,94,178,44,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_TCOFFSETX,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
RTEXT "Y:",IDC_TCOFFSETY_TEXT,139,181,10,8
EDITTEXT IDC_TCOFFSETY2,152,178,44,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_TCOFFSETY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
// OpenGL Advanced Settings:
GROUPBOX "OpenGL Advanced Settings",IDC_STATIC,7,202,196,61,0,WS_EX_TRANSPARENT
RTEXT "Geometry Shader:",IDC_GEOMETRY_SHADER_TEXT,14,216,62,8
COMBOBOX IDC_GEOMETRY_SHADER_OVERRIDE,80,213,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Image Load Store:",IDC_IMAGE_LOAD_STORE_TEXT,14,231,62,8
COMBOBOX IDC_IMAGE_LOAD_STORE,80,228,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Sparse Texture:",IDC_SPARSE_TEXTURE_TEXT,14,246,62,8
COMBOBOX IDC_SPARSE_TEXTURE,80,243,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
// General Settings:
DEFPUSHBUTTON "OK",IDOK,52,269,50,14
DEFPUSHBUTTON "Cancel",IDCANCEL,108,269,50,14
END
IDD_SHADER DIALOGEX 0, 0, 248, 230
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Shader Configuration"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Texture Filtering of Display",IDC_LINEAR_PRESENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,6,100,10
CONTROL "FXAA Shader (PgUp)",IDC_FXAA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,19,80,10
CONTROL "Shade Boost",IDC_SHADEBOOST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,32,90,10
LTEXT "Shade Boost Brightness",IDC_BRIGHTNESS_TEXT,16,50,80,8
CONTROL "",IDC_BRIGHTNESS_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,95,48,122,15
RTEXT "100",IDC_BRIGHTNESS_VALUE,221,50,12,8
LTEXT "Shade Boost Contrast",IDC_CONTRAST_TEXT,16,75,80,8
CONTROL "",IDC_CONTRAST_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,95,73,122,15
RTEXT "100",IDC_CONTRAST_VALUE,221,75,12,8
LTEXT "Shade Boost Saturation",IDC_SATURATION_TEXT,16,100,80,8
CONTROL "",IDC_SATURATION_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,95,98,122,15
RTEXT "100",IDC_SATURATION_VALUE,221,100,12,8
CONTROL "External Shader (Home)",IDC_SHADER_FX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,116,91,10
LTEXT "External Shader",IDC_SHADER_FX_TEXT,16,131,75,8
EDITTEXT IDC_SHADER_FX_EDIT,16,139,170,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_SHADER_FX_BUTTON,196,139,37,14
LTEXT "External Shader Config",IDC_SHADER_FX_CONF_TEXT,16,156,75,8
PUSHBUTTON "Browse",IDC_SHADER_FX_CONF_BUTTON,196,164,37,14
EDITTEXT IDC_SHADER_FX_CONF_EDIT,16,164,170,14,ES_AUTOHSCROLL
COMBOBOX IDC_TVSHADER,75,184,98,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "TV Shader:",IDC_STATIC,16,186,55,8
DEFPUSHBUTTON "OK",IDOK,71,208,50,14
DEFPUSHBUTTON "Cancel",IDCANCEL,127,208,50,14
END
IDD_OSD DIALOGEX 0, 0, 210, 205
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "OSD Configuration"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
// Enable/Disable
CONTROL "Enable Statistics Monitor",IDC_OSD_MONITOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,7,88,10
CONTROL "Enable Log",IDC_OSD_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,7,54,10
// Font Settings
GROUPBOX "Font",IDC_STATIC,7,20,196,100,0,WS_EX_TRANSPARENT
LTEXT "Size:",IDC_OSD_SIZE_TEXT,16,34,25,8
EDITTEXT IDC_OSD_SIZE_EDIT,112,31,83,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_OSD_SIZE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
LTEXT "Red:",IDC_OSD_COLOR_RED_TEXT,16,51,25,8
CONTROL "",IDC_OSD_COLOR_RED_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,107,49,76,15
RTEXT "255",IDC_OSD_COLOR_RED_AMOUNT,184,52,12,8
LTEXT "Green:",IDC_OSD_COLOR_GREEN_TEXT,16,68,25,8
CONTROL "",IDC_OSD_COLOR_GREEN_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,107,66,76,15
RTEXT "255",IDC_OSD_COLOR_GREEN_AMOUNT,184,69,12,8
LTEXT "Blue:",IDC_OSD_COLOR_BLUE_TEXT,16,86,25,8
CONTROL "",IDC_OSD_COLOR_BLUE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,107,83,76,15
RTEXT "255",IDC_OSD_COLOR_BLUE_AMOUNT,184,86,12,8
LTEXT "Opacity:",IDC_OSD_OPACITY_TEXT,16,104,50,8
CONTROL "",IDC_OSD_OPACITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,107,100,76,15
RTEXT "100",IDC_OSD_OPACITY_AMOUNT,184,104,12,8
// Log Settings
GROUPBOX "Log Messages",IDC_STATIC,7,125,196,52,0,WS_EX_TRANSPARENT
LTEXT "Timeout (seconds):",IDC_OSD_TIMEOUT_TEXT,16,139,75,8
EDITTEXT IDC_OSD_TIMEOUT_EDIT,112,135,83,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "", IDC_OSD_TIMEOUT,"msctls_updown32", UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
LTEXT "Max:",IDC_OSD_MAX_LOG_TEXT,16,158,25,8
EDITTEXT IDC_OSD_MAX_LOG_EDIT,112,155,83,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "", IDC_OSD_MAX_LOG,"msctls_updown32", UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
// OK/CANCEL
DEFPUSHBUTTON "OK",IDOK,52,183,50,14
DEFPUSHBUTTON "Cancel",IDCANCEL,108,183,50,14
END
IDD_CAPTURE DIALOGEX 0, 0, 279, 71
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Capture settings"
@@ -238,53 +114,6 @@ BEGIN
COMBOBOX IDC_COLORSPACE,102,47,48,32,CBS_DROPDOWNLIST | WS_TABSTOP
END
IDD_CONFIG DIALOGEX 0, 0, 242, 315
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Graphics Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
// General Settings:
LTEXT "Renderer:",IDC_STATIC,7,8,79,8
COMBOBOX IDC_RENDERER,71,6,166,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Adapter:",IDC_ADAPTER_TEXT,7,23,79,8
COMBOBOX IDC_ADAPTER,71,21,166,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Interlacing (F5):",IDC_INTERLACE_TEXT,7,38,55,8
COMBOBOX IDC_INTERLACE,71,36,166,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Texture Filtering:",IDC_FILTER_TEXT,7,53,79,8
COMBOBOX IDC_FILTER,71,51,166,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "OSD Configuration",IDC_OSDBUTTON,11,274,108,14
PUSHBUTTON "Shader Configuration",IDC_SHADEBUTTON,125,274,108,14
DEFPUSHBUTTON "OK",IDOK,69,294,50,14
PUSHBUTTON "Cancel",IDCANCEL,125,294,50,14
GROUPBOX "Hardware Renderer Settings",IDC_STATIC,7,67,230,154,BS_CENTER
CONTROL "Accurate DATE",IDC_ACCURATE_DATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,77,63,10
CONTROL "GPU Palette Conversion",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,87,10
CONTROL "Conservative Buffer Allocation",IDC_CONSERVATIVE_FB,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,93,110,10
LTEXT "Internal Resolution:",IDC_UPSCALE_MULTIPLIER_TEXT,23,109,79,8
COMBOBOX IDC_UPSCALE_MULTIPLIER,105,107,127,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Anisotropic Filtering:",IDC_AFCOMBO_TEXT,23,125,79,8
COMBOBOX IDC_AFCOMBO,105,123,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Dithering (PgDn):",IDC_DITHERING_TEXT,23,141,79,8
COMBOBOX IDC_DITHERING,105,139,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Mipmapping (Ins):",IDC_MIPMAP_HW_TEXT,23,157,79,8
COMBOBOX IDC_MIPMAP_HW,105,155,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "CRC Hack Level:",IDC_CRC_LEVEL_TEXT,23,173,79,8
COMBOBOX IDC_CRC_LEVEL,105,171,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Blending Accuracy:",IDC_ACCURATE_BLEND_UNIT_TEXT,23,189,79,8
COMBOBOX IDC_ACCURATE_BLEND_UNIT,105,187,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_ACCURATE_BLEND_UNIT_D3D11,105,187,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Enable HW Hacks",IDC_HACKS_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,205,71,10
PUSHBUTTON "Advanced Settings and Hacks",IDC_HACKSBUTTON,105,203,127,14
GROUPBOX "Software Renderer Settings",IDC_STATIC,7,224,230,44,BS_CENTER
CONTROL "Auto Flush",IDC_AUTO_FLUSH_SW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,236,90,10
CONTROL "Edge Anti-aliasing (Del)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,236,90,10
LTEXT "Rendering threads:",IDC_SWTHREADS_TEXT,125,252,65,8
EDITTEXT IDC_SWTHREADS_EDIT,197,250,34,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,11,14
CONTROL "Mipmapping",IDC_MIPMAP_SW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,250,90,10
END
/////////////////////////////////////////////////////////////////////////////
//
@@ -294,37 +123,6 @@ END
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_HACKS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 154
VERTGUIDE, 14
VERTGUIDE, 84
VERTGUIDE, 88
VERTGUIDE, 146
TOPMARGIN, 7
BOTTOMMARGIN, 229
HORZGUIDE, 51
HORZGUIDE, 64
HORZGUIDE, 77
END
IDD_SHADER, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 242
TOPMARGIN, 7
BOTTOMMARGIN, 244
END
IDD_OSD, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 242
TOPMARGIN, 7
BOTTOMMARGIN, 244
END
IDD_CAPTURE, DIALOG
BEGIN
VERTGUIDE, 6
@@ -332,19 +130,6 @@ BEGIN
VERTGUIDE, 271
HORZGUIDE, 54
END
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 237
VERTGUIDE, 11
VERTGUIDE, 22
VERTGUIDE, 101
VERTGUIDE, 105
VERTGUIDE, 232
TOPMARGIN, 6
BOTTOMMARGIN, 367
END
END
#endif // APSTUDIO_INVOKED
+4 -3
View File
@@ -18,10 +18,11 @@
template <int i>
class GSAlignedClass
{
public:
GSAlignedClass() {}
virtual ~GSAlignedClass() {}
protected:
GSAlignedClass() = default;
~GSAlignedClass() = default;
public:
void* operator new(size_t size)
{
return _aligned_malloc(size, i);
+80 -80
View File
@@ -15,7 +15,7 @@
#pragma once
#include "GS.h"
#include "GSRegs.h"
#include "GSTables.h"
#include "GSVector.h"
@@ -47,11 +47,11 @@ class GSBlock
static const GSVector4i m_uw8hmask3;
public:
template <int i, int alignment, uint32 mask>
__forceinline static void WriteColumn32(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
template <int i, int alignment, u32 mask>
__forceinline static void WriteColumn32(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
const uint8* RESTRICT s0 = &src[srcpitch * 0];
const uint8* RESTRICT s1 = &src[srcpitch * 1];
const u8* RESTRICT s0 = &src[srcpitch * 0];
const u8* RESTRICT s1 = &src[srcpitch * 1];
#if _M_SSE >= 0x501
@@ -173,12 +173,12 @@ public:
}
template <int i, int alignment>
__forceinline static void WriteColumn16(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
__forceinline static void WriteColumn16(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
const uint8* RESTRICT s0 = &src[srcpitch * 0];
const uint8* RESTRICT s1 = &src[srcpitch * 1];
const u8* RESTRICT s0 = &src[srcpitch * 0];
const u8* RESTRICT s1 = &src[srcpitch * 1];
// for(int j = 0; j < 16; j++) {((uint16*)s0)[j] = columnTable16[0][j]; ((uint16*)s1)[j] = columnTable16[1][j];}
// for(int j = 0; j < 16; j++) {((u16*)s0)[j] = columnTable16[0][j]; ((u16*)s1)[j] = columnTable16[1][j];}
#if _M_SSE >= 0x501
@@ -247,7 +247,7 @@ public:
}
template <int i, int alignment>
__forceinline static void WriteColumn8(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
__forceinline static void WriteColumn8(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
// TODO: read unaligned as WriteColumn32 does and try saving a few shuffles
@@ -310,7 +310,7 @@ public:
}
template <int i, int alignment>
__forceinline static void WriteColumn4(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
__forceinline static void WriteColumn4(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
//printf("WriteColumn4\n");
@@ -345,8 +345,8 @@ public:
((GSVector4i*)dst)[i * 4 + 3] = v3;
}
template <int alignment, uint32 mask>
static void WriteColumn32(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
template <int alignment, u32 mask>
static void WriteColumn32(int y, u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
switch ((y >> 1) & 3)
{
@@ -359,7 +359,7 @@ public:
}
template <int alignment>
static void WriteColumn16(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteColumn16(int y, u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
switch ((y >> 1) & 3)
{
@@ -372,7 +372,7 @@ public:
}
template <int alignment>
static void WriteColumn8(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteColumn8(int y, u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
switch ((y >> 2) & 3)
{
@@ -385,7 +385,7 @@ public:
}
template <int alignment>
static void WriteColumn4(int y, uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteColumn4(int y, u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
switch ((y >> 2) & 3)
{
@@ -397,8 +397,8 @@ public:
}
}
template <int alignment, uint32 mask>
static void WriteBlock32(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
template <int alignment, u32 mask>
static void WriteBlock32(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
WriteColumn32<0, alignment, mask>(dst, src, srcpitch);
src += srcpitch * 2;
@@ -410,7 +410,7 @@ public:
}
template <int alignment>
static void WriteBlock16(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteBlock16(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
WriteColumn16<0, alignment>(dst, src, srcpitch);
src += srcpitch * 2;
@@ -422,7 +422,7 @@ public:
}
template <int alignment>
static void WriteBlock8(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteBlock8(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
WriteColumn8<0, alignment>(dst, src, srcpitch);
src += srcpitch * 4;
@@ -434,7 +434,7 @@ public:
}
template <int alignment>
static void WriteBlock4(uint8* RESTRICT dst, const uint8* RESTRICT src, int srcpitch)
static void WriteBlock4(u8* RESTRICT dst, const u8* RESTRICT src, int srcpitch)
{
WriteColumn4<0, alignment>(dst, src, srcpitch);
src += srcpitch * 4;
@@ -446,7 +446,7 @@ public:
}
template <int i>
__forceinline static void ReadColumn32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadColumn32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
#if _M_SSE >= 0x501
@@ -484,7 +484,7 @@ public:
}
template <int i>
__forceinline static void ReadColumn16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadColumn16(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
#if _M_SSE >= 0x501
@@ -526,10 +526,10 @@ public:
}
template <int i>
__forceinline static void ReadColumn8(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadColumn8(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
//for(int j = 0; j < 64; j++) ((uint8*)src)[j] = (uint8)j;
//for(int j = 0; j < 64; j++) ((u8*)src)[j] = (u8)j;
#if 0 //_M_SSE >= 0x501
@@ -593,7 +593,7 @@ public:
}
template <int i>
__forceinline static void ReadColumn4(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadColumn4(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
//printf("ReadColumn4\n");
@@ -628,7 +628,7 @@ public:
GSVector4i::store<true>(&dst[dstpitch * 3], v3);
}
static void ReadColumn32(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadColumn32(int y, const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
switch ((y >> 1) & 3)
{
@@ -640,7 +640,7 @@ public:
}
}
static void ReadColumn16(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadColumn16(int y, const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
switch ((y >> 1) & 3)
{
@@ -652,7 +652,7 @@ public:
}
}
static void ReadColumn8(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadColumn8(int y, const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
switch ((y >> 2) & 3)
{
@@ -664,7 +664,7 @@ public:
}
}
static void ReadColumn4(int y, const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadColumn4(int y, const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
switch ((y >> 2) & 3)
{
@@ -676,7 +676,7 @@ public:
}
}
static void ReadBlock32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadBlock32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
ReadColumn32<0>(src, dst, dstpitch);
dst += dstpitch * 2;
@@ -687,7 +687,7 @@ public:
ReadColumn32<3>(src, dst, dstpitch);
}
static void ReadBlock16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadBlock16(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
ReadColumn16<0>(src, dst, dstpitch);
dst += dstpitch * 2;
@@ -698,7 +698,7 @@ public:
ReadColumn16<3>(src, dst, dstpitch);
}
static void ReadBlock8(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadBlock8(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
ReadColumn8<0>(src, dst, dstpitch);
dst += dstpitch * 4;
@@ -709,7 +709,7 @@ public:
ReadColumn8<3>(src, dst, dstpitch);
}
static void ReadBlock4(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
static void ReadBlock4(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
ReadColumn4<0>(src, dst, dstpitch);
dst += dstpitch * 4;
@@ -720,7 +720,7 @@ public:
ReadColumn4<3>(src, dst, dstpitch);
}
__forceinline static void ReadBlock4P(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadBlock4P(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
//printf("ReadBlock4P\n");
@@ -784,12 +784,12 @@ public:
}
}
__forceinline static void ReadBlock8HP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadBlock8HP(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
#if _M_SSE >= 0x501
uint8* RESTRICT d0 = &dst[dstpitch * 0];
uint8* RESTRICT d1 = &dst[dstpitch * 4];
u8* RESTRICT d0 = &dst[dstpitch * 0];
u8* RESTRICT d1 = &dst[dstpitch * 4];
const GSVector8i* s = (const GSVector8i*)src;
@@ -855,12 +855,12 @@ public:
#endif
}
__forceinline static void ReadBlock4HLP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadBlock4HLP(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
#if _M_SSE >= 0x501
uint8* RESTRICT d0 = &dst[dstpitch * 0];
uint8* RESTRICT d1 = &dst[dstpitch * 4];
u8* RESTRICT d0 = &dst[dstpitch * 0];
u8* RESTRICT d1 = &dst[dstpitch * 4];
const GSVector8i* s = (const GSVector8i*)src;
@@ -929,12 +929,12 @@ public:
#endif
}
__forceinline static void ReadBlock4HHP(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch)
__forceinline static void ReadBlock4HHP(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch)
{
#if _M_SSE >= 0x501
uint8* RESTRICT d0 = &dst[dstpitch * 0];
uint8* RESTRICT d1 = &dst[dstpitch * 4];
u8* RESTRICT d0 = &dst[dstpitch * 0];
u8* RESTRICT d1 = &dst[dstpitch * 4];
const GSVector8i* s = (const GSVector8i*)src;
@@ -1013,7 +1013,7 @@ public:
}
template <bool AEM>
static void ExpandBlock24(const uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
static void ExpandBlock24(const u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
{
#if _M_SSE >= 0x501
@@ -1061,7 +1061,7 @@ public:
}
template <bool AEM>
static void ExpandBlock16(const uint16* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) // do not inline, uses too many xmm regs
static void ExpandBlock16(const u16* RESTRICT src, u8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA) // do not inline, uses too many xmm regs
{
#if _M_SSE >= 0x501
@@ -1101,7 +1101,7 @@ public:
#endif
}
__forceinline static void ExpandBlock8_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock8_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 16; j++, dst += dstpitch)
{
@@ -1109,7 +1109,7 @@ public:
}
}
__forceinline static void ExpandBlock8_16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock8_16(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 16; j++, dst += dstpitch)
{
@@ -1117,7 +1117,7 @@ public:
}
}
__forceinline static void ExpandBlock4_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal)
__forceinline static void ExpandBlock4_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u64* RESTRICT pal)
{
for (int j = 0; j < 16; j++, dst += dstpitch)
{
@@ -1125,7 +1125,7 @@ public:
}
}
__forceinline static void ExpandBlock4_16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal)
__forceinline static void ExpandBlock4_16(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u64* RESTRICT pal)
{
for (int j = 0; j < 16; j++, dst += dstpitch)
{
@@ -1133,7 +1133,7 @@ public:
}
}
__forceinline static void ExpandBlock8H_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock8H_32(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1144,7 +1144,7 @@ public:
}
}
__forceinline static void ExpandBlock8H_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock8H_16(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1158,7 +1158,7 @@ public:
}
}
__forceinline static void ExpandBlock4HL_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock4HL_32(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1169,7 +1169,7 @@ public:
}
}
__forceinline static void ExpandBlock4HL_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock4HL_16(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1182,7 +1182,7 @@ public:
}
}
__forceinline static void ExpandBlock4HH_32(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock4HH_32(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1193,7 +1193,7 @@ public:
}
}
__forceinline static void ExpandBlock4HH_16(uint32* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ExpandBlock4HH_16(u32* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
for (int j = 0; j < 8; j++, dst += dstpitch)
{
@@ -1206,14 +1206,14 @@ public:
}
}
__forceinline static void UnpackAndWriteBlock24(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst)
__forceinline static void UnpackAndWriteBlock24(const u8* RESTRICT src, int srcpitch, u8* RESTRICT dst)
{
#if _M_SSE >= 0x501
const uint8* RESTRICT s0 = &src[srcpitch * 0];
const uint8* RESTRICT s1 = &src[srcpitch * 1];
const uint8* RESTRICT s2 = &src[srcpitch * 2];
const uint8* RESTRICT s3 = &src[srcpitch * 3];
const u8* RESTRICT s0 = &src[srcpitch * 0];
const u8* RESTRICT s1 = &src[srcpitch * 1];
const u8* RESTRICT s2 = &src[srcpitch * 2];
const u8* RESTRICT s3 = &src[srcpitch * 3];
GSVector8i v0, v1, v2, v3, v4, v5, v6;
GSVector8i mask = GSVector8i::x00ffffff();
@@ -1293,7 +1293,7 @@ public:
#endif
}
__forceinline static void UnpackAndWriteBlock8H(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst)
__forceinline static void UnpackAndWriteBlock8H(const u8* RESTRICT src, int srcpitch, u8* RESTRICT dst)
{
#if _M_SSE >= 0x501
@@ -1367,13 +1367,13 @@ public:
#endif
}
__forceinline static void UnpackAndWriteBlock4HL(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst)
__forceinline static void UnpackAndWriteBlock4HL(const u8* RESTRICT src, int srcpitch, u8* RESTRICT dst)
{
//printf("4HL\n");
if (0)
{
uint8* s = (uint8*)src;
u8* s = (u8*)src;
for (int j = 0; j < 8; j++, s += srcpitch)
for (int i = 0; i < 4; i++)
s[i] = (columnTable32[j][i * 2] & 0x0f) | (columnTable32[j][i * 2 + 1] << 4);
@@ -1385,7 +1385,7 @@ public:
GSVector8i v0, v1, v2, v3;
GSVector8i mask(0x0f000000);
v6 = GSVector4i(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 3]);
v6 = GSVector4i(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 3]);
v4 = v6.upl8(v6 >> 4);
v5 = v6.uph8(v6 >> 4);
@@ -1405,7 +1405,7 @@ public:
src += srcpitch * 4;
v6 = GSVector4i(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 3]);
v6 = GSVector4i(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 3]);
v4 = v6.upl8(v6 >> 4);
v5 = v6.uph8(v6 >> 4);
@@ -1434,7 +1434,7 @@ public:
for (int i = 0; i < 2; i++, src += srcpitch * 4)
{
GSVector4i v(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 3]);
GSVector4i v(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 3]);
v4 = v.upl8(v >> 4);
v5 = v.uph8(v >> 4);
@@ -1463,7 +1463,7 @@ public:
#endif
}
__forceinline static void UnpackAndWriteBlock4HH(const uint8* RESTRICT src, int srcpitch, uint8* RESTRICT dst)
__forceinline static void UnpackAndWriteBlock4HH(const u8* RESTRICT src, int srcpitch, u8* RESTRICT dst)
{
#if _M_SSE >= 0x501
@@ -1472,7 +1472,7 @@ public:
GSVector8i v0, v1, v2, v3;
GSVector8i mask = GSVector8i::xf0000000();
v6 = GSVector4i(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 3]);
v6 = GSVector4i(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 3]);
v4 = (v6 << 4).upl8(v6);
v5 = (v6 << 4).uph8(v6);
@@ -1492,7 +1492,7 @@ public:
src += srcpitch * 4;
v6 = GSVector4i(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 3]);
v6 = GSVector4i(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 3]);
v4 = (v6 << 4).upl8(v6);
v5 = (v6 << 4).uph8(v6);
@@ -1521,7 +1521,7 @@ public:
for (int i = 0; i < 2; i++, src += srcpitch * 4)
{
GSVector4i v(*(uint32*)&src[srcpitch * 0], *(uint32*)&src[srcpitch * 1], *(uint32*)&src[srcpitch * 2], *(uint32*)&src[srcpitch * 3]);
GSVector4i v(*(u32*)&src[srcpitch * 0], *(u32*)&src[srcpitch * 1], *(u32*)&src[srcpitch * 2], *(u32*)&src[srcpitch * 3]);
v4 = (v << 4).upl8(v);
v5 = (v << 4).uph8(v);
@@ -1551,7 +1551,7 @@ public:
}
template <bool AEM>
__forceinline static void ReadAndExpandBlock24(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
__forceinline static void ReadAndExpandBlock24(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
{
#if _M_SSE >= 0x501
@@ -1628,7 +1628,7 @@ public:
}
template <bool AEM>
__forceinline static void ReadAndExpandBlock16(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
__forceinline static void ReadAndExpandBlock16(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const GIFRegTEXA& TEXA)
{
#if _M_SSE >= 0x501
@@ -1656,16 +1656,16 @@ public:
#else
alignas(32) uint16 block[16 * 8];
alignas(32) u16 block[16 * 8];
ReadBlock16(src, (uint8*)block, sizeof(block) / 8);
ReadBlock16(src, (u8*)block, sizeof(block) / 8);
ExpandBlock16<AEM>(block, dst, dstpitch, TEXA);
#endif
}
__forceinline static void ReadAndExpandBlock8_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ReadAndExpandBlock8_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
//printf("ReadAndExpandBlock8_32\n");
@@ -1714,7 +1714,7 @@ public:
// TODO: ReadAndExpandBlock8_16
__forceinline static void ReadAndExpandBlock4_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint64* RESTRICT pal)
__forceinline static void ReadAndExpandBlock4_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u64* RESTRICT pal)
{
//printf("ReadAndExpandBlock4_32\n");
@@ -1779,7 +1779,7 @@ public:
// TODO: ReadAndExpandBlock4_16
__forceinline static void ReadAndExpandBlock8H_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ReadAndExpandBlock8H_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
//printf("ReadAndExpandBlock8H_32\n");
@@ -1810,7 +1810,7 @@ public:
// TODO: ReadAndExpandBlock8H_16
__forceinline static void ReadAndExpandBlock4HL_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ReadAndExpandBlock4HL_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
//printf("ReadAndExpandBlock4HL_32\n");
const GSVector4i* s = (const GSVector4i*)src;
@@ -1840,7 +1840,7 @@ public:
// TODO: ReadAndExpandBlock4HL_16
__forceinline static void ReadAndExpandBlock4HH_32(const uint8* RESTRICT src, uint8* RESTRICT dst, int dstpitch, const uint32* RESTRICT pal)
__forceinline static void ReadAndExpandBlock4HH_32(const u8* RESTRICT src, u8* RESTRICT dst, int dstpitch, const u32* RESTRICT pal)
{
//printf("ReadAndExpandBlock4HH_32\n");
+10 -10
View File
@@ -17,7 +17,7 @@
#include "GSCapture.h"
#include "GSPng.h"
#include "GSUtil.h"
#include "GS_types.h"
#include "GSExtra.h"
#ifdef _WIN32
@@ -126,7 +126,7 @@ GSSource : public CBaseFilter, private CCritSec, public IGSSource
vih.bmiHeader.biPlanes = 1;
vih.bmiHeader.biBitCount = 16;
vih.bmiHeader.biSizeImage = m_size.x * m_size.y * 2;
mt.SetFormat((uint8*)&vih, sizeof(vih));
mt.SetFormat((u8*)&vih, sizeof(vih));
m_mts.push_back(mt);
@@ -139,7 +139,7 @@ GSSource : public CBaseFilter, private CCritSec, public IGSSource
vih.bmiHeader.biPlanes = 1;
vih.bmiHeader.biBitCount = 32;
vih.bmiHeader.biSizeImage = m_size.x * m_size.y * 4;
mt.SetFormat((uint8*)&vih, sizeof(vih));
mt.SetFormat((u8*)&vih, sizeof(vih));
if (colorspace == 1)
m_mts.insert(m_mts.begin(), mt);
@@ -272,8 +272,8 @@ public:
const CMediaType& mt = m_output->CurrentMediaType();
uint8* src = (uint8*)bits;
uint8* dst = NULL;
u8* src = (u8*)bits;
u8* dst = NULL;
sample->GetPointer(&dst);
@@ -300,8 +300,8 @@ public:
for (int j = 0; j < h; j++, dst += dstpitch, src += srcpitch)
{
uint32* s = (uint32*)src;
uint16* d = (uint16*)dst;
u32* s = (u32*)src;
u16* d = (u16*)dst;
for (int i = 0; i < w; i += 2)
{
@@ -314,7 +314,7 @@ public:
GSVector4 c = lo.hadd(hi) + offset;
*((uint32*)&d[i]) = GSVector4i(c).rgba32();
*((u32*)&d[i]) = GSVector4i(c).rgba32();
}
}
}
@@ -568,8 +568,8 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
#elif defined(__unix__)
std::string out_file = m_out_dir + format("/frame.%010d.png", m_frame);
//GSPng::Save(GSPng::RGB_PNG, out_file, (uint8*)bits, m_size.x, m_size.y, pitch, m_compression_level);
m_workers[m_frame % m_threads]->Push(std::make_shared<GSPng::Transaction>(GSPng::RGB_PNG, out_file, static_cast<const uint8*>(bits), m_size.x, m_size.y, pitch, m_compression_level));
//GSPng::Save(GSPng::RGB_PNG, out_file, (u8*)bits, m_size.x, m_size.y, pitch, m_compression_level);
m_workers[m_frame % m_threads]->Push(std::make_shared<GSPng::Transaction>(GSPng::RGB_PNG, out_file, static_cast<const u8*>(bits), m_size.x, m_size.y, pitch, m_compression_level));
m_frame++;
+1 -1
View File
@@ -28,7 +28,7 @@ class GSCapture
std::recursive_mutex m_lock;
bool m_capturing;
GSVector2i m_size;
uint64 m_frame;
u64 m_frame;
std::string m_out_dir;
int m_threads;
+59 -82
View File
@@ -16,17 +16,18 @@
#include "PrecompiledHeader.h"
#include "GSClut.h"
#include "GSLocalMemory.h"
#include "GSGL.h"
#define CLUT_ALLOC_SIZE (2 * 4096)
GSClut::GSClut(GSLocalMemory* mem)
: m_mem(mem)
{
uint8* p = (uint8*)vmalloc(CLUT_ALLOC_SIZE, false);
u8* p = (u8*)vmalloc(CLUT_ALLOC_SIZE, false);
m_clut = (uint16*)&p[0]; // 1k + 1k for mirrored area simulating wrapping memory
m_buff32 = (uint32*)&p[2048]; // 1k
m_buff64 = (uint64*)&p[4096]; // 2k
m_clut = (u16*)&p[0]; // 1k + 1k for mirrored area simulating wrapping memory
m_buff32 = (u32*)&p[2048]; // 1k
m_buff64 = (u64*)&p[4096]; // 2k
m_write.dirty = true;
m_read.dirty = true;
@@ -107,7 +108,7 @@ void GSClut::Invalidate()
m_write.dirty = true;
}
void GSClut::Invalidate(uint32 block)
void GSClut::Invalidate(u32 block)
{
if (block == m_write.TEX0.CBP)
{
@@ -158,113 +159,83 @@ void GSClut::Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
m_read.dirty = true;
(this->*m_wc[TEX0.CSM][TEX0.CPSM][TEX0.PSM])(TEX0, TEXCLUT);
// Mirror write to other half of buffer to simulate wrapping memory
int offset = (TEX0.CSA & (TEX0.CPSM < PSM_PSMCT16 ? 15 : 31)) * 16;
if (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT8H)
{
int size = TEX0.CPSM < PSM_PSMCT16 ? 512 : 256;
memcpy(m_clut + 512 + offset, m_clut + offset, sizeof(*m_clut) * std::min(size, 512 - offset));
memcpy(m_clut, m_clut + 512, sizeof(*m_clut) * std::max(0, size + offset - 512));
}
else
{
int size = 16;
memcpy(m_clut + 512 + offset, m_clut + offset, sizeof(*m_clut) * size);
if (TEX0.CPSM < PSM_PSMCT16)
{
memcpy(m_clut + 512 + 256 + offset, m_clut + 256 + offset, sizeof(*m_clut) * size);
}
}
}
void GSClut::WriteCLUT32_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
ALIGN_STACK(32);
//FIXME: Romance of the Three Kingdoms VIII text doesn't like the offset
WriteCLUT_T32_I8_CSM1((uint32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut + ((TEX0.CSA & 15) << 4));
WriteCLUT_T32_I8_CSM1((u32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut, (TEX0.CSA & 15));
}
void GSClut::WriteCLUT32_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
ALIGN_STACK(32);
WriteCLUT_T32_I4_CSM1((uint32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut + ((TEX0.CSA & 15) << 4));
WriteCLUT_T32_I4_CSM1((u32*)m_mem->BlockPtr32(0, 0, TEX0.CBP, 1), m_clut + ((TEX0.CSA & 15) << 4));
}
void GSClut::WriteCLUT16_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
WriteCLUT_T16_I8_CSM1((uint16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
WriteCLUT_T16_I8_CSM1((u16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
}
void GSClut::WriteCLUT16_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
WriteCLUT_T16_I4_CSM1((uint16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
WriteCLUT_T16_I4_CSM1((u16*)m_mem->BlockPtr16(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
}
void GSClut::WriteCLUT16S_I8_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
WriteCLUT_T16_I8_CSM1((uint16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
WriteCLUT_T16_I8_CSM1((u16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
}
void GSClut::WriteCLUT16S_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
WriteCLUT_T16_I4_CSM1((uint16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
WriteCLUT_T16_I4_CSM1((u16*)m_mem->BlockPtr16S(0, 0, TEX0.CBP, 1), m_clut + (TEX0.CSA << 4));
}
template <int n>
void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
GSOffset* off = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32);
GSOffset off = GSOffset::fromKnownPSM(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32);
auto pa = off.paMulti(m_mem->m_vm32, TEXCLUT.COU << 4, TEXCLUT.COV);
uint32* RESTRICT s = &m_mem->m_vm32[off->pixel.row[TEXCLUT.COV]];
int* RESTRICT col = &off->pixel.col[0][TEXCLUT.COU << 4];
uint16* RESTRICT clut = m_clut + ((TEX0.CSA & 15) << 4);
u16* RESTRICT clut = m_clut + ((TEX0.CSA & 15) << 4);
for (int i = 0; i < n; i++)
{
uint32 c = s[col[i]];
u32 c = *pa.value(i);
clut[i] = (uint16)(c & 0xffff);
clut[i + 256] = (uint16)(c >> 16);
clut[i] = (u16)(c & 0xffff);
clut[i + 256] = (u16)(c >> 16);
}
}
template <int n>
void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
GSOffset* off = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16);
GSOffset off = GSOffset::fromKnownPSM(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16);
auto pa = off.paMulti(m_mem->m_vm16, TEXCLUT.COU << 4, TEXCLUT.COV);
uint16* RESTRICT s = &m_mem->m_vm16[off->pixel.row[TEXCLUT.COV]];
int* RESTRICT col = &off->pixel.col[0][TEXCLUT.COU << 4];
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
u16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
for (int i = 0; i < n; i++)
{
clut[i] = s[col[i]];
clut[i] = *pa.value(i);
}
}
template <int n>
void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
{
GSOffset* off = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S);
GSOffset off = GSOffset::fromKnownPSM(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S);
auto pa = off.paMulti(m_mem->m_vm16, TEXCLUT.COU << 4, TEXCLUT.COV);
uint16* RESTRICT s = &m_mem->m_vm16[off->pixel.row[TEXCLUT.COV]];
int* RESTRICT col = &off->pixel.col[0][TEXCLUT.COU << 4];
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
u16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
for (int i = 0; i < n; i++)
{
clut[i] = s[col[i]];
clut[i] = *pa.value(i);
}
}
@@ -282,7 +253,7 @@ void GSClut::Read(const GIFRegTEX0& TEX0)
m_read.TEX0 = TEX0;
m_read.dirty = false;
uint16* clut = m_clut;
u16* clut = m_clut;
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
{
@@ -331,7 +302,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
m_read.dirty = false;
m_read.adirty = true;
uint16* clut = m_clut;
u16* clut = m_clut;
if (TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
{
@@ -339,8 +310,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
{
case PSM_PSMT8:
case PSM_PSMT8H:
clut += (TEX0.CSA & 15) << 4; // disney golf title screen
ReadCLUT_T32_I8(clut, m_buff32);
ReadCLUT_T32_I8(clut, m_buff32, (TEX0.CSA & 15) << 4);
break;
case PSM_PSMT4:
case PSM_PSMT4HL:
@@ -348,7 +318,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
clut += (TEX0.CSA & 15) << 4;
// TODO: merge these functions
ReadCLUT_T32_I4(clut, m_buff32);
ExpandCLUT64_T32_I8(m_buff32, (uint64*)m_buff64); // sw renderer does not need m_buff64 anymore
ExpandCLUT64_T32_I8(m_buff32, (u64*)m_buff64); // sw renderer does not need m_buff64 anymore
break;
}
}
@@ -367,7 +337,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
clut += TEX0.CSA << 4;
// TODO: merge these functions
Expand16(clut, m_buff32, 16, TEXA);
ExpandCLUT64_T32_I8(m_buff32, (uint64*)m_buff64); // sw renderer does not need m_buff64 anymore
ExpandCLUT64_T32_I8(m_buff32, (u64*)m_buff64); // sw renderer does not need m_buff64 anymore
break;
}
}
@@ -443,20 +413,20 @@ void GSClut::GetAlphaMinMax32(int& amin_out, int& amax_out)
//
void GSClut::WriteCLUT_T32_I8_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut)
void GSClut::WriteCLUT_T32_I8_CSM1(const u32* RESTRICT src, u16* RESTRICT clut, u16 offset)
{
// 4 blocks
for (int i = 0; i < 64; i += 16)
// This is required when CSA is offset from the base of the CLUT so we point to the right data
for (int i = offset; i < 16; i ++)
{
WriteCLUT_T32_I4_CSM1(&src[i + 0], &clut[i * 2 + 0]);
WriteCLUT_T32_I4_CSM1(&src[i + 64], &clut[i * 2 + 16]);
WriteCLUT_T32_I4_CSM1(&src[i + 128], &clut[i * 2 + 128]);
WriteCLUT_T32_I4_CSM1(&src[i + 192], &clut[i * 2 + 144]);
const int off = i << 4; // WriteCLUT_T32_I4_CSM1 loads 16 at a time
// Source column
const int s = clutTableT32I8[off & 0x70] | (off & 0x80);
WriteCLUT_T32_I4_CSM1(&src[s], &clut[off]);
}
}
__forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut)
__forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const u32* RESTRICT src, u16* RESTRICT clut)
{
// 1 block
@@ -497,7 +467,7 @@ __forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uin
#endif
}
void GSClut::WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut)
void GSClut::WriteCLUT_T16_I8_CSM1(const u16* RESTRICT src, u16* RESTRICT clut)
{
// 2 blocks
@@ -522,7 +492,7 @@ void GSClut::WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT
}
}
__forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut)
__forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const u16* RESTRICT src, u16* RESTRICT clut)
{
// 1 block (half)
@@ -532,15 +502,22 @@ __forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uin
}
}
void GSClut::ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst)
void GSClut::ReadCLUT_T32_I8(const u16* RESTRICT clut, u32* RESTRICT dst, int offset)
{
// Okay this deserves a small explanation
// T32 I8 can address up to 256 colors however the offset can be "more than zero" when reading
// Previously I assumed that it would wrap around the end of the buffer to the beginning
// but it turns out this is incorrect, the address doesn't mirror, it clamps to to the last offset,
// probably though some sort of addressing mechanism then picks the color from the lower 0xF of the requested CLUT entry.
// if we don't do this, the dirt on GTA SA goes transparent and actually cleans the car driving through dirt.
for (int i = 0; i < 256; i += 16)
{
ReadCLUT_T32_I4(&clut[i], &dst[i]);
// Min value + offet or Last CSA * 16 (240)
ReadCLUT_T32_I4(&clut[std::min((i + offset), 240)], &dst[i]);
}
}
__forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst)
__forceinline void GSClut::ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst)
{
GSVector4i* s = (GSVector4i*)clut;
GSVector4i* d = (GSVector4i*)dst;
@@ -559,7 +536,7 @@ __forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32*
}
#if 0
__forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64)
__forceinline void GSClut::ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst32, u64* RESTRICT dst64)
{
GSVector4i* s = (GSVector4i*)clut;
GSVector4i* d32 = (GSVector4i*)dst32;
@@ -585,7 +562,7 @@ __forceinline void GSClut::ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32*
#endif
#if 0
void GSClut::ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst)
void GSClut::ReadCLUT_T16_I8(const u16* RESTRICT clut, u32* RESTRICT dst)
{
for(int i = 0; i < 256; i += 16)
{
@@ -595,7 +572,7 @@ void GSClut::ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst)
#endif
#if 0
__forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst)
__forceinline void GSClut::ReadCLUT_T16_I4(const u16* RESTRICT clut, u32* RESTRICT dst)
{
GSVector4i* s = (GSVector4i*)clut;
GSVector4i* d = (GSVector4i*)dst;
@@ -611,7 +588,7 @@ __forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32*
#endif
#if 0
__forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64)
__forceinline void GSClut::ReadCLUT_T16_I4(const u16* RESTRICT clut, u32* RESTRICT dst32, u64* RESTRICT dst64)
{
GSVector4i* s = (GSVector4i*)clut;
GSVector4i* d32 = (GSVector4i*)dst32;
@@ -637,7 +614,7 @@ __forceinline void GSClut::ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32*
}
#endif
void GSClut::ExpandCLUT64_T32_I8(const uint32* RESTRICT src, uint64* RESTRICT dst)
void GSClut::ExpandCLUT64_T32_I8(const u32* RESTRICT src, u64* RESTRICT dst)
{
GSVector4i* s = (GSVector4i*)src;
GSVector4i* d = (GSVector4i*)dst;
@@ -680,7 +657,7 @@ __forceinline void GSClut::ExpandCLUT64_T32(const GSVector4i& hi, const GSVector
}
#if 0
void GSClut::ExpandCLUT64_T16_I8(const uint32* RESTRICT src, uint64* RESTRICT dst)
void GSClut::ExpandCLUT64_T16_I8(const u32* RESTRICT src, u64* RESTRICT dst)
{
GSVector4i* s = (GSVector4i*)src;
GSVector4i* d = (GSVector4i*)dst;
@@ -729,7 +706,7 @@ CONSTINIT const GSVector4i GSClut::m_bm = GSVector4i::cxpr(0x00007c00);
CONSTINIT const GSVector4i GSClut::m_gm = GSVector4i::cxpr(0x000003e0);
CONSTINIT const GSVector4i GSClut::m_rm = GSVector4i::cxpr(0x0000001f);
void GSClut::Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int w, const GIFRegTEXA& TEXA)
void GSClut::Expand16(const u16* RESTRICT src, u32* RESTRICT dst, int w, const GIFRegTEXA& TEXA)
{
ASSERT((w & 7) == 0);
+22 -22
View File
@@ -15,7 +15,7 @@
#pragma once
#include "GS.h"
#include "GSRegs.h"
#include "GSVector.h"
#include "GSTables.h"
#include "GSAlignedClass.h"
@@ -30,10 +30,10 @@ class alignas(32) GSClut : public GSAlignedClass<32>
GSLocalMemory* m_mem;
uint32 m_CBP[2];
uint16* m_clut;
uint32* m_buff32;
uint64* m_buff64;
u32 m_CBP[2];
u16* m_clut;
u32* m_buff32;
u64* m_buff64;
struct alignas(32) WriteState
{
@@ -74,42 +74,42 @@ class alignas(32) GSClut : public GSAlignedClass<32>
void WriteCLUT_NULL(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
static void WriteCLUT_T32_I8_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut);
static void WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut);
static void WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut);
static void WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut);
static void ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst);
static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst);
//static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64);
//static void ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst);
//static void ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst);
//static void ReadCLUT_T16_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64);
static void WriteCLUT_T32_I8_CSM1(const u32* RESTRICT src, u16* RESTRICT clut, u16 offset);
static void WriteCLUT_T32_I4_CSM1(const u32* RESTRICT src, u16* RESTRICT clut);
static void WriteCLUT_T16_I8_CSM1(const u16* RESTRICT src, u16* RESTRICT clut);
static void WriteCLUT_T16_I4_CSM1(const u16* RESTRICT src, u16* RESTRICT clut);
static void ReadCLUT_T32_I8(const u16* RESTRICT clut, u32* RESTRICT dst, int offset);
static void ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst);
//static void ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst32, u64* RESTRICT dst64);
//static void ReadCLUT_T16_I8(const u16* RESTRICT clut, u32* RESTRICT dst);
//static void ReadCLUT_T16_I4(const u16* RESTRICT clut, u32* RESTRICT dst);
//static void ReadCLUT_T16_I4(const u16* RESTRICT clut, u32* RESTRICT dst32, u64* RESTRICT dst64);
public:
static void ExpandCLUT64_T32_I8(const uint32* RESTRICT src, uint64* RESTRICT dst);
static void ExpandCLUT64_T32_I8(const u32* RESTRICT src, u64* RESTRICT dst);
private:
static void ExpandCLUT64_T32(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst);
static void ExpandCLUT64_T32(const GSVector4i& hi, const GSVector4i& lo, GSVector4i* dst);
//static void ExpandCLUT64_T16_I8(const uint32* RESTRICT src, uint64* RESTRICT dst);
//static void ExpandCLUT64_T16_I8(const u32* RESTRICT src, u64* RESTRICT dst);
static void ExpandCLUT64_T16(const GSVector4i& hi, const GSVector4i& lo0, const GSVector4i& lo1, const GSVector4i& lo2, const GSVector4i& lo3, GSVector4i* dst);
static void ExpandCLUT64_T16(const GSVector4i& hi, const GSVector4i& lo, GSVector4i* dst);
static void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int w, const GIFRegTEXA& TEXA);
static void Expand16(const u16* RESTRICT src, u32* RESTRICT dst, int w, const GIFRegTEXA& TEXA);
public:
GSClut(GSLocalMemory* mem);
virtual ~GSClut();
void Invalidate();
void Invalidate(uint32 block);
void Invalidate(u32 block);
bool WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
void Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
//void Read(const GIFRegTEX0& TEX0);
void Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
void GetAlphaMinMax32(int& amin, int& amax);
uint32 operator[](size_t i) const { return m_buff32[i]; }
u32 operator[](size_t i) const { return m_buff32[i]; }
operator const uint32*() const { return m_buff32; }
operator const uint64*() const { return m_buff64; }
operator const u32*() const { return m_buff32; }
operator const u64*() const { return m_buff64; }
};
+3 -3
View File
@@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "GSCodeBuffer.h"
#include "GS_types.h"
#include "GSExtra.h"
GSCodeBuffer::GSCodeBuffer(size_t blocksize)
: m_blocksize(blocksize)
@@ -42,14 +42,14 @@ void* GSCodeBuffer::GetBuffer(size_t size)
if (m_ptr == NULL || m_pos + size > m_blocksize)
{
m_ptr = (uint8*)vmalloc(m_blocksize, true);
m_ptr = (u8*)vmalloc(m_blocksize, true);
m_pos = 0;
m_buffers.push_back(m_ptr);
}
uint8* ptr = &m_ptr[m_pos];
u8* ptr = &m_ptr[m_pos];
m_reserved = size;
+1 -3
View File
@@ -15,14 +15,12 @@
#pragma once
#include "GS_types.h"
class GSCodeBuffer
{
std::vector<void*> m_buffers;
size_t m_blocksize;
size_t m_pos, m_reserved;
uint8* m_ptr;
u8* m_ptr;
public:
GSCodeBuffer(size_t blocksize = 4096 * 64); // 256k
+12 -11
View File
@@ -14,10 +14,11 @@
*/
#include "PrecompiledHeader.h"
#include "GS.h"
#include "GSCrc.h"
#include "GSExtra.h"
#include "GS.h"
CRC::Game CRC::m_games[] =
const CRC::Game CRC::m_games[] =
{
// Note: IDs 0x7ACF7E03, 0x7D4EA48F, 0x37C53760 - shouldn't be added as it's from the multiloaders when packing games.
{0x00000000, NoTitle, NoRegion, 0},
@@ -505,7 +506,7 @@ CRC::Game CRC::m_games[] =
{0xB1BE3E51, Whiplash, EU, 0},
};
std::map<uint32, CRC::Game*> CRC::m_map;
std::map<u32, const CRC::Game*> CRC::m_map;
std::string ToLower(std::string str)
{
@@ -517,14 +518,14 @@ std::string ToLower(std::string str)
// The list is case insensitive and order insensitive.
// E.g. Disable all CRC hacks: CrcHacksExclusions=all
// E.g. Disable hacks for these CRCs: CrcHacksExclusions=0x0F0C4A9C, 0x0EE5646B, 0x7ACF7E03
bool IsCrcExcluded(std::string exclusionList, uint32 crc)
bool IsCrcExcluded(std::string exclusionList, u32 crc)
{
std::string target = format("0x%08x", crc);
exclusionList = ToLower(exclusionList);
return exclusionList.find(target) != std::string::npos || exclusionList.find("all") != std::string::npos;
}
CRC::Game CRC::Lookup(uint32 crc)
const CRC::Game& CRC::Lookup(u32 crc)
{
printf("GS Lookup CRC:%08X\n", crc);
if (m_map.empty())
@@ -533,20 +534,20 @@ CRC::Game CRC::Lookup(uint32 crc)
if (exclusions.length() != 0)
printf("GS: CrcHacksExclusions: %s\n", exclusions.c_str());
int crcDups = 0;
for (size_t i = 0; i < countof(m_games); i++)
for (const Game& game : m_games)
{
if (!IsCrcExcluded(exclusions, m_games[i].crc))
if (!IsCrcExcluded(exclusions, game.crc))
{
if (m_map[m_games[i].crc])
if (m_map[game.crc])
{
printf("[FIXME] GS: Duplicate CRC: 0x%08X: (game-id/region-id) %d/%d overrides %d/%d\n", m_games[i].crc, m_games[i].title, m_games[i].region, m_map[m_games[i].crc]->title, m_map[m_games[i].crc]->region);
printf("[FIXME] GS: Duplicate CRC: 0x%08X: (game-id/region-id) %d/%d overrides %d/%d\n", game.crc, game.title, game.region, m_map[game.crc]->title, m_map[game.crc]->region);
crcDups++;
}
m_map[m_games[i].crc] = &m_games[i];
m_map[game.crc] = &game;
}
//else
// printf( "GS: excluding CRC hack for 0x%08x\n", m_games[i].crc );
// printf( "GS: excluding CRC hack for 0x%08x\n", game.crc );
}
if (crcDups)
printf("[FIXME] GS: Duplicate CRC: Overall: %d\n", crcDups);
+7 -5
View File
@@ -15,6 +15,8 @@
#pragma once
#include <map>
class CRC
{
public:
@@ -170,16 +172,16 @@ public:
struct Game
{
uint32 crc;
u32 crc;
Title title;
Region region;
uint32 flags;
u32 flags;
};
private:
static Game m_games[];
static std::map<uint32, Game*> m_map;
static const Game m_games[];
static std::map<u32, const Game*> m_map;
public:
static Game Lookup(uint32 crc);
static const Game& Lookup(u32 crc);
};
+1
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "GSDrawingContext.h"
#include "GSGL.h"
#include "GS.h"
static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
+8 -9
View File
@@ -15,11 +15,10 @@
#pragma once
#ifdef __clang__
// Ignore format for this file, as it spams a lot of warnings about uint64 and %llu.
// Ignore format for this file, as it spams a lot of warnings about u64 and %llu.
#pragma clang diagnostic ignored "-Wformat"
#endif
#include "GS.h"
#include "GSLocalMemory.h"
class alignas(32) GSDrawingContext
@@ -48,9 +47,9 @@ public:
struct
{
GSOffset* fb;
GSOffset* zb;
GSOffset* tex;
GSOffset fb;
GSOffset zb;
GSOffset tex;
GSPixelOffset* fzb;
GSPixelOffset4* fzb4;
} offset;
@@ -102,10 +101,10 @@ public:
{
ASSERT(XYOFFSET.OFX <= 0xf800 && XYOFFSET.OFY <= 0xf800);
scissor.ex.u16[0] = (uint16)((SCISSOR.SCAX0 << 4) + XYOFFSET.OFX - 0x8000);
scissor.ex.u16[1] = (uint16)((SCISSOR.SCAY0 << 4) + XYOFFSET.OFY - 0x8000);
scissor.ex.u16[2] = (uint16)((SCISSOR.SCAX1 << 4) + XYOFFSET.OFX - 0x8000);
scissor.ex.u16[3] = (uint16)((SCISSOR.SCAY1 << 4) + XYOFFSET.OFY - 0x8000);
scissor.ex.U16[0] = (u16)((SCISSOR.SCAX0 << 4) + XYOFFSET.OFX - 0x8000);
scissor.ex.U16[1] = (u16)((SCISSOR.SCAY0 << 4) + XYOFFSET.OFY - 0x8000);
scissor.ex.U16[2] = (u16)((SCISSOR.SCAX1 << 4) + XYOFFSET.OFX - 0x8000);
scissor.ex.U16[3] = (u16)((SCISSOR.SCAY1 << 4) + XYOFFSET.OFY - 0x8000);
scissor.ofex = GSVector4(
(int)((SCISSOR.SCAX0 << 4) + XYOFFSET.OFX),
-2
View File
@@ -15,8 +15,6 @@
#pragma once
#include "GS.h"
class alignas(32) GSDrawingEnvironment
{
public:
+11 -10
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "GSDump.h"
#include "GSExtra.h"
GSDumpBase::GSDumpBase(const std::string& fn)
: m_frames(0)
@@ -31,7 +32,7 @@ GSDumpBase::~GSDumpBase()
fclose(m_gs);
}
void GSDumpBase::AddHeader(uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
void GSDumpBase::AddHeader(u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
{
AppendRawData(&crc, 4);
AppendRawData(&fd.size, 4);
@@ -39,18 +40,18 @@ void GSDumpBase::AddHeader(uint32 crc, const freezeData& fd, const GSPrivRegSet*
AppendRawData(regs, sizeof(*regs));
}
void GSDumpBase::Transfer(int index, const uint8* mem, size_t size)
void GSDumpBase::Transfer(int index, const u8* mem, size_t size)
{
if (size == 0)
return;
AppendRawData(0);
AppendRawData(static_cast<uint8>(index));
AppendRawData(static_cast<u8>(index));
AppendRawData(&size, 4);
AppendRawData(mem, size);
}
void GSDumpBase::ReadFIFO(uint32 size)
void GSDumpBase::ReadFIFO(u32 size)
{
if (size == 0)
return;
@@ -69,7 +70,7 @@ bool GSDumpBase::VSync(int field, bool last, const GSPrivRegSet* regs)
AppendRawData(regs, sizeof(*regs));
AppendRawData(1);
AppendRawData(static_cast<uint8>(field));
AppendRawData(static_cast<u8>(field));
if (last)
m_extra_frames--;
@@ -91,7 +92,7 @@ void GSDumpBase::Write(const void* data, size_t size)
// GSDump implementation
//////////////////////////////////////////////////////////////////////
GSDump::GSDump(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
GSDump::GSDump(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
: GSDumpBase(fn + ".gs")
{
AddHeader(crc, fd, regs);
@@ -102,7 +103,7 @@ void GSDump::AppendRawData(const void* data, size_t size)
Write(data, size);
}
void GSDump::AppendRawData(uint8 c)
void GSDump::AppendRawData(u8 c)
{
Write(&c, 1);
}
@@ -111,7 +112,7 @@ void GSDump::AppendRawData(uint8 c)
// GSDumpXz implementation
//////////////////////////////////////////////////////////////////////
GSDumpXz::GSDumpXz(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
GSDumpXz::GSDumpXz(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
: GSDumpBase(fn + ".gs.xz")
{
m_strm = LZMA_STREAM_INIT;
@@ -150,7 +151,7 @@ void GSDumpXz::AppendRawData(const void* data, size_t size)
Flush();
}
void GSDumpXz::AppendRawData(uint8 c)
void GSDumpXz::AppendRawData(u8 c)
{
m_in_buff.push_back(c);
}
@@ -170,7 +171,7 @@ void GSDumpXz::Flush()
void GSDumpXz::Compress(lzma_action action, lzma_ret expected_status)
{
std::vector<uint8> out_buff(1024 * 1024);
std::vector<u8> out_buff(1024 * 1024);
do
{
m_strm.next_out = out_buff.data();
+11 -10
View File
@@ -15,7 +15,8 @@
#pragma once
#include "GS.h"
#include "SaveState.h"
#include "GSRegs.h"
#include "Renderers/SW/GSVertexSW.h"
#include <lzma.h>
@@ -45,28 +46,28 @@ class GSDumpBase
FILE* m_gs;
protected:
void AddHeader(uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
void AddHeader(u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
void Write(const void* data, size_t size);
virtual void AppendRawData(const void* data, size_t size) = 0;
virtual void AppendRawData(uint8 c) = 0;
virtual void AppendRawData(u8 c) = 0;
public:
GSDumpBase(const std::string& fn);
virtual ~GSDumpBase();
void ReadFIFO(uint32 size);
void Transfer(int index, const uint8* mem, size_t size);
void ReadFIFO(u32 size);
void Transfer(int index, const u8* mem, size_t size);
bool VSync(int field, bool last, const GSPrivRegSet* regs);
};
class GSDump final : public GSDumpBase
{
void AppendRawData(const void* data, size_t size) final;
void AppendRawData(uint8 c) final;
void AppendRawData(u8 c) final;
public:
GSDump(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
GSDump(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
virtual ~GSDump() = default;
};
@@ -74,14 +75,14 @@ class GSDumpXz final : public GSDumpBase
{
lzma_stream m_strm;
std::vector<uint8> m_in_buff;
std::vector<u8> m_in_buff;
void Flush();
void Compress(lzma_action action, lzma_ret expected_status);
void AppendRawData(const void* data, size_t size);
void AppendRawData(uint8 c);
void AppendRawData(u8 c);
public:
GSDumpXz(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
GSDumpXz(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
virtual ~GSDumpXz();
};
+99
View File
@@ -0,0 +1,99 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "GSVector.h"
#ifdef _WIN32
inline std::string convert_utf16_to_utf8(const std::wstring& utf16_string)
{
const int size = WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), nullptr, 0, nullptr, nullptr);
std::string converted_string(size, 0);
WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), converted_string.data(), converted_string.size(), nullptr, nullptr);
return converted_string;
}
inline std::wstring convert_utf8_to_utf16(const std::string& utf8_string)
{
int size = MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, nullptr, 0);
std::vector<wchar_t> converted_string(size);
MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, converted_string.data(), converted_string.size());
return {converted_string.data()};
}
#endif
// _wfopen has to be used on Windows for pathnames containing non-ASCII characters.
inline FILE* px_fopen(const std::string& filename, const std::string& mode)
{
#ifdef _WIN32
return _wfopen(convert_utf8_to_utf16(filename).c_str(), convert_utf8_to_utf16(mode).c_str());
#else
return fopen(filename.c_str(), mode.c_str());
#endif
}
#ifdef ENABLE_ACCURATE_BUFFER_EMULATION
static const GSVector2i default_rt_size(2048, 2048);
#else
static const GSVector2i default_rt_size(1280, 1024);
#endif
// Helper path to dump texture
extern const std::string root_sw;
extern const std::string root_hw;
extern std::string format(const char* fmt, ...);
extern void* vmalloc(size_t size, bool code);
extern void vmfree(void* ptr, size_t size);
extern void* fifo_alloc(size_t size, size_t repeat);
extern void fifo_free(void* ptr, size_t size, size_t repeat);
// 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
#ifdef __GNUC__
// GCC removes the variable as dead code and generates some warnings.
// Stack is automatically realigned due to SSE/AVX operations
#define ALIGN_STACK(n) (void)0;
#else
// TODO Check clang behavior
#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
+67
View File
@@ -0,0 +1,67 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "Renderers/OpenGL/GLLoader.h"
#include "GSExtra.h"
// Note: GL messages are present in common code, so in all renderers.
#define GL_INSERT(type, code, sev, ...) \
do \
if (glDebugMessageInsert) glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, type, code, sev, -1, format(__VA_ARGS__).c_str()); \
while(0);
#if defined(_DEBUG)
#define GL_CACHE(...) GL_INSERT(GL_DEBUG_TYPE_OTHER, 0xFEAD, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__)
#else
#define GL_CACHE(...) (void)(0);
#endif
#if defined(ENABLE_TRACE_REG) && defined(_DEBUG)
#define GL_REG(...) GL_INSERT(GL_DEBUG_TYPE_OTHER, 0xB0B0, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__)
#else
#define GL_REG(...) (void)(0);
#endif
#if defined(ENABLE_EXTRA_LOG) && defined(_DEBUG)
#define GL_DBG(...) GL_INSERT(GL_DEBUG_TYPE_OTHER, 0xD0D0, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__)
#else
#define GL_DBG(...) (void)(0);
#endif
#if defined(ENABLE_OGL_DEBUG)
struct GLAutoPop
{
~GLAutoPop()
{
if (glPopDebugGroup)
glPopDebugGroup();
}
};
#define GL_PUSH_(...) do if (glPushDebugGroup) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, format(__VA_ARGS__).c_str()); while(0);
#define GL_PUSH(...) do if (glPushDebugGroup) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0xBAD, -1, format(__VA_ARGS__).c_str()); while(0); GLAutoPop gl_auto_pop;
#define GL_POP() do if (glPopDebugGroup) glPopDebugGroup(); while(0);
#define GL_INS(...) GL_INSERT(GL_DEBUG_TYPE_ERROR, 0xDEAD, GL_DEBUG_SEVERITY_MEDIUM, __VA_ARGS__)
#define GL_PERF(...) GL_INSERT(GL_DEBUG_TYPE_PERFORMANCE, 0xFEE1, GL_DEBUG_SEVERITY_NOTIFICATION, __VA_ARGS__)
#else
#define GL_PUSH_(...) (void)(0);
#define GL_PUSH(...) (void)(0);
#define GL_POP() (void)(0);
#define GL_INS(...) (void)(0);
#define GL_PERF(...) (void)(0);
#endif
+44
View File
@@ -0,0 +1,44 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 <xmmintrin.h>
#include <emmintrin.h>
#include <tmmintrin.h>
#include <smmintrin.h>
#if _M_SSE >= 0x500
#include <immintrin.h>
#endif
#if !defined(_MSC_VER)
// http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/mingw32/intrin_x86.h?view=markup
static int _BitScanForward(unsigned long* const Index, const unsigned long Mask)
{
#if __has_builtin(__builtin_ctz)
if (Mask == 0)
return 0;
*Index = __builtin_ctz(Mask);
return 1;
#else
__asm__("bsfl %k[Mask], %k[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask) : "cc");
return Mask ? 1 : 0;
#endif
}
#endif
+528 -893
View File
File diff suppressed because it is too large Load Diff
+626 -382
View File
File diff suppressed because it is too large Load Diff
+7 -6
View File
@@ -15,7 +15,6 @@
#include "PrecompiledHeader.h"
#include "GSPerfMon.h"
#include "GS_types.h"
GSPerfMon::GSPerfMon()
: m_frame(0)
@@ -34,11 +33,13 @@ void GSPerfMon::Put(counter_t c, double val)
if (c == Frame)
{
#if defined(__unix__) || defined(__APPLE__)
// clock on linux will return CLOCK_PROCESS_CPUTIME_ID.
// CLOCK_THREAD_CPUTIME_ID is much more useful to measure the fps
struct timespec ts;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
uint64 now = (uint64)ts.tv_sec * (uint64)1e6 + (uint64)ts.tv_nsec / (uint64)1e3;
# ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
# else
clock_gettime(CLOCK_MONOTONIC, &ts);
# endif
u64 now = (u64)ts.tv_sec * (u64)1e6 + (u64)ts.tv_nsec / (u64)1e3;
#else
clock_t now = clock();
#endif
@@ -64,7 +65,7 @@ void GSPerfMon::Update()
#ifndef DISABLE_PERF_MON
if (m_count > 0)
{
for (size_t i = 0; i < countof(m_counters); i++)
for (size_t i = 0; i < std::size(m_counters); i++)
{
m_stats[i] = m_counters[i] / m_count;
}
+4 -6
View File
@@ -15,8 +15,6 @@
#pragma once
#include "GS_types.h"
class GSPerfMon
{
public:
@@ -45,8 +43,8 @@ public:
protected:
double m_counters[CounterLast];
double m_stats[CounterLast];
uint64 m_begin[TimerLast], m_total[TimerLast], m_start[TimerLast];
uint64 m_frame;
u64 m_begin[TimerLast], m_total[TimerLast], m_start[TimerLast];
u64 m_frame;
clock_t m_lastframe;
int m_count;
@@ -55,8 +53,8 @@ protected:
public:
GSPerfMon();
void SetFrame(uint64 frame) { m_frame = frame; }
uint64 GetFrame() { return m_frame; }
void SetFrame(u64 frame) { m_frame = frame; }
u64 GetFrame() { return m_frame; }
void Put(counter_t c, double val = 0);
double Get(counter_t c) { return m_stats[c]; }
+7 -6
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "GSPng.h"
#include "GSExtra.h"
#include <zlib.h>
#include <png.h>
@@ -38,8 +39,8 @@ struct
namespace GSPng
{
bool SaveFile(const std::string& file, const Format fmt, const uint8* const image,
uint8* const row, const int width, const int height, const int pitch,
bool SaveFile(const std::string& file, const Format fmt, const u8* const image,
u8* const row, const int width, const int height, const int pitch,
const int compression, const bool rb_swapped = false, const bool first_image = false)
{
const int channel_bit_depth = pixel[fmt].channel_bit_depth;
@@ -105,7 +106,7 @@ namespace GSPng
return success;
}
bool Save(GSPng::Format fmt, const std::string& file, uint8* image, int w, int h, int pitch, int compression, bool rb_swapped)
bool Save(GSPng::Format fmt, const std::string& file, u8* image, int w, int h, int pitch, int compression, bool rb_swapped)
{
std::string root = file;
root.replace(file.length() - 4, 4, "");
@@ -115,7 +116,7 @@ namespace GSPng
if (compression < 0 || compression > Z_BEST_COMPRESSION)
compression = Z_BEST_SPEED;
std::unique_ptr<uint8[]> row(new uint8[pixel[fmt].bytes_per_pixel_out * w]);
std::unique_ptr<u8[]> row(new u8[pixel[fmt].bytes_per_pixel_out * w]);
std::string filename = root + pixel[fmt].extension[0];
if (!SaveFile(filename, fmt, image, row.get(), w, h, pitch, compression, rb_swapped, true))
@@ -129,11 +130,11 @@ namespace GSPng
return SaveFile(filename, fmt, image, row.get(), w, h, pitch, compression);
}
Transaction::Transaction(GSPng::Format fmt, const std::string& file, const uint8* image, int w, int h, int pitch, int compression)
Transaction::Transaction(GSPng::Format fmt, const std::string& file, const u8* image, int w, int h, int pitch, int compression)
: m_fmt(fmt), m_file(file), m_w(w), m_h(h), m_pitch(pitch), m_compression(compression)
{
// Note: yes it would be better to use shared pointer
m_image = (uint8*)_aligned_malloc(pitch * h, 32);
m_image = (u8*)_aligned_malloc(pitch * h, 32);
if (m_image)
memcpy(m_image, image, pitch * h);
}
+3 -3
View File
@@ -37,17 +37,17 @@ namespace GSPng
public:
Format m_fmt;
const std::string m_file;
uint8* m_image;
u8* m_image;
int m_w;
int m_h;
int m_pitch;
int m_compression;
Transaction(GSPng::Format fmt, const std::string& file, const uint8* image, int w, int h, int pitch, int compression);
Transaction(GSPng::Format fmt, const std::string& file, const u8* image, int w, int h, int pitch, int compression);
~Transaction();
};
bool Save(GSPng::Format fmt, const std::string& file, uint8* image, int w, int h, int pitch, int compression, bool rb_swapped = false);
bool Save(GSPng::Format fmt, const std::string& file, u8* image, int w, int h, int pitch, int compression, bool rb_swapped = false);
void Process(std::shared_ptr<Transaction>& item);
+1411
View File
File diff suppressed because it is too large Load Diff
+321 -335
View File
File diff suppressed because it is too large Load Diff
+33 -32
View File
@@ -31,12 +31,12 @@
struct GSFrameInfo
{
uint32 FBP;
uint32 FPSM;
uint32 FBMSK;
uint32 TBP0;
uint32 TPSM;
uint32 TZTST;
u32 FBP;
u32 FPSM;
u32 FBMSK;
u32 TBP0;
u32 TPSM;
u32 TZTST;
bool TME;
};
@@ -56,8 +56,8 @@ class GSState : public GSAlignedClass<32>
void GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r);
template<uint32 prim, uint32 adc, bool auto_flush> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
template<uint32 prim, uint32 adc, bool auto_flush> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
template<u32 prim, u32 adc, bool auto_flush> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
template<u32 prim, u32 adc, bool auto_flush> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r);
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r);
@@ -67,18 +67,18 @@ class GSState : public GSAlignedClass<32>
GIFRegHandler m_fpGIFRegHandlers[256];
GIFRegHandler m_fpGIFRegHandlerXYZ[8][4];
typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, uint32 size);
typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, u32 size);
GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[2];
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8];
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8];
template<uint32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size);
template<uint32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size);
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, uint32 size);
template<u32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size);
template<u32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size);
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, u32 size);
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);
void ApplyPRIM(uint32 prim);
void ApplyPRIM(u32 prim);
void GIFRegHandlerNull(const GIFReg* RESTRICT r);
void GIFRegHandlerPRIM(const GIFReg* RESTRICT r);
@@ -86,8 +86,8 @@ class GSState : public GSAlignedClass<32>
void GIFRegHandlerST(const GIFReg* RESTRICT r);
void GIFRegHandlerUV(const GIFReg* RESTRICT r);
void GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r);
template<uint32 prim, uint32 adc, bool auto_flush> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
template<uint32 prim, uint32 adc, bool auto_flush> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
template<u32 prim, u32 adc, bool auto_flush> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
template<u32 prim, u32 adc, bool auto_flush> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerTEX0(const GIFReg* RESTRICT r);
template<int i> void GIFRegHandlerCLAMP(const GIFReg* RESTRICT r);
void GIFRegHandlerFOG(const GIFReg* RESTRICT r);
@@ -128,7 +128,7 @@ class GSState : public GSAlignedClass<32>
int x, y;
int start, end, total;
bool overflow;
uint8* buff;
u8* buff;
GIFRegBITBLTBUF m_blit;
GSTransferBuffer();
@@ -157,18 +157,19 @@ protected:
float m_q;
GSVector4i m_scissor;
GSVector4i m_ofxy;
bool tex_flushed;
struct
{
GSVertex* buff;
size_t head, tail, next, maxcount; // head: first vertex, tail: last vertex + 1, next: last indexed + 1
size_t xy_tail;
uint64 xy[4];
u64 xy[4];
} m_vertex;
struct
{
uint32* buff;
u32* buff;
size_t tail;
} m_index;
@@ -179,8 +180,8 @@ protected:
void GrowVertexBuffer();
template <uint32 prim, bool auto_flush>
void VertexKick(uint32 skip);
template <u32 prim, bool auto_flush>
void VertexKick(u32 skip);
// following functions need m_vt to be initialized
@@ -188,11 +189,11 @@ protected:
void GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear);
void GetAlphaMinMax();
bool TryAlphaTest(uint32& fm, uint32& zm);
bool TryAlphaTest(u32& fm, u32& zm);
bool IsOpaque();
bool IsMipMapDraw();
bool IsMipMapActive();
GIFRegTEX0 GetTex0Layer(uint32 lod);
GIFRegTEX0 GetTex0Layer(u32 lod);
public:
GIFPath m_path[4];
@@ -202,7 +203,7 @@ public:
GSDrawingEnvironment m_env;
GSDrawingContext* m_context;
GSPerfMon m_perfmon;
uint32 m_crc;
u32 m_crc;
CRC::Game m_game;
std::unique_ptr<GSDumpBase> m_dump;
int m_options;
@@ -248,17 +249,17 @@ public:
virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false) {}
void Move();
void Write(const uint8* mem, int len);
void Read(uint8* mem, int len);
void InitReadFIFO(uint8* mem, int len);
void Write(const u8* mem, int len);
void Read(u8* mem, int len);
void InitReadFIFO(u8* mem, int len);
void SoftReset(uint32 mask);
void WriteCSR(uint32 csr) { m_regs->CSR.u32[1] = csr; }
void ReadFIFO(uint8* mem, int size);
template<int index> void Transfer(const uint8* mem, uint32 size);
void SoftReset(u32 mask);
void WriteCSR(u32 csr) { m_regs->CSR.U32[1] = csr; }
void ReadFIFO(u8* mem, int size);
template<int index> void Transfer(const u8* mem, u32 size);
int Freeze(freezeData* fd, bool sizeonly);
int Defrost(const freezeData* fd);
virtual void SetGameCRC(uint32 crc, int options);
virtual void SetGameCRC(u32 crc, int options);
void SetFrameSkip(int skip);
void SetRegsMem(uint8* basemem);
void SetRegsMem(u8* basemem);
};
+108 -17
View File
@@ -17,9 +17,19 @@
#include "PrecompiledHeader.h"
#include "GSTables.h"
#include "GS_types.h"
const uint8 blockTable32[4][8] =
template <int Width, int Height>
static constexpr GSSizedBlockSwizzleTable<Height, Width> makeSwizzleTable(const u8 (&arr)[Height][Width]) {
GSSizedBlockSwizzleTable<Height, Width> table = {};
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
table.value[y][x] = arr[y % Height][x % Width];
}
}
return table;
}
static constexpr u8 _blockTable32[4][8] =
{
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
@@ -27,7 +37,7 @@ const uint8 blockTable32[4][8] =
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
const uint8 blockTable32Z[4][8] =
static constexpr u8 _blockTable32Z[4][8] =
{
{ 24, 25, 28, 29, 8, 9, 12, 13},
{ 26, 27, 30, 31, 10, 11, 14, 15},
@@ -35,7 +45,7 @@ const uint8 blockTable32Z[4][8] =
{ 18, 19, 22, 23, 2, 3, 6, 7}
};
const uint8 blockTable16[8][4] =
static constexpr u8 _blockTable16[8][4] =
{
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
@@ -47,7 +57,7 @@ const uint8 blockTable16[8][4] =
{ 21, 23, 29, 31 }
};
const uint8 blockTable16S[8][4] =
static constexpr u8 _blockTable16S[8][4] =
{
{ 0, 2, 16, 18 },
{ 1, 3, 17, 19 },
@@ -59,7 +69,7 @@ const uint8 blockTable16S[8][4] =
{ 13, 15, 29, 31 }
};
const uint8 blockTable16Z[8][4] =
static constexpr u8 _blockTable16Z[8][4] =
{
{ 24, 26, 16, 18 },
{ 25, 27, 17, 19 },
@@ -71,7 +81,7 @@ const uint8 blockTable16Z[8][4] =
{ 13, 15, 5, 7 }
};
const uint8 blockTable16SZ[8][4] =
static constexpr u8 _blockTable16SZ[8][4] =
{
{ 24, 26, 8, 10 },
{ 25, 27, 9, 11 },
@@ -83,7 +93,7 @@ const uint8 blockTable16SZ[8][4] =
{ 21, 23, 5, 7 }
};
const uint8 blockTable8[4][8] =
static constexpr u8 _blockTable8[4][8] =
{
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
@@ -91,7 +101,7 @@ const uint8 blockTable8[4][8] =
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
const uint8 blockTable4[8][4] =
static constexpr u8 _blockTable4[8][4] =
{
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
@@ -103,7 +113,16 @@ const uint8 blockTable4[8][4] =
{ 21, 23, 29, 31 }
};
const uint8 columnTable32[8][8] =
constexpr GSSizedBlockSwizzleTable<4, 8> blockTable32 = makeSwizzleTable(_blockTable32);
constexpr GSSizedBlockSwizzleTable<4, 8> blockTable32Z = makeSwizzleTable(_blockTable32Z);
constexpr GSSizedBlockSwizzleTable<8, 4> blockTable16 = makeSwizzleTable(_blockTable16);
constexpr GSSizedBlockSwizzleTable<8, 4> blockTable16S = makeSwizzleTable(_blockTable16S);
constexpr GSSizedBlockSwizzleTable<8, 4> blockTable16Z = makeSwizzleTable(_blockTable16Z);
constexpr GSSizedBlockSwizzleTable<8, 4> blockTable16SZ = makeSwizzleTable(_blockTable16SZ);
constexpr GSSizedBlockSwizzleTable<4, 8> blockTable8 = makeSwizzleTable(_blockTable8);
constexpr GSSizedBlockSwizzleTable<8, 4> blockTable4 = makeSwizzleTable(_blockTable4);
constexpr u8 columnTable32[8][8] =
{
{ 0, 1, 4, 5, 8, 9, 12, 13 },
{ 2, 3, 6, 7, 10, 11, 14, 15 },
@@ -115,7 +134,7 @@ const uint8 columnTable32[8][8] =
{ 50, 51, 54, 55, 58, 59, 62, 63 },
};
const uint8 columnTable16[8][16] =
constexpr u8 columnTable16[8][16] =
{
{ 0, 2, 8, 10, 16, 18, 24, 26,
1, 3, 9, 11, 17, 19, 25, 27 },
@@ -135,7 +154,7 @@ const uint8 columnTable16[8][16] =
101, 103, 109, 111, 117, 119, 125, 127 },
};
const uint8 columnTable8[16][16] =
constexpr u8 columnTable8[16][16] =
{
{ 0, 4, 16, 20, 32, 36, 48, 52, // column 0
2, 6, 18, 22, 34, 38, 50, 54 },
@@ -171,7 +190,7 @@ const uint8 columnTable8[16][16] =
203, 207, 219, 223, 235, 239, 251, 255 },
};
const uint16 columnTable4[16][32] =
constexpr u16 columnTable4[16][32] =
{
{ 0, 8, 32, 40, 64, 72, 96, 104, // column 0
2, 10, 34, 42, 66, 74, 98, 106,
@@ -239,7 +258,7 @@ const uint16 columnTable4[16][32] =
407, 415, 439, 447, 471, 479, 503, 511 },
};
const uint8 clutTableT32I8[128] =
constexpr u8 clutTableT32I8[128] =
{
0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15,
64, 65, 68, 69, 72, 73, 76, 77, 66, 67, 70, 71, 74, 75, 78, 79,
@@ -251,13 +270,13 @@ const uint8 clutTableT32I8[128] =
112, 113, 116, 117, 120, 121, 124, 125, 114, 115, 118, 119, 122, 123, 126, 127
};
const uint8 clutTableT32I4[16] =
constexpr u8 clutTableT32I4[16] =
{
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15
};
const uint8 clutTableT16I8[32] =
constexpr u8 clutTableT16I8[32] =
{
0, 2, 8, 10, 16, 18, 24, 26,
4, 6, 12, 14, 20, 22, 28, 30,
@@ -265,8 +284,80 @@ const uint8 clutTableT16I8[32] =
5, 7, 13, 15, 21, 23, 29, 31
};
const uint8 clutTableT16I4[16] =
constexpr u8 clutTableT16I4[16] =
{
0, 2, 8, 10, 16, 18, 24, 26,
4, 6, 12, 14, 20, 22, 28, 30
};
template <int BlocksHigh, int BlocksWide, int ColHeight, int ColWidth, typename Col>
constexpr int pxOffset(const u8 (&blockTable)[BlocksHigh][BlocksWide], Col (&colTable)[ColHeight][ColWidth], int x, int y)
{
int blockSize = ColHeight * ColWidth;
int pageSize = blockSize * BlocksHigh * BlocksWide;
int pageWidth = BlocksWide * ColWidth;
int pageX = x / pageWidth;
int subpageX = x % pageWidth;
int blockID = blockTable[y / ColHeight][subpageX / ColWidth];
int sublockOffset = colTable[y % ColHeight][subpageX % ColWidth];
return pageX * pageSize + blockID * blockSize + sublockOffset;
}
template <int BlocksHigh, int BlocksWide, int ColHeight, int ColWidth, typename Col>
constexpr GSPixelColOffsetTable<BlocksHigh * ColHeight> makeColOffsetTable(const u8 (&blockTable)[BlocksHigh][BlocksWide], Col (&colTable)[ColHeight][ColWidth])
{
constexpr int size = BlocksHigh * ColHeight;
GSPixelColOffsetTable<size> table = {};
for (int y = 0; y < size; y++)
{
table.value[y] = pxOffset(blockTable, colTable, 0, y);
}
return table;
}
template <int BlocksHigh, int BlocksWide, int ColHeight, int ColWidth, typename Col>
constexpr GSSizedPixelRowOffsetTable<BlocksWide * ColWidth> makeRowOffsetTable(const u8 (&blockTable)[BlocksHigh][BlocksWide], Col (&colTable)[ColHeight][ColWidth], int y)
{
int base = pxOffset(blockTable, colTable, 0, y);
GSSizedPixelRowOffsetTable<BlocksWide * ColWidth> table = {};
for (int x = 0; x < 2048; x++)
{
table.value[x] = pxOffset(blockTable, colTable, x, y) - base;
}
return table;
}
constexpr GSPixelColOffsetTable< 32> pixelColOffset32 = makeColOffsetTable(_blockTable32, columnTable32);
constexpr GSPixelColOffsetTable< 32> pixelColOffset32Z = makeColOffsetTable(_blockTable32Z, columnTable32);
constexpr GSPixelColOffsetTable< 64> pixelColOffset16 = makeColOffsetTable(_blockTable16, columnTable16);
constexpr GSPixelColOffsetTable< 64> pixelColOffset16S = makeColOffsetTable(_blockTable16S, columnTable16);
constexpr GSPixelColOffsetTable< 64> pixelColOffset16Z = makeColOffsetTable(_blockTable16Z, columnTable16);
constexpr GSPixelColOffsetTable< 64> pixelColOffset16SZ = makeColOffsetTable(_blockTable16SZ, columnTable16);
constexpr GSPixelColOffsetTable< 64> pixelColOffset8 = makeColOffsetTable(_blockTable8, columnTable8);
constexpr GSPixelColOffsetTable<128> pixelColOffset4 = makeColOffsetTable(_blockTable4, columnTable4);
// These can't be constexpr due to a GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99901
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset32 = makeRowOffsetTable(_blockTable32, columnTable32, 0);
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset32Z = makeRowOffsetTable(_blockTable32Z, columnTable32, 0);
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset16 = makeRowOffsetTable(_blockTable16, columnTable16, 0);
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset16S = makeRowOffsetTable(_blockTable16S, columnTable16, 0);
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset16Z = makeRowOffsetTable(_blockTable16Z, columnTable16, 0);
CONSTINIT const GSSizedPixelRowOffsetTable< 64> GSTables::_pixelRowOffset16SZ = makeRowOffsetTable(_blockTable16SZ, columnTable16, 0);
CONSTINIT const GSSizedPixelRowOffsetTable<128> GSTables::_pixelRowOffset8[2] =
{
makeRowOffsetTable(_blockTable8, columnTable8, 0),
makeRowOffsetTable(_blockTable8, columnTable8, 2),
};
CONSTINIT const GSSizedPixelRowOffsetTable<128> GSTables::_pixelRowOffset4[2] =
{
makeRowOffsetTable(_blockTable4, columnTable4, 0),
makeRowOffsetTable(_blockTable4, columnTable4, 2),
};
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset32;
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset32Z;
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset16;
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset16S;
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset16Z;
constexpr GSPixelRowOffsetTableList< 64, 0> GSTables::pixelRowOffset16SZ;
constexpr GSPixelRowOffsetTableList<128, 7> GSTables::pixelRowOffset8;
constexpr GSPixelRowOffsetTableList<128, 7> GSTables::pixelRowOffset4;
+155 -17
View File
@@ -15,21 +15,159 @@
#pragma once
#include "GS_types.h"
/// Table for storing swizzling of blocks within a page
struct alignas(64) GSBlockSwizzleTable
{
// Some swizzles are 4x8 and others are 8x4. An 8x8 table can store either at the cost of 2x size
u8 value[8][8];
extern const uint8 blockTable32[4][8];
extern const uint8 blockTable32Z[4][8];
extern const uint8 blockTable16[8][4];
extern const uint8 blockTable16S[8][4];
extern const uint8 blockTable16Z[8][4];
extern const uint8 blockTable16SZ[8][4];
extern const uint8 blockTable8[4][8];
extern const uint8 blockTable4[8][4];
extern const uint8 columnTable32[8][8];
extern const uint8 columnTable16[8][16];
extern const uint8 columnTable8[16][16];
extern const uint16 columnTable4[16][32];
extern const uint8 clutTableT32I8[128];
extern const uint8 clutTableT32I4[16];
extern const uint8 clutTableT16I8[32];
extern const uint8 clutTableT16I4[16];
constexpr u8 lookup(int x, int y) const
{
return value[y & 7][x & 7];
}
};
/// Adds sizes to GSBlockSwizzleTable for to feel better about not making mistakes
template <int Height, int Width>
struct GSSizedBlockSwizzleTable : public GSBlockSwizzleTable
{
};
/// Table for storing offsets of x = 0 pixels from the beginning of the page
/// Add values from a GSPixelRowOffsetTable to get the pixels for x != 0
template <int Height>
struct alignas(128) GSPixelColOffsetTable
{
int value[Height] = {};
int operator[](int y) const
{
return value[y % Height];
}
};
/// Table for storing offsets of x != 0 pixels from the pixel at the same y where x = 0
/// Unlike ColOffsets, this table stretches to the maximum size of a texture so no masking is needed
struct alignas(128) GSPixelRowOffsetTable
{
int value[2048] = {};
int operator[](size_t x) const
{
ASSERT(x < 2048);
return value[x];
}
};
/// Adds size to GSPixelRowOffsetTable to feel better about not making mistakes
template <int PageWidth>
struct GSSizedPixelRowOffsetTable : public GSPixelRowOffsetTable
{
};
/// List of row offset tables
/// Some swizzlings (PSMT8 and PSMT4) have different row offsets depending on which column they're a part of
/// The ones that do use an a a b b b b a a pattern that repeats every 8 rows.
/// You can always look up the correct row in this list with y & 7, but if you use y & Mask where Mask is known at compile time, the compiler should be able to optimize better
template <int PageWidth, int Mask>
struct alignas(sizeof(void*) * 8) GSPixelRowOffsetTableList
{
const GSPixelRowOffsetTable* rows[8];
const GSPixelRowOffsetTable& operator[](int y) const
{
return *rows[y & Mask];
}
};
/// Full pixel offset table
/// Template values are for objects constructing from one of these tables
template <int PageHeight, int PageWidth, int BlockHeight, int BlockWidth, int RowMask>
struct GSSwizzleTableList
{
const GSSizedBlockSwizzleTable<BlockHeight, BlockWidth>& block;
const GSPixelColOffsetTable<PageHeight>& col;
const GSPixelRowOffsetTableList<PageWidth, RowMask>& row;
};
/// List of all tables for a given swizzle for easy setup
template <int PageHeight, int PageWidth, int BlockHeight, int BlockWidth, int RowMask>
constexpr GSSwizzleTableList<PageHeight, PageWidth, BlockHeight, BlockWidth, RowMask>
makeSwizzleTableList(
const GSSizedBlockSwizzleTable<BlockHeight, BlockWidth>& block,
const GSPixelColOffsetTable<PageHeight>& col,
const GSPixelRowOffsetTableList<PageWidth, RowMask>& row)
{
return {block, col, row};
}
extern const GSSizedBlockSwizzleTable<4, 8> blockTable32;
extern const GSSizedBlockSwizzleTable<4, 8> blockTable32Z;
extern const GSSizedBlockSwizzleTable<8, 4> blockTable16;
extern const GSSizedBlockSwizzleTable<8, 4> blockTable16S;
extern const GSSizedBlockSwizzleTable<8, 4> blockTable16Z;
extern const GSSizedBlockSwizzleTable<8, 4> blockTable16SZ;
extern const GSSizedBlockSwizzleTable<4, 8> blockTable8;
extern const GSSizedBlockSwizzleTable<8, 4> blockTable4;
extern const u8 columnTable32[8][8];
extern const u8 columnTable16[8][16];
extern const u8 columnTable8[16][16];
extern const u16 columnTable4[16][32];
extern const u8 clutTableT32I8[128];
extern const u8 clutTableT32I4[16];
extern const u8 clutTableT16I8[32];
extern const u8 clutTableT16I4[16];
extern const GSPixelColOffsetTable< 32> pixelColOffset32;
extern const GSPixelColOffsetTable< 32> pixelColOffset32Z;
extern const GSPixelColOffsetTable< 64> pixelColOffset16;
extern const GSPixelColOffsetTable< 64> pixelColOffset16S;
extern const GSPixelColOffsetTable< 64> pixelColOffset16Z;
extern const GSPixelColOffsetTable< 64> pixelColOffset16SZ;
extern const GSPixelColOffsetTable< 64> pixelColOffset8;
extern const GSPixelColOffsetTable<128> pixelColOffset4;
template <int PageWidth>
constexpr GSPixelRowOffsetTableList<PageWidth, 0> makeRowOffsetTableList(
const GSSizedPixelRowOffsetTable<PageWidth>* a)
{
return {{a, a, a, a, a, a, a, a}};
}
template <int PageWidth>
constexpr GSPixelRowOffsetTableList<PageWidth, 7> makeRowOffsetTableList(
const GSSizedPixelRowOffsetTable<PageWidth>* a,
const GSSizedPixelRowOffsetTable<PageWidth>* b)
{
return {{a, a, b, b, b, b, a, a}};
}
/// Just here to force external linkage so we don't end up with multiple copies of pixelRowOffset*
struct GSTables
{
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset32;
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset32Z;
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset16;
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset16S;
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset16Z;
static const GSSizedPixelRowOffsetTable< 64> _pixelRowOffset16SZ;
static const GSSizedPixelRowOffsetTable<128> _pixelRowOffset8[2];
static const GSSizedPixelRowOffsetTable<128> _pixelRowOffset4[2];
static constexpr auto pixelRowOffset32 = makeRowOffsetTableList(&_pixelRowOffset32);
static constexpr auto pixelRowOffset32Z = makeRowOffsetTableList(&_pixelRowOffset32Z);
static constexpr auto pixelRowOffset16 = makeRowOffsetTableList(&_pixelRowOffset16);
static constexpr auto pixelRowOffset16S = makeRowOffsetTableList(&_pixelRowOffset16S);
static constexpr auto pixelRowOffset16Z = makeRowOffsetTableList(&_pixelRowOffset16Z);
static constexpr auto pixelRowOffset16SZ = makeRowOffsetTableList(&_pixelRowOffset16SZ);
static constexpr auto pixelRowOffset8 = makeRowOffsetTableList(&_pixelRowOffset8[0], &_pixelRowOffset8[1]);
static constexpr auto pixelRowOffset4 = makeRowOffsetTableList(&_pixelRowOffset4[0], &_pixelRowOffset4[1]);
};
constexpr auto swizzleTables32 = makeSwizzleTableList(blockTable32, pixelColOffset32, GSTables::pixelRowOffset32 );
constexpr auto swizzleTables32Z = makeSwizzleTableList(blockTable32Z, pixelColOffset32Z, GSTables::pixelRowOffset32Z );
constexpr auto swizzleTables16 = makeSwizzleTableList(blockTable16, pixelColOffset16, GSTables::pixelRowOffset16 );
constexpr auto swizzleTables16Z = makeSwizzleTableList(blockTable16Z, pixelColOffset16Z, GSTables::pixelRowOffset16Z );
constexpr auto swizzleTables16S = makeSwizzleTableList(blockTable16S, pixelColOffset16S, GSTables::pixelRowOffset16S );
constexpr auto swizzleTables16SZ = makeSwizzleTableList(blockTable16SZ, pixelColOffset16SZ, GSTables::pixelRowOffset16SZ);
constexpr auto swizzleTables8 = makeSwizzleTableList(blockTable8, pixelColOffset8, GSTables::pixelRowOffset8 );
constexpr auto swizzleTables4 = makeSwizzleTableList(blockTable4, pixelColOffset4, GSTables::pixelRowOffset4 );
+5 -2
View File
@@ -18,6 +18,9 @@
#include "GS.h"
#include "common/boost_spsc_queue.hpp"
#include "common/General.h"
#include <condition_variable>
#include <functional>
#include <mutex>
template <class T, int CAPACITY>
class GSJobQueue final
@@ -50,7 +53,7 @@ private:
l.unlock();
uint32 waited = 0;
u32 waited = 0;
while (true)
{
while (m_queue.consume_one(*this))
@@ -110,7 +113,7 @@ public:
void Wait()
{
uint32 waited = 0;
u32 waited = 0;
while (true)
{
if (IsEmpty())
+18 -93
View File
@@ -14,12 +14,13 @@
*/
#include "PrecompiledHeader.h"
#include "GS.h"
#include "GSExtra.h"
#include "GSUtil.h"
#include <locale>
#include <codecvt>
#ifdef _WIN32
#include "Renderers/DX11/GSDevice11.h"
#include <VersionHelpers.h>
#include "svnrev.h"
#include <wil/com.h>
@@ -33,11 +34,11 @@ Xbyak::util::Cpu g_cpu;
static class GSUtilMaps
{
public:
uint8 PrimClassField[8];
uint8 VertexCountField[8];
uint8 ClassVertexCountField[4];
uint32 CompatibleBitsField[64][2];
uint32 SharedBitsField[64][2];
u8 PrimClassField[8];
u8 VertexCountField[8];
u8 ClassVertexCountField[4];
u32 CompatibleBitsField[64][2];
u32 SharedBitsField[64][2];
// Defer init to avoid AVX2 illegal instructions
void Init()
@@ -106,42 +107,42 @@ void GSUtil::Init()
s_maps.Init();
}
GS_PRIM_CLASS GSUtil::GetPrimClass(uint32 prim)
GS_PRIM_CLASS GSUtil::GetPrimClass(u32 prim)
{
return (GS_PRIM_CLASS)s_maps.PrimClassField[prim];
}
int GSUtil::GetVertexCount(uint32 prim)
int GSUtil::GetVertexCount(u32 prim)
{
return s_maps.VertexCountField[prim];
}
int GSUtil::GetClassVertexCount(uint32 primclass)
int GSUtil::GetClassVertexCount(u32 primclass)
{
return s_maps.ClassVertexCountField[primclass];
}
const uint32* GSUtil::HasSharedBitsPtr(uint32 dpsm)
const u32* GSUtil::HasSharedBitsPtr(u32 dpsm)
{
return s_maps.SharedBitsField[dpsm];
}
bool GSUtil::HasSharedBits(uint32 spsm, const uint32* RESTRICT ptr)
bool GSUtil::HasSharedBits(u32 spsm, const u32* RESTRICT ptr)
{
return (ptr[spsm >> 5] & (1 << (spsm & 0x1f))) == 0;
}
bool GSUtil::HasSharedBits(uint32 spsm, uint32 dpsm)
bool GSUtil::HasSharedBits(u32 spsm, u32 dpsm)
{
return (s_maps.SharedBitsField[dpsm][spsm >> 5] & (1 << (spsm & 0x1f))) == 0;
}
bool GSUtil::HasSharedBits(uint32 sbp, uint32 spsm, uint32 dbp, uint32 dpsm)
bool GSUtil::HasSharedBits(u32 sbp, u32 spsm, u32 dbp, u32 dpsm)
{
return ((sbp ^ dbp) | (s_maps.SharedBitsField[dpsm][spsm >> 5] & (1 << (spsm & 0x1f)))) == 0;
}
bool GSUtil::HasCompatibleBits(uint32 spsm, uint32 dpsm)
bool GSUtil::HasCompatibleBits(u32 spsm, u32 dpsm)
{
return (s_maps.CompatibleBitsField[spsm][dpsm >> 5] & (1 << (dpsm & 0x1f))) != 0;
}
@@ -168,11 +169,11 @@ bool GSUtil::CheckSSE()
#endif
};
for (size_t i = 0; i < countof(checks); i++)
for (const ISA& check : checks)
{
if (!g_cpu.has(checks[i].type))
if (!g_cpu.has(check.type))
{
fprintf(stderr, "This CPU does not support %s\n", checks[i].name);
fprintf(stderr, "This CPU does not support %s\n", check.name);
status = false;
}
@@ -186,82 +187,6 @@ CRCHackLevel GSUtil::GetRecommendedCRCHackLevel(GSRendererType type)
return type == GSRendererType::OGL_HW ? CRCHackLevel::Partial : CRCHackLevel::Full;
}
#ifdef _WIN32
// ---------------------------------------------------------------------------------
// DX11 Detection (includes DXGI detection and dynamic library method bindings)
// ---------------------------------------------------------------------------------
// Code 'Borrowed' from Microsoft's DXGI sources -- Modified to suit our needs. --air
// Stripped down because of unnecessary complexity and false positives
// e.g. (d3d11_beta.dll would fail at device creation time) --pseudonym
static int s_DXGI;
static int s_D3D11;
bool GSUtil::CheckDXGI()
{
if (0 == s_DXGI)
{
HMODULE hmod = LoadLibrary(L"dxgi.dll");
s_DXGI = hmod ? 1 : -1;
if (hmod)
FreeLibrary(hmod);
}
return s_DXGI > 0;
}
bool GSUtil::CheckD3D11()
{
if (!CheckDXGI())
return false;
if (0 == s_D3D11)
{
HMODULE hmod = LoadLibrary(L"d3d11.dll");
s_D3D11 = hmod ? 1 : -1;
if (hmod)
FreeLibrary(hmod);
}
return s_D3D11 > 0;
}
D3D_FEATURE_LEVEL GSUtil::CheckDirect3D11Level(IDXGIAdapter* adapter, D3D_DRIVER_TYPE type)
{
HRESULT hr;
D3D_FEATURE_LEVEL level;
if (!CheckD3D11())
return (D3D_FEATURE_LEVEL)0;
hr = D3D11CreateDevice(adapter, type, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, &level, NULL);
return SUCCEEDED(hr) ? level : (D3D_FEATURE_LEVEL)0;
}
GSRendererType GSUtil::GetBestRenderer()
{
wil::com_ptr_nothrow<IDXGIFactory1> dxgi_factory;
if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(dxgi_factory.put()))))
{
wil::com_ptr_nothrow<IDXGIAdapter1> adapter;
if (SUCCEEDED(dxgi_factory->EnumAdapters1(0, adapter.put())))
{
DXGI_ADAPTER_DESC1 desc;
if (SUCCEEDED(adapter->GetDesc1(&desc)))
{
D3D_FEATURE_LEVEL level = GSUtil::CheckDirect3D11Level();
// Check for Nvidia VendorID. Latest OpenGL features need at least DX11 level GPU
if (desc.VendorId == 0x10DE && level >= D3D_FEATURE_LEVEL_11_0)
return GSRendererType::OGL_HW;
}
}
}
return GSRendererType::DX1011_HW;
}
#endif
#ifdef _WIN32
void GSmkdir(const wchar_t* dir)
{
+13 -15
View File
@@ -16,6 +16,11 @@
#pragma once
#include "GS.h"
#include "GSRegs.h"
#ifdef _WIN32
#include <d3dcommon.h>
#include <dxgi.h>
#endif
#include <xbyak/xbyak_util.h>
@@ -24,25 +29,18 @@ class GSUtil
public:
static void Init();
static GS_PRIM_CLASS GetPrimClass(uint32 prim);
static int GetVertexCount(uint32 prim);
static int GetClassVertexCount(uint32 primclass);
static GS_PRIM_CLASS GetPrimClass(u32 prim);
static int GetVertexCount(u32 prim);
static int GetClassVertexCount(u32 primclass);
static const uint32* HasSharedBitsPtr(uint32 dpsm);
static bool HasSharedBits(uint32 spsm, const uint32* ptr);
static bool HasSharedBits(uint32 spsm, uint32 dpsm);
static bool HasSharedBits(uint32 sbp, uint32 spsm, uint32 dbp, uint32 dpsm);
static bool HasCompatibleBits(uint32 spsm, uint32 dpsm);
static const u32* HasSharedBitsPtr(u32 dpsm);
static bool HasSharedBits(u32 spsm, const u32* ptr);
static bool HasSharedBits(u32 spsm, u32 dpsm);
static bool HasSharedBits(u32 sbp, u32 spsm, u32 dbp, u32 dpsm);
static bool HasCompatibleBits(u32 spsm, u32 dpsm);
static bool CheckSSE();
static CRCHackLevel GetRecommendedCRCHackLevel(GSRendererType type);
#ifdef _WIN32
static bool CheckDXGI();
static bool CheckD3D11();
static GSRendererType GetBestRenderer();
static D3D_FEATURE_LEVEL CheckDirect3D11Level(IDXGIAdapter* adapter = NULL, D3D_DRIVER_TYPE type = D3D_DRIVER_TYPE_HARDWARE);
#endif
};
#ifdef _WIN32
+2 -2
View File
@@ -14,8 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "GS.h"
#include "GSVector.h"
#include <cfloat>
CONSTINIT const GSVector4i GSVector4i::m_xff[17] =
{
@@ -201,7 +201,7 @@ GSVector4i GSVector4i::fit(int preset) const
{
GSVector4i r;
if (preset > 0 && preset < (int)countof(s_ar))
if (preset > 0 && preset < (int)std::size(s_ar))
{
r = fit(s_ar[preset][0], s_ar[preset][1]);
}
+9 -15
View File
@@ -14,14 +14,14 @@
*/
#include "PrecompiledHeader.h"
#include "GS_types.h"
#include "GSIntrin.h"
#pragma once
#ifdef _WIN32
# define gsforceinline __forceinline
#define gsforceinline __forceinline
#else
# define gsforceinline __forceinline __inline__
#define gsforceinline __forceinline __inline__
#endif
enum Align_Mode
@@ -53,28 +53,22 @@ public:
struct { T v[2]; };
};
GSVector2T()
GSVector2T() = default;
constexpr GSVector2T(T x): x(x), y(x)
{
}
GSVector2T(T x)
constexpr GSVector2T(T x, T y): x(x), y(y)
{
this->x = x;
this->y = x;
}
GSVector2T(T x, T y)
{
this->x = x;
this->y = y;
}
bool operator==(const GSVector2T& v) const
constexpr bool operator==(const GSVector2T& v) const
{
return x == v.x && y == v.y;
}
bool operator!=(const GSVector2T& v) const
constexpr bool operator!=(const GSVector2T& v) const
{
return x != v.x || y != v.y;
}
+14 -14
View File
@@ -50,15 +50,15 @@ public:
struct { float r, g, b, a; };
struct { float left, top, right, bottom; };
float v[4];
float f32[4];
int8 i8[16];
int16 i16[8];
int32 i32[4];
int64 i64[2];
uint8 u8[16];
uint16 u16[8];
uint32 u32[4];
uint64 u64[2];
float F32[4];
s8 I8[16];
s16 I16[8];
s32 I32[4];
s64 I64[2];
u8 U8[16];
u16 U16[8];
u32 U32[4];
u64 U64[2];
__m128 m;
};
@@ -154,7 +154,7 @@ public:
#endif
}
__forceinline explicit GSVector4(uint32 u)
__forceinline explicit GSVector4(u32 u)
{
GSVector4i v((int)u);
@@ -216,17 +216,17 @@ public:
return *this;
}
__forceinline uint32 rgba32() const
__forceinline u32 rgba32() const
{
return GSVector4i(*this).rgba32();
}
__forceinline static GSVector4 rgba32(uint32 rgba)
__forceinline static GSVector4 rgba32(u32 rgba)
{
return GSVector4(GSVector4i::load((int)rgba).u8to32());
}
__forceinline static GSVector4 rgba32(uint32 rgba, int shift)
__forceinline static GSVector4 rgba32(u32 rgba, int shift)
{
return GSVector4(GSVector4i::load((int)rgba).u8to32() << shift);
}
@@ -634,7 +634,7 @@ GSVector.h:2973:15: error: shadows template parm 'int i'
return GSVector4(_mm_load_ss(&f));
}
__forceinline static GSVector4 load(uint32 u)
__forceinline static GSVector4 load(u32 u)
{
GSVector4i v = GSVector4i::load((int)u);
+71 -44
View File
@@ -13,8 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "GS_types.h"
class alignas(16) GSVector4i
{
static const GSVector4i m_xff[17];
@@ -54,15 +52,15 @@ public:
struct { int r, g, b, a; };
struct { int left, top, right, bottom; };
int v[4];
float f32[4];
int8 i8[16];
int16 i16[8];
int32 i32[4];
int64 i64[2];
uint8 u8[16];
uint16 u16[8];
uint32 u32[4];
uint64 u64[2];
float F32[4];
s8 I8[16];
s16 I16[8];
s32 I32[4];
s64 I64[2];
u8 U8[16];
u16 U16[8];
u32 U32[4];
u64 U64[2];
__m128i m;
};
@@ -234,13 +232,9 @@ public:
return sat_i32(a);
}
template <int mode>
__forceinline GSVector4i ralign(const GSVector2i& a) const
template <Align_Mode mode>
GSVector4i _ralign_helper(const GSVector4i& mask) const
{
// a must be 1 << n
GSVector4i mask = GSVector4i(a) - GSVector4i(1, 1);
GSVector4i v;
switch (mode)
@@ -248,13 +242,28 @@ public:
case Align_Inside: v = *this + mask; break;
case Align_Outside: v = *this + mask.zwxy(); break;
case Align_NegInf: v = *this; break;
case Align_PosInf: v = *this + mask.zwzw(); break;
case Align_PosInf: v = *this + mask.xyxy(); break;
default: pxAssert(0); break;
}
return v.andnot(mask.xyxy());
}
/// Align the rect using mask values that already have one subtracted (1 << n - 1 aligns to 1 << n)
template <Align_Mode mode>
GSVector4i ralign_presub(const GSVector2i& a) const
{
return _ralign_helper<mode>(GSVector4i(a));
}
template <Align_Mode mode>
GSVector4i ralign(const GSVector2i& a) const
{
// a must be 1 << n
return _ralign_helper<mode>(GSVector4i(a) - GSVector4i(1, 1));
}
GSVector4i fit(int arx, int ary) const;
GSVector4i fit(int preset) const;
@@ -275,14 +284,14 @@ public:
//
__forceinline uint32 rgba32() const
__forceinline u32 rgba32() const
{
GSVector4i v = *this;
v = v.ps32(v);
v = v.pu16(v);
return (uint32)store(v);
return (u32)store(v);
}
__forceinline GSVector4i sat_i8(const GSVector4i& a, const GSVector4i& b) const
@@ -426,15 +435,19 @@ public:
return GSVector4i(_mm_blend_epi16(m, a, mask));
}
#if _M_SSE >= 0x501
template <int mask>
__forceinline GSVector4i blend32(const GSVector4i& v) const
{
#if _M_SSE >= 0x501
return GSVector4i(_mm_blend_epi32(m, v.m, mask));
}
#else
constexpr int bit3 = ((mask & 8) * 3) << 3;
constexpr int bit2 = ((mask & 4) * 3) << 2;
constexpr int bit1 = ((mask & 2) * 3) << 1;
constexpr int bit0 = (mask & 1) * 3;
return blend16<bit3 | bit2 | bit1 | bit0>(v);
#endif
}
__forceinline GSVector4i blend(const GSVector4i& a, const GSVector4i& mask) const
{
@@ -698,6 +711,13 @@ public:
return GSVector4i(_mm_sra_epi32(m, i));
}
#if _M_SSE >= 0x501
__forceinline GSVector4i srav32(const GSVector4i& v) const
{
return GSVector4i(_mm_srav_epi32(m, v.m));
}
#endif
__forceinline GSVector4i sll16(int i) const
{
return GSVector4i(_mm_slli_epi16(m, i));
@@ -719,9 +739,9 @@ public:
}
#if _M_SSE >= 0x501
__forceinline GSVector4i sllv32(__m128i i) const
__forceinline GSVector4i sllv32(const GSVector4i& v) const
{
return GSVector4i(_mm_sllv_epi32(m, i));
return GSVector4i(_mm_sllv_epi32(m, v.m));
}
#endif
@@ -756,9 +776,9 @@ public:
}
#if _M_SSE >= 0x501
__forceinline GSVector4i srlv32(__m128i i) const
__forceinline GSVector4i srlv32(const GSVector4i& v) const
{
return GSVector4i(_mm_srlv_epi32(m, i));
return GSVector4i(_mm_srlv_epi32(m, v.m));
}
#endif
@@ -1051,13 +1071,13 @@ public:
#ifdef _M_AMD64
template <int i>
__forceinline GSVector4i insert64(int64 a) const
__forceinline GSVector4i insert64(s64 a) const
{
return GSVector4i(_mm_insert_epi64(m, a, i));
}
template <int i>
__forceinline int64 extract64() const
__forceinline s64 extract64() const
{
if (i == 0)
return GSVector4i::storeq(*this);
@@ -1299,8 +1319,8 @@ public:
{
GSVector4i v;
v = loadq((int64)ptr[extract8<src + 0>() & 0xf]);
v = v.insert64<1>((int64)ptr[extract8<src + 0>() >> 4]);
v = loadq((s64)ptr[extract8<src + 0>() & 0xf]);
v = v.insert64<1>((s64)ptr[extract8<src + 0>() >> 4]);
return v;
}
@@ -1310,8 +1330,8 @@ public:
{
GSVector4i v;
v = loadq((int64)ptr[extract8<src + 0>()]);
v = v.insert64<1>((int64)ptr[extract8<src + 1>()]);
v = loadq((s64)ptr[extract8<src + 0>()]);
v = v.insert64<1>((s64)ptr[extract8<src + 1>()]);
return v;
}
@@ -1321,8 +1341,8 @@ public:
{
GSVector4i v;
v = loadq((int64)ptr[extract16<src + 0>()]);
v = v.insert64<1>((int64)ptr[extract16<src + 1>()]);
v = loadq((s64)ptr[extract16<src + 0>()]);
v = v.insert64<1>((s64)ptr[extract16<src + 1>()]);
return v;
}
@@ -1332,8 +1352,8 @@ public:
{
GSVector4i v;
v = loadq((int64)ptr[extract32<src + 0>()]);
v = v.insert64<1>((int64)ptr[extract32<src + 1>()]);
v = loadq((s64)ptr[extract32<src + 0>()]);
v = v.insert64<1>((s64)ptr[extract32<src + 1>()]);
return v;
}
@@ -1343,8 +1363,8 @@ public:
{
GSVector4i v;
v = loadq((int64)ptr[extract64<0>()]);
v = v.insert64<1>((int64)ptr[extract64<1>()]);
v = loadq((s64)ptr[extract64<0>()]);
v = v.insert64<1>((s64)ptr[extract64<1>()]);
return v;
}
@@ -1400,7 +1420,7 @@ public:
dst[1] = gather8_4<8>(ptr);
}
__forceinline void gather8_8(const uint8* RESTRICT ptr, GSVector4i* RESTRICT dst) const
__forceinline void gather8_8(const u8* RESTRICT ptr, GSVector4i* RESTRICT dst) const
{
dst[0] = gather8_8<>(ptr);
}
@@ -1568,7 +1588,7 @@ public:
#ifdef _M_AMD64
__forceinline static GSVector4i loadq(int64 i)
__forceinline static GSVector4i loadq(s64 i)
{
return GSVector4i(_mm_cvtsi64_si128(i));
}
@@ -1612,7 +1632,7 @@ public:
#ifdef _M_AMD64
__forceinline static int64 storeq(const GSVector4i& v)
__forceinline static s64 storeq(const GSVector4i& v)
{
return _mm_cvtsi128_si64(v.m);
}
@@ -1648,7 +1668,14 @@ public:
__forceinline static void transpose(GSVector4i& a, GSVector4i& b, GSVector4i& c, GSVector4i& d)
{
_MM_TRANSPOSE4_SI128(a.m, b.m, c.m, d.m);
__m128 tmp0 = _mm_shuffle_ps(_mm_castsi128_ps(a.m), _mm_castsi128_ps(b.m), 0x44);
__m128 tmp2 = _mm_shuffle_ps(_mm_castsi128_ps(a.m), _mm_castsi128_ps(b.m), 0xEE);
__m128 tmp1 = _mm_shuffle_ps(_mm_castsi128_ps(c.m), _mm_castsi128_ps(d.m), 0x44);
__m128 tmp3 = _mm_shuffle_ps(_mm_castsi128_ps(c.m), _mm_castsi128_ps(d.m), 0xEE);
a = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0x88));
b = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0xDD));
c = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0x88));
d = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0xDD));
}
__forceinline static void sw4(GSVector4i& a, GSVector4i& b, GSVector4i& c, GSVector4i& d)
+10 -10
View File
@@ -59,15 +59,15 @@ public:
struct { float x0, y0, z0, w0, x1, y1, z1, w1; };
struct { float r0, g0, b0, a0, r1, g1, b1, a1; };
float v[8];
float f32[8];
int8 i8[32];
int16 i16[16];
int32 i32[8];
int64 i64[4];
uint8 u8[32];
uint16 u16[16];
uint32 u32[8];
uint64 u64[4];
float F32[8];
s8 I8[32];
s16 I16[16];
s32 I32[8];
s64 I64[4];
u8 U8[32];
u16 U16[16];
u32 U32[8];
u64 U64[4];
__m256 m;
__m128 m0, m1;
};
@@ -103,7 +103,7 @@ public:
return GSVector8(cxpr_setr_epi32(x, x, x, x, x, x, x, x));
}
static constexpr GSVector8 cxpr(uint32 x)
static constexpr GSVector8 cxpr(u32 x)
{
return cxpr(static_cast<int>(x));
}
+18 -18
View File
@@ -69,15 +69,15 @@ public:
struct { int x0, y0, z0, w0, x1, y1, z1, w1; };
struct { int r0, g0, b0, a0, r1, g1, b1, a1; };
int v[8];
float f32[8];
int8 i8[32];
int16 i16[16];
int32 i32[8];
int64 i64[4];
uint8 u8[32];
uint16 u16[16];
uint32 u32[8];
uint64 u64[4];
float F32[8];
s8 I8[32];
s16 I16[16];
s32 I32[8];
s64 I64[4];
u8 U8[32];
u16 U16[16];
u32 U32[8];
u64 U64[4];
__m256i m;
__m128i m0, m1;
};
@@ -1055,17 +1055,17 @@ public:
return cast(v0).insert<1>(v1);
}
__forceinline GSVector8i gather32_32(const uint8* ptr) const
__forceinline GSVector8i gather32_32(const u8* ptr) const
{
return GSVector8i(_mm256_i32gather_epi32((const int*)ptr, m, 1)) & GSVector8i::x000000ff();
}
__forceinline GSVector8i gather32_32(const uint16* ptr) const
__forceinline GSVector8i gather32_32(const u16* ptr) const
{
return GSVector8i(_mm256_i32gather_epi32((const int*)ptr, m, 2)) & GSVector8i::x0000ffff();
}
__forceinline GSVector8i gather32_32(const uint32* ptr) const
__forceinline GSVector8i gather32_32(const u32* ptr) const
{
return GSVector8i(_mm256_i32gather_epi32((const int*)ptr, m, 4));
}
@@ -1092,14 +1092,14 @@ public:
return cast(v0).insert<1>(v1);
}
__forceinline GSVector8i gather32_32(const uint8* ptr1, const uint32* ptr2) const
__forceinline GSVector8i gather32_32(const u8* ptr1, const u32* ptr2) const
{
return gather32_32<uint8>(ptr1).gather32_32<uint32>(ptr2);
return gather32_32<u8>(ptr1).gather32_32<u32>(ptr2);
}
__forceinline GSVector8i gather32_32(const uint32* ptr1, const uint32* ptr2) const
__forceinline GSVector8i gather32_32(const u32* ptr1, const u32* ptr2) const
{
return gather32_32<uint32>(ptr1).gather32_32<uint32>(ptr2);
return gather32_32<u32>(ptr1).gather32_32<u32>(ptr2);
}
template <class T>
@@ -1169,7 +1169,7 @@ public:
#ifdef _M_AMD64
__forceinline static GSVector8i loadq(int64 i)
__forceinline static GSVector8i loadq(s64 i)
{
return cast(GSVector4i::loadq(i));
}
@@ -1213,7 +1213,7 @@ public:
#ifdef _M_AMD64
__forceinline static int64 storeq(const GSVector8i& v)
__forceinline static s64 storeq(const GSVector8i& v)
{
return GSVector4i::storeq(GSVector4i::cast(v));
}
-130
View File
@@ -1,130 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned long long uint64;
typedef signed long long int64;
typedef signed long long sint64;
// Makes sure that if anyone includes xbyak, it doesn't do anything bad
#define MIE_INTEGER_TYPE_DEFINED
#define XBYAK_ENABLE_OMITTED_OPERAND
#include <cfloat>
// clang-format off
#ifndef RESTRICT
#ifdef __INTEL_COMPILER
#define RESTRICT restrict
#elif defined(_MSC_VER)
#define RESTRICT __restrict
#elif defined(__GNUC__)
#define RESTRICT __restrict__
#else
#define RESTRICT
#endif
#endif
#ifdef _WIN32
inline std::string convert_utf16_to_utf8(const std::wstring& utf16_string)
{
const int size = WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), nullptr, 0, nullptr, nullptr);
std::string converted_string(size, 0);
WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), converted_string.data(), converted_string.size(), nullptr, nullptr);
return converted_string;
}
inline std::wstring convert_utf8_to_utf16(const std::string& utf8_string)
{
int size = MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, nullptr, 0);
std::vector<wchar_t> converted_string(size);
MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, converted_string.data(), converted_string.size());
return {converted_string.data()};
}
#endif
// _wfopen has to be used on Windows for pathnames containing non-ASCII characters.
inline FILE* px_fopen(const std::string& filename, const std::string& mode)
{
#ifdef _WIN32
return _wfopen(convert_utf8_to_utf16(filename).c_str(), convert_utf8_to_utf16(mode).c_str());
#else
return fopen(filename.c_str(), mode.c_str());
#endif
}
#define _MM_TRANSPOSE4_SI128(row0, row1, row2, row3) \
{ \
__m128 tmp0 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0x44); \
__m128 tmp2 = _mm_shuffle_ps(_mm_castsi128_ps(row0), _mm_castsi128_ps(row1), 0xEE); \
__m128 tmp1 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0x44); \
__m128 tmp3 = _mm_shuffle_ps(_mm_castsi128_ps(row2), _mm_castsi128_ps(row3), 0xEE); \
(row0) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0x88)); \
(row1) = _mm_castps_si128(_mm_shuffle_ps(tmp0, tmp1, 0xDD)); \
(row2) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0x88)); \
(row3) = _mm_castps_si128(_mm_shuffle_ps(tmp2, tmp3, 0xDD)); \
}
extern void* vmalloc(size_t size, bool code);
extern void vmfree(void* ptr, size_t size);
#define countof(a) (sizeof(a) / sizeof(a[0]))
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifdef __cpp_constinit
#define CONSTINIT constinit
#elif __has_attribute(require_constant_initialization)
#define CONSTINIT __attribute__((require_constant_initialization))
#else
#define CONSTINIT
#endif
#define ASSERT assert
// sse
#if defined(__GNUC__)
// Convert gcc see define into GS (windows) define
#if defined(__AVX2__)
#if defined(__x86_64__)
#define _M_SSE 0x500 // TODO
#else
#define _M_SSE 0x501
#endif
#elif defined(__AVX__)
#define _M_SSE 0x500
#elif defined(__SSE4_1__)
#define _M_SSE 0x401
#else
#error PCSX2 requires compiling for at least SSE 4.1
#endif
#elif _M_SSE < 0x401
#error PCSX2 requires compiling for at least SSE 4.1
#endif
+6 -5
View File
@@ -14,8 +14,9 @@
*/
#include "PrecompiledHeader.h"
#include "GS/GS.h"
#include "GSDevice.h"
#include "GS/GSGL.h"
#include "GS/GS.h"
GSDevice::GSDevice()
: m_vsync(false)
@@ -126,7 +127,7 @@ GSTexture* GSDevice::FetchSurface(int type, int w, int h, int format)
void GSDevice::PrintMemoryUsage()
{
#ifdef ENABLE_OGL_DEBUG
uint32 pool = 0;
u32 pool = 0;
for (auto t : m_pool)
{
if (t)
@@ -242,7 +243,7 @@ void GSDevice::Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, con
{
GSTexture* tex[3] = {NULL, NULL, NULL};
for (size_t i = 0; i < countof(tex); i++)
for (size_t i = 0; i < std::size(tex); i++)
{
if (sTex[i] != NULL)
{
@@ -252,7 +253,7 @@ void GSDevice::Merge(GSTexture* sTex[3], GSVector4* sRect, GSVector4* dRect, con
DoMerge(tex, sRect, m_merge, dRect, PMODE, EXTBUF, c);
for (size_t i = 0; i < countof(tex); i++)
for (size_t i = 0; i < std::size(tex); i++)
{
if (tex[i] != sTex[i])
{
@@ -422,7 +423,7 @@ HWBlend GSDevice::GetBlend(size_t index)
return blend;
}
uint16 GSDevice::GetBlendFlags(size_t index) { return m_blendMap[index].flags; }
u16 GSDevice::GetBlendFlags(size_t index) { return m_blendMap[index].flags; }
// clang-format off
+14 -10
View File
@@ -21,6 +21,10 @@
#include "GSVertex.h"
#include "GS/GSAlignedClass.h"
#include "GSOsdManager.h"
#include <array>
#ifdef _WIN32
#include <dxgi.h>
#endif
enum ShaderConvert
{
@@ -120,7 +124,7 @@ enum HWBlendFlags
// Determines the HW blend function for DX11/OGL
struct HWBlend
{
uint16 flags, op, src, dst;
u16 flags, op, src, dst;
};
class GSDevice : public GSAlignedClass<32>
@@ -130,7 +134,7 @@ private:
static std::array<HWBlend, 3*3*3*3 + 1> m_blendMap;
protected:
enum : uint16
enum : u16
{
// HW blend factors
SRC_COLOR, INV_SRC_COLOR, DST_COLOR, INV_DST_COLOR,
@@ -172,7 +176,7 @@ protected:
virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {}
virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) {}
virtual void DoExternalFX(GSTexture* sTex, GSTexture* dTex) {}
virtual uint16 ConvertBlendEnum(uint16 generic) = 0; // Convert blend factors/ops from the generic enum to DX11/OGl specific.
virtual u16 ConvertBlendEnum(u16 generic) = 0; // Convert blend factors/ops from the generic enum to DX11/OGl specific.
public:
GSOsdManager m_osd;
@@ -208,9 +212,9 @@ public:
virtual bool HasColorSparse() { return false; }
virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) {}
virtual void ClearRenderTarget(GSTexture* t, uint32 c) {}
virtual void ClearRenderTarget(GSTexture* t, u32 c) {}
virtual void ClearDepth(GSTexture* t) {}
virtual void ClearStencil(GSTexture* t, uint8 c) {}
virtual void ClearStencil(GSTexture* t, u8 c) {}
GSTexture* CreateSparseRenderTarget(int w, int h, int format = 0);
GSTexture* CreateSparseDepthStencil(int w, int h, int format = 0);
@@ -257,15 +261,15 @@ public:
// Convert the GS blend equations to HW specific blend factors/ops
// Index is computed as ((((A * 3 + B) * 3) + C) * 3) + D. A, B, C, D taken from ALPHA register.
HWBlend GetBlend(size_t index);
uint16 GetBlendFlags(size_t index);
u16 GetBlendFlags(size_t index);
};
struct GSAdapter
{
uint32 vendor;
uint32 device;
uint32 subsys;
uint32 rev;
u32 vendor;
u32 device;
u32 subsys;
u32 rev;
operator std::string() const;
bool operator==(const GSAdapter&) const;

Some files were not shown because too many files have changed in this diff Show More