Compare commits

...
159 Commits
Author SHA1 Message Date
Mrlinkwiiandrefractionpcsx2 cca52e271b Gamedb: add 'VIFFIFOHack' to 'Men in Black II: Alien Escape' 2021-12-02 19:29:28 +00:00
TellowKrinkleandlightningterror a2e15bbc87 GHActions:macos: Install glib
Looks like GHActions changed what things they preinstall
2021-12-02 15:08:18 +01:00
Mrlinkwiiandrefractionpcsx2 9d6ad0303c GameDB: Add fixes for 'Shadow Man - 2econd Coming' and 'Ghosthunter' games. 2021-12-02 14:01:47 +00:00
Mrlinkwiiandrefractionpcsx2 bbaa23c22d Readme : update links 2021-12-01 22:43:36 +00:00
ZiemasandGitHub bacb860cc1 GUI: Allow relative elf file paths on command line. (#4451) 2021-11-30 10:06:17 +01:00
Ziemasandrefractionpcsx2 7a4191e16d Fix compilation with LTO on GCC 2021-11-30 02:25:06 +00:00
PCSX2 Botandlightningterror 0fa620e3ba pad-linux: Update to latest controller database. 2021-11-29 17:17:26 +01:00
dependabot[bot]andlightningterror 96642d8bc3 Bump mathieudutour/github-tag-action from 5.6 to 6.0
Bumps [mathieudutour/github-tag-action](https://github.com/mathieudutour/github-tag-action) from 5.6 to 6.0.
- [Release notes](https://github.com/mathieudutour/github-tag-action/releases)
- [Commits](https://github.com/mathieudutour/github-tag-action/compare/v5.6...v6.0)

---
updated-dependencies:
- dependency-name: mathieudutour/github-tag-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 16:01:55 +01:00
dependabot[bot]andrefractionpcsx2 8a26c3783a Bump actions/cache from 2.1.6 to 2.1.7
Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2.1.6...v2.1.7)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 13:21:27 +00:00
lightningterror d2742a177c GS-d3d11: Properly set afix in EmulateBlending.
Accumulation blend -> afix is already handled in shader, no need to set it for hw blending too.
SW blending -> done in shader.
HW blending - > set only when it is actually used, Alpha C.

GS-d3d11: Properly set afix in EmulateBlending.

Accumulation blend -> afix is already handled in shader, no need to set it for hw blending too.
SW blending -> done in shader.
HW blending - > set only when it is actually used, Alpha C.
2021-11-26 21:25:16 +01:00
TellowKrinkleandtellowkrinkle 6d4713e069 GS: Alloc sw renderer things on custom heap 2021-11-26 13:44:07 -06:00
TellowKrinkleandtellowkrinkle 342170b077 GS: Add new heap for SW renderer allocations 2021-11-26 13:44:07 -06:00
TellowKrinkleandtellowkrinkle df02d784d6 GS: Throw from vmalloc on failure 2021-11-26 13:44:07 -06:00
tellowkrinkle 340874996e CMake: Always default CMAKE_BUILD_PO off
Git files getting modified by build is just as much of a pain in release builds as it is in devel builds
2021-11-26 13:02:25 -06:00
lightningterrorandrefractionpcsx2 3bd89154d3 GS-wx: Fix some gui interaction.
Fix interaction of Anisotropic filtering with Nearest Texture Filtering and GPU Palette Conversion.
Fix interaction of Trilinear Filtering with selected renderer.

Options should gray out properly now.
2021-11-26 18:32:58 +00:00
Connor McLaughlinandlightningterror 1e198fbb83 GS/OpenGL: Use CreateRenderTarget() for temp HDR target
Probably won't change much, except maybe with sparse textures,
where it'll use less video memory.
2021-11-25 23:26:31 +01:00
TellowKrinkleandtellowkrinkle 01855fc66a GHActions: Don't shallow clone submodules
Shallow clones tend to be 5-10s slower
2021-11-24 15:43:56 -06:00
refractionpcsx2 7ac045b5e2 GS: Partial revert of #5061 2021-11-24 01:01:55 +00:00
lightningterror 03f1617ff5 GS-GSState: Mask out AA1 on triangles.
AA1 is not supported on hw renderers so ignore flushing the prims on triangles.

Should provide a nice speed boost on games that use AA1 on triangle prims.
2021-11-24 00:14:03 +01:00
lightningterror c75b20e37d GS-hw: Also disable Blending when AA1 and ABE or PABE are both set on lines.
There's no need to blend them since there is no implementation.
2021-11-24 00:14:03 +01:00
lightningterror 08f72596d4 GS-hw: EmulateBlending move early return to the top.
Optimization.
2021-11-24 00:14:03 +01:00
lightningterror dcd1f90ae7 GS-hw: Disable Z writes on AA1 flag when prim are lines.
When AA1 flag is enabled Z is not written on lines since coverage is always less than 0x80.
2021-11-24 00:14:03 +01:00
lightningterror c10603d161 GS-hw: Disable alpha blending when only AA1 flag is enabled.
There is no hw implementation of AA1.

Alpha blending shouldn't be enabled by AA1 flag, only ABE and PABE flags.
2021-11-24 00:14:03 +01:00
Mrlinkwiiandrefractionpcsx2 7ea335e59b GameDB : fix Fuuraiki 2 patch 2021-11-23 11:55:23 +00:00
lightningterror d20cb91d90 Gs-d3d11:fx: Adjust sw blend shader a bit.
Use As and Cs in pabe code, makes more sense.

Get rid of Cv vector, use Color parameter for operations instead like on gl.
2021-11-23 09:02:54 +01:00
lightningterror e38d754e86 Gs-ogl:glsl: Adjust sw blend shader a bit.
Get rid of Color_pabe vector, makes more sense to use As and Cs in pabe code.
2021-11-23 09:02:54 +01:00
refractionpcsx2 afacc47f33 CDVD: Adjust DMA timing based on PS1 timings.
Bus width is 16bit on the PS2 and 8bit on PS1, so serves to reason the DMA would be twice the speed. (PS1 is 24 cycle per word)
2021-11-22 22:18:32 +00:00
refractionpcsx2 5803cc441e GS: Improve FixedTEX0 accuracy 2021-11-22 22:17:59 +00:00
Mrlinkwiiandrefractionpcsx2 d60c66deee GameDB: purge patches for 'Knockout Kings 2002' 2021-11-22 21:42:26 +00:00
PCSX2 Botandlightningterror d7797a50f5 pad-linux: Update to latest controller database. 2021-11-22 20:55:52 +01:00
Mrlinkwiiandrefractionpcsx2 87bbebed36 Gamedb: remove the patch for Virtua Fighter 4 2021-11-22 17:51:51 +00:00
Mrlinkwiiandrefractionpcsx2 3aa33bf0b1 Gamedb :add 'GIFFIFOHack' to 'FIFA 2005'and EE clamping for 'D1 Professional Drift Grand Prix Series 2005' 2021-11-22 15:41:25 +00:00
Christian Kennyandrefractionpcsx2 e37afd6976 3rdparty: Upgrade soundtouch lib to 2.3.1 2021-11-22 15:38:03 +00:00
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
352 changed files with 18229 additions and 28474 deletions
+1 -1
View File
@@ -118,7 +118,7 @@ jobs:
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v2.1.6
uses: actions/cache@v2.1.7
with:
path: .ccache
key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
+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 wxwidgets sdl2 libsamplerate glib
}
if ! do-install; then
brew update
@@ -33,7 +33,7 @@ jobs:
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
- name: Bump Version and Push Tag
id: tag_version
uses: mathieudutour/github-tag-action@v5.6
uses: mathieudutour/github-tag-action@v6.0
with:
github_token: ${{ secrets.BOT_PAT }}
tag_prefix: v
@@ -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
View File
@@ -1,23 +1,18 @@
[submodule "3rdparty/xz/xz"]
path = 3rdparty/xz/xz
url = https://github.com/PCSX2/xz.git
shallow = true
[submodule "3rdparty/gtest"]
path = 3rdparty/gtest
url = https://github.com/google/googletest.git
shallow = true
[submodule "3rdparty/fmt/fmt"]
path = 3rdparty/fmt/fmt
url = https://github.com/fmtlib/fmt.git
shallow = true
[submodule "3rdparty/yaml-cpp/yaml-cpp"]
path = 3rdparty/yaml-cpp/yaml-cpp
url = https://github.com/jbeder/yaml-cpp.git
shallow = true
[submodule "3rdparty/libchdr/libchdr"]
path = 3rdparty/libchdr/libchdr
url = https://github.com/rtissera/libchdr.git
shallow = true
[submodule "3rdparty/wil"]
path = 3rdparty/wil
url = https://github.com/microsoft/wil.git
+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)
/*----------------------------------------------------------------------------
+2 -2
View File
@@ -2,7 +2,7 @@
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -117,7 +117,7 @@ be combined with the library in order to run.
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authoried party saying it may be distributed under the terms of
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
+949 -877
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -170,6 +170,9 @@ public:
/// allow trimming (downwards) amount of samples in pipeline.
/// Returns adjusted amount of samples
uint adjustAmountOfSamples(uint numSamples);
/// Add silence to end of buffer
void addSilent(uint nSamples);
};
}
+14 -7
View File
@@ -121,10 +121,10 @@ namespace soundtouch
#endif
// If defined, allows the SIMD-optimized routines to take minor shortcuts
// for improved performance. Undefine to require faithfully similar SIMD
// calculations as in normal C implementation.
#define SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
// If defined, allows the SIMD-optimized routines to skip unevenly aligned
// memory offsets that can cause performance penalty in some SIMD implementations.
// Causes slight compromise in sound quality.
// #define SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
@@ -149,8 +149,9 @@ namespace soundtouch
// floating point samples
typedef float SAMPLETYPE;
// data type for sample accumulation: Use double to utilize full precision.
typedef double LONG_SAMPLETYPE;
// data type for sample accumulation: Use float also here to enable
// efficient autovectorization
typedef float LONG_SAMPLETYPE;
#ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
// Allow SSE optimizations
@@ -159,7 +160,13 @@ namespace soundtouch
#endif // SOUNDTOUCH_INTEGER_SAMPLES
};
#if ((SOUNDTOUCH_ALLOW_SSE) || (__SSE__) || (SOUNDTOUCH_USE_NEON))
#if SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
#define ST_SIMD_AVOID_UNALIGNED
#endif
#endif
}
// define ST_NO_EXCEPTION_HANDLING switch to disable throwing std exceptions:
// #define ST_NO_EXCEPTION_HANDLING 1
+2 -2
View File
@@ -72,10 +72,10 @@ namespace soundtouch
{
/// Soundtouch library version string
#define SOUNDTOUCH_VERSION "2.1.2"
#define SOUNDTOUCH_VERSION "2.3.1"
/// SoundTouch library version id
#define SOUNDTOUCH_VERSION_ID (20102)
#define SOUNDTOUCH_VERSION_ID (20301)
//
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
+3 -4
View File
@@ -313,7 +313,7 @@ void BPMDetect::updateXCorr(int process_samples)
#pragma omp parallel for
for (offs = windowStart; offs < windowLen; offs ++)
{
double sum;
float sum;
int i;
sum = 0;
@@ -341,7 +341,6 @@ void BPMDetect::updateBeatPos(int process_samples)
// static double thr = 0.0003;
double posScale = (double)this->decimateBy / (double)this->sampleRate;
int resetDur = (int)(0.12 / posScale + 0.5);
double corrScale = 1.0 / (double)(windowLen - windowStart);
// prescale pbuffer
float tmp[XCORR_UPDATE_SEQUENCE / 2];
@@ -353,7 +352,7 @@ void BPMDetect::updateBeatPos(int process_samples)
#pragma omp parallel for
for (int offs = windowStart; offs < windowLen; offs++)
{
double sum = 0;
float sum = 0;
for (int i = 0; i < process_samples; i++)
{
sum += tmp[i] * pBuffer[offs + i];
@@ -562,7 +561,7 @@ float BPMDetect::getBpm()
/// \return number of beats in the arrays.
int BPMDetect::getBeats(float *pos, float *values, int max_num)
{
int num = beats.size();
int num = (int)beats.size();
if ((!pos) || (!values)) return num; // pos or values NULL, return just size
for (int i = 0; (i < num) && (i < max_num); i++)
@@ -265,3 +265,11 @@ uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
}
return samplesInBuffer;
}
/// Add silence to end of buffer
void FIFOSampleBuffer::addSilent(uint nSamples)
{
memset(ptrEnd(nSamples), 0, sizeof(SAMPLETYPE) * nSamples * channels);
samplesInBuffer += nSamples;
}
+44 -39
View File
@@ -60,12 +60,14 @@ FIRFilter::FIRFilter()
length = 0;
lengthDiv8 = 0;
filterCoeffs = NULL;
filterCoeffsStereo = NULL;
}
FIRFilter::~FIRFilter()
{
delete[] filterCoeffs;
delete[] filterCoeffsStereo;
}
@@ -78,35 +80,26 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
// because division is much slower operation than multiplying.
double dScaler = 1.0 / (double)resultDivider;
#endif
// hint compiler autovectorization that loop length is divisible by 8
int ilength = length & -8;
assert(length != 0);
assert(src != NULL);
assert(dest != NULL);
assert(filterCoeffs != NULL);
assert((length != 0) && (length == ilength) && (src != NULL) && (dest != NULL) && (filterCoeffs != NULL));
end = 2 * (numSamples - length);
end = 2 * (numSamples - ilength);
#pragma omp parallel for
for (j = 0; j < end; j += 2)
{
const SAMPLETYPE *ptr;
LONG_SAMPLETYPE suml, sumr;
uint i;
suml = sumr = 0;
ptr = src + j;
for (i = 0; i < length; i += 4)
for (int i = 0; i < ilength; i ++)
{
// loop is unrolled by factor of 4 here for efficiency
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
ptr[2 * i + 2] * filterCoeffs[i + 1] +
ptr[2 * i + 4] * filterCoeffs[i + 2] +
ptr[2 * i + 6] * filterCoeffs[i + 3];
sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
ptr[2 * i + 3] * filterCoeffs[i + 1] +
ptr[2 * i + 5] * filterCoeffs[i + 2] +
ptr[2 * i + 7] * filterCoeffs[i + 3];
suml += ptr[2 * i] * filterCoeffsStereo[2 * i];
sumr += ptr[2 * i + 1] * filterCoeffsStereo[2 * i + 1];
}
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
@@ -116,14 +109,11 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
// saturate to 16 bit integer limits
sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
#else
suml *= dScaler;
sumr *= dScaler;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[j] = (SAMPLETYPE)suml;
dest[j + 1] = (SAMPLETYPE)sumr;
}
return numSamples - length;
return numSamples - ilength;
}
@@ -137,31 +127,28 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
double dScaler = 1.0 / (double)resultDivider;
#endif
assert(length != 0);
// hint compiler autovectorization that loop length is divisible by 8
int ilength = length & -8;
end = numSamples - length;
assert(ilength != 0);
end = numSamples - ilength;
#pragma omp parallel for
for (j = 0; j < end; j ++)
for (j = 0; j < end; j ++)
{
const SAMPLETYPE *pSrc = src + j;
LONG_SAMPLETYPE sum;
uint i;
int i;
sum = 0;
for (i = 0; i < length; i += 4)
for (i = 0; i < ilength; i ++)
{
// loop is unrolled by factor of 4 here for efficiency
sum += pSrc[i + 0] * filterCoeffs[i + 0] +
pSrc[i + 1] * filterCoeffs[i + 1] +
pSrc[i + 2] * filterCoeffs[i + 2] +
pSrc[i + 3] * filterCoeffs[i + 3];
sum += pSrc[i] * filterCoeffs[i];
}
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
sum >>= resultDivFactor;
// saturate to 16 bit integer limits
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
#else
sum *= dScaler;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[j] = (SAMPLETYPE)sum;
}
@@ -185,14 +172,18 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
assert(filterCoeffs != NULL);
assert(numChannels < 16);
end = numChannels * (numSamples - length);
// hint compiler autovectorization that loop length is divisible by 8
int ilength = length & -8;
end = numChannels * (numSamples - ilength);
#pragma omp parallel for
for (j = 0; j < end; j += numChannels)
{
const SAMPLETYPE *ptr;
LONG_SAMPLETYPE sums[16];
uint c, i;
uint c;
int i;
for (c = 0; c < numChannels; c ++)
{
@@ -201,7 +192,7 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
ptr = src + j;
for (i = 0; i < length; i ++)
for (i = 0; i < ilength; i ++)
{
SAMPLETYPE coef=filterCoeffs[i];
for (c = 0; c < numChannels; c ++)
@@ -215,13 +206,11 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
{
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
sums[c] >>= resultDivFactor;
#else
sums[c] *= dScaler;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[j+c] = (SAMPLETYPE)sums[c];
}
}
return numSamples - length;
return numSamples - ilength;
}
@@ -233,6 +222,13 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
assert(newLength > 0);
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
// scale coefficients already here if using floating samples
double scale = 1.0 / resultDivider;
#else
short scale = 1;
#endif
lengthDiv8 = newLength / 8;
length = lengthDiv8 * 8;
assert(length == newLength);
@@ -242,7 +238,16 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
delete[] filterCoeffs;
filterCoeffs = new SAMPLETYPE[length];
memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
delete[] filterCoeffsStereo;
filterCoeffsStereo = new SAMPLETYPE[length*2];
for (uint i = 0; i < length; i ++)
{
filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale);
// create also stereo set of filter coefficients: this allows compiler
// to autovectorize filter evaluation much more efficiently
filterCoeffsStereo[2 * i] = (SAMPLETYPE)(coeffs[i] * scale);
filterCoeffsStereo[2 * i + 1] = (SAMPLETYPE)(coeffs[i] * scale);
}
}
+1
View File
@@ -57,6 +57,7 @@ protected:
// Memory for filter coefficients
SAMPLETYPE *filterCoeffs;
SAMPLETYPE *filterCoeffsStereo;
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
+7 -1
View File
@@ -41,7 +41,6 @@ namespace soundtouch
class InterpolateCubic : public TransposerBase
{
protected:
virtual void resetRegisters();
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
@@ -56,6 +55,13 @@ protected:
public:
InterpolateCubic();
virtual void resetRegisters();
int getLatency() const
{
return 1;
}
};
}
@@ -142,7 +142,7 @@ int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE
LONG_SAMPLETYPE temp, vol1;
assert(iFract < SCALE);
vol1 = (SCALE - iFract);
vol1 = (LONG_SAMPLETYPE)(SCALE - iFract);
for (int c = 0; c < numChannels; c ++)
{
temp = vol1 * src[c] + iFract * src[c + numChannels];
+14 -4
View File
@@ -45,8 +45,6 @@ protected:
int iFract;
int iRate;
virtual void resetRegisters();
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
@@ -60,6 +58,13 @@ public:
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// rate, larger faster rates.
virtual void setRate(double newRate);
virtual void resetRegisters();
int getLatency() const
{
return 0;
}
};
@@ -69,8 +74,6 @@ class InterpolateLinearFloat : public TransposerBase
protected:
double fract;
virtual void resetRegisters();
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
@@ -81,6 +84,13 @@ protected:
public:
InterpolateLinearFloat();
virtual void resetRegisters();
int getLatency() const
{
return 0;
}
};
}
+7 -1
View File
@@ -46,7 +46,6 @@ namespace soundtouch
class InterpolateShannon : public TransposerBase
{
protected:
void resetRegisters();
int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
@@ -61,6 +60,13 @@ protected:
public:
InterpolateShannon();
void resetRegisters();
int getLatency() const
{
return 3;
}
};
}
+3 -3
View File
@@ -57,7 +57,7 @@ int PeakFinder::findTop(const float *data, int peakpos) const
refvalue = data[peakpos];
// seek within 10 points
// seek within ±10 points
start = peakpos - 10;
if (start < minPos) start = minPos;
end = peakpos + 10;
@@ -142,7 +142,7 @@ int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, i
peaklevel = data[peakpos];
assert(peaklevel >= level);
pos = peakpos;
while ((pos >= minPos) && (pos < maxPos))
while ((pos >= minPos) && (pos + direction < maxPos))
{
if (data[pos + direction] < level) return pos; // crossing found
pos += direction;
@@ -256,7 +256,7 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
// accept harmonic peak if
// (a) it is found
// (b) is within 4% of the expected harmonic interval
// (b) is within ±4% of the expected harmonic interval
// (c) has at least half x-corr value of the max. peak
double diff = harmonic * peaktmp / highPeak;
+9 -1
View File
@@ -61,6 +61,7 @@ RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
// Instantiates the anti-alias filter
pAAFilter = new AAFilter(64);
pTransposer = TransposerBase::newInstance();
clear();
}
@@ -77,6 +78,7 @@ void RateTransposer::enableAAFilter(bool newMode)
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
// Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
bUseAAFilter = newMode;
clear();
#endif
}
@@ -192,6 +194,11 @@ void RateTransposer::clear()
outputBuffer.clear();
midBuffer.clear();
inputBuffer.clear();
pTransposer->resetRegisters();
// prefill buffer to avoid losing first samples at beginning of stream
int prefill = getLatency();
inputBuffer.addSilent(prefill);
}
@@ -209,7 +216,8 @@ int RateTransposer::isEmpty() const
/// Return approximate initial input-output latency
int RateTransposer::getLatency() const
{
return (bUseAAFilter) ? pAAFilter->getLength() : 0;
return pTransposer->getLatency() +
((bUseAAFilter) ? (pAAFilter->getLength() / 2) : 0);
}
+3 -2
View File
@@ -59,8 +59,6 @@ public:
};
protected:
virtual void resetRegisters() = 0;
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples) = 0;
@@ -83,6 +81,9 @@ public:
virtual int transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src);
virtual void setRate(double newRate);
virtual void setChannels(int channels);
virtual int getLatency() const = 0;
virtual void resetRegisters() = 0;
// static factory function
static TransposerBase *newInstance();
+70 -75
View File
@@ -1,4 +1,4 @@
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
/// while maintaining the original pitch by using a time domain WSOLA-like
@@ -54,7 +54,6 @@ using namespace soundtouch;
#define max(x, y) (((x) > (y)) ? (x) : (y))
/*****************************************************************************
*
* Constant definitions
@@ -93,11 +92,6 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
bAutoSeqSetting = true;
bAutoSeekSetting = true;
maxnorm = 0;
maxnormf = 1e8;
skipFract = 0;
tempo = 1.0f;
setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
setTempo(1.0f);
@@ -203,7 +197,7 @@ void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
m1 = (SAMPLETYPE)0;
m2 = (SAMPLETYPE)overlapLength;
for (i = 0; i < overlapLength ; i ++)
for (i = 0; i < overlapLength ; i ++)
{
pOutput[i] = (pInput[i] * m1 + pMidBuffer[i] * m2 ) / overlapLength;
m1 += 1;
@@ -224,6 +218,9 @@ void TDStretch::clearInput()
inputBuffer.clear();
clearMidBuffer();
isBeginning = true;
maxnorm = 0;
maxnormf = 1e8;
skipFract = 0;
}
@@ -311,13 +308,14 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
bestCorr = (bestCorr + 0.1) * 0.75;
#pragma omp parallel for
for (i = 1; i < seekLength; i ++)
for (i = 1; i < seekLength; i ++)
{
double corr;
// Calculates correlation value for the mixing position corresponding to 'i'
#ifdef _OPENMP
#if defined(_OPENMP) || defined(ST_SIMD_AVOID_UNALIGNED)
// in parallel OpenMP mode, can't use norm accumulator version as parallel executor won't
// iterate the loop in sequential order
// in SIMD mode, avoid accumulator version to allow avoiding unaligned positions
corr = calcCrossCorr(refPos + channels * i, pMidBuffer, norm);
#else
// In non-parallel version call "calcCrossCorrAccumulate" that is otherwise same
@@ -675,23 +673,24 @@ void TDStretch::processSamples()
// Adjust processing offset at beginning of track by not perform initial overlapping
// and compensating that in the 'input buffer skip' calculation
isBeginning = false;
int skip = (int)(tempo * overlapLength + 0.5);
int skip = (int)(tempo * overlapLength + 0.5 * seekLength + 0.5);
#ifdef SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
#ifdef SOUNDTOUCH_ALLOW_SSE
// if SSE mode, round the skip amount to value corresponding to aligned memory address
if (channels == 1)
{
skip &= -4;
}
else if (channels == 2)
{
skip &= -2;
}
#endif
#ifdef ST_SIMD_AVOID_UNALIGNED
// in SIMD mode, round the skip amount to value corresponding to aligned memory address
if (channels == 1)
{
skip &= -4;
}
else if (channels == 2)
{
skip &= -2;
}
#endif
skipFract -= skip;
assert(nominalSkip >= -skipFract);
if (skipFract <= -nominalSkip)
{
skipFract = -nominalSkip;
}
}
// ... then copy sequence samples from 'inputBuffer' to output:
@@ -818,7 +817,7 @@ void TDStretch::overlapStereo(short *poutput, const short *input) const
short temp;
int cnt2;
for (i = 0; i < overlapLength ; i ++)
for (i = 0; i < overlapLength ; i ++)
{
temp = (short)(overlapLength - i);
cnt2 = 2 * i;
@@ -830,21 +829,19 @@ void TDStretch::overlapStereo(short *poutput, const short *input) const
// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Multi'
// version of the routine.
void TDStretch::overlapMulti(SAMPLETYPE *poutput, const SAMPLETYPE *input) const
void TDStretch::overlapMulti(short *poutput, const short *input) const
{
SAMPLETYPE m1=(SAMPLETYPE)0;
SAMPLETYPE m2;
int i=0;
short m1;
int i = 0;
for (m2 = (SAMPLETYPE)overlapLength; m2; m2 --)
for (m1 = 0; m1 < overlapLength; m1 ++)
{
short m2 = (short)(overlapLength - m1);
for (int c = 0; c < channels; c ++)
{
poutput[i] = (input[i] * m1 + pMidBuffer[i] * m2) / overlapLength;
i++;
}
m1++;
}
}
@@ -889,20 +886,23 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do
unsigned long lnorm;
int i;
#ifdef ST_SIMD_AVOID_UNALIGNED
// in SIMD mode skip 'mixingPos' positions that aren't aligned to 16-byte boundary
if (((ulongptr)mixingPos) & 15) return -1e50;
#endif
// hint compiler autovectorization that loop length is divisible by 8
int ilength = (channels * overlapLength) & -8;
corr = lnorm = 0;
// Same routine for stereo and mono. For stereo, unroll loop for better
// efficiency and gives slightly better resolution against rounding.
// For mono it same routine, just unrolls loop by factor of 4
for (i = 0; i < channels * overlapLength; i += 4)
// Same routine for stereo and mono
for (i = 0; i < ilength; i += 2)
{
corr += (mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow
corr += (mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm;
mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm;
lnorm += (mixingPos[i] * mixingPos[i] +
mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow
lnorm += (mixingPos[i + 2] * mixingPos[i + 2] +
mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBitsNorm;
mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBitsNorm;
// do intermediate scalings to avoid integer overflow
}
if (lnorm > maxnorm)
@@ -925,9 +925,12 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do
double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm)
{
long corr;
unsigned long lnorm;
long lnorm;
int i;
// hint compiler autovectorization that loop length is divisible by 8
int ilength = (channels * overlapLength) & -8;
// cancel first normalizer tap from previous round
lnorm = 0;
for (i = 1; i <= channels; i ++)
@@ -936,15 +939,11 @@ double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *c
}
corr = 0;
// Same routine for stereo and mono. For stereo, unroll loop for better
// efficiency and gives slightly better resolution against rounding.
// For mono it same routine, just unrolls loop by factor of 4
for (i = 0; i < channels * overlapLength; i += 4)
// Same routine for stereo and mono.
for (i = 0; i < ilength; i += 2)
{
corr += (mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow
corr += (mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm;
mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm;
}
// update normalizer with last samples of this round
@@ -1045,27 +1044,24 @@ void TDStretch::calculateOverlapLength(int overlapInMsec)
/// Calculate cross-correlation
double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &anorm)
{
double corr;
double norm;
float corr;
float norm;
int i;
#ifdef ST_SIMD_AVOID_UNALIGNED
// in SIMD mode skip 'mixingPos' positions that aren't aligned to 16-byte boundary
if (((ulongptr)mixingPos) & 15) return -1e50;
#endif
// hint compiler autovectorization that loop length is divisible by 8
int ilength = (channels * overlapLength) & -8;
corr = norm = 0;
// Same routine for stereo and mono. For Stereo, unroll by factor of 2.
// For mono it's same routine yet unrollsd by factor of 4.
for (i = 0; i < channels * overlapLength; i += 4)
// Same routine for stereo and mono
for (i = 0; i < ilength; i ++)
{
corr += mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1];
norm += mixingPos[i] * mixingPos[i] +
mixingPos[i + 1] * mixingPos[i + 1];
// unroll the loop for better CPU efficiency:
corr += mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3];
norm += mixingPos[i + 2] * mixingPos[i + 2] +
mixingPos[i + 3] * mixingPos[i + 3];
corr += mixingPos[i] * compare[i];
norm += mixingPos[i] * mixingPos[i];
}
anorm = norm;
@@ -1076,7 +1072,7 @@ double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, do
/// Update cross-correlation by accumulating "norm" coefficient by previously calculated value
double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm)
{
double corr;
float corr;
int i;
corr = 0;
@@ -1087,14 +1083,13 @@ double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *c
norm -= mixingPos[-i] * mixingPos[-i];
}
// Same routine for stereo and mono. For Stereo, unroll by factor of 2.
// For mono it's same routine yet unrollsd by factor of 4.
for (i = 0; i < channels * overlapLength; i += 4)
// hint compiler autovectorization that loop length is divisible by 8
int ilength = (channels * overlapLength) & -8;
// Same routine for stereo and mono
for (i = 0; i < ilength; i ++)
{
corr += mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1] +
mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3];
corr += mixingPos[i] * compare[i];
}
// update normalizer with last samples of this round
+1 -1
View File
@@ -80,7 +80,7 @@ double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &a
// Compile-time define SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
// for choosing if this little cheating is allowed.
#ifdef SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
#ifdef ST_SIMD_AVOID_UNALIGNED
// Little cheating allowed, return valid correlation only for
// aligned locations, meaning every second round for stereo sound.
+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
+1 -1
View File
@@ -15,7 +15,7 @@ The latest officially released stable version is version 1.6.0.
Installers and binaries for both Windows and Linux are available from [our website](https://pcsx2.net/download.html).
Development builds are also available from [our website](https://pcsx2.net/download/development.html).
Development builds are also available from [Github](https://github.com/PCSX2/pcsx2/releases).
## System Requirements
+589 -168
View File
File diff suppressed because it is too large Load Diff
+6 -12
View File
@@ -121,15 +121,7 @@ endif()
# It only cost several MB so disbable it by default
option(CMAKE_BUILD_STRIP "Srip binaries to save a couple of MB (developer option)")
if(NOT DEFINED CMAKE_BUILD_PO)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_BUILD_PO TRUE)
message(STATUS "Enable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
else()
set(CMAKE_BUILD_PO FALSE)
message(STATUS "Disable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
endif()
endif()
option(CMAKE_BUILD_PO "Build po files (modifies git-tracked files)" OFF)
#-------------------------------------------------------------------------------
# Select the architecture
@@ -220,7 +212,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 +322,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;
}
+5
View File
@@ -170,6 +170,11 @@ else()
endif()
endif()
if (USE_GCC AND CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# GCC LTO doesn't work with asm statements
set_source_files_properties(FastJmp.cpp PROPERTIES COMPILE_FLAGS -fno-lto)
endif()
target_link_libraries(common PRIVATE ${LIBC_LIBRARIES} PUBLIC wxWidgets::all glad)
target_compile_features(common PUBLIC cxx_std_17)
target_include_directories(common PUBLIC ../3rdparty/include ../)
+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>
+81 -17
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)
@@ -1179,7 +1243,7 @@ __fi void cdvdReadInterrupt()
cdvd.Status = CDVD_STATUS_PAUSE;
cdvd.nCommand = 0;
//DevCon.Warning("Scheduling interrupt in %d cycles", cdvd.ReadTime - (cdvd.BlockSize / 4));
//DevCon.Warning("Scheduling interrupt in %d cycles", cdvd.ReadTime - ((cdvd.BlockSize / 4) * 12));
// Timing issues on command end
// Star Ocean (1.1 Japan) expects the DMA to end and interrupt at least 128 or more cycles before the CDVD command ends.
// However the time required seems to increase slowly, so delaying the end of the command is not the solution.
@@ -1190,7 +1254,7 @@ __fi void cdvdReadInterrupt()
}
else
{
CDVDREAD_INT((cdvd.BlockSize / 4));
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
return;
}
@@ -1198,9 +1262,9 @@ __fi void cdvdReadInterrupt()
cdvd.Reading = 1;
cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode);
if (cdvd.nextSectorsBuffered)
CDVDREAD_INT((cdvd.BlockSize / 4));
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
else
CDVDREAD_INT(cdvd.ReadTime + (cdvd.BlockSize / 4));
CDVDREAD_INT(cdvd.ReadTime + ((cdvd.BlockSize / 4) * 12));
}
// Returns the number of IOP cycles until the event completes.
@@ -1274,16 +1338,16 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
if (psxRegs.interrupt & (1 << IopEvt_CdvdSectorReady))
{
//DevCon.Warning("coming back from ready sector early reducing %d cycles by %d cycles", seektime, psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]);
seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + (cdvd.BlockSize / 4);
seektime = (psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12);
}
else
{
CDVDSECTORREADY_INT(cdvd.ReadTime);
seektime = cdvd.ReadTime + (cdvd.BlockSize / 4);
seektime = cdvd.ReadTime + ((cdvd.BlockSize / 4) * 12);
}
}
else
seektime = (cdvd.BlockSize / 4);
seektime = (cdvd.BlockSize / 4) * 12;
}
else
{
@@ -1299,7 +1363,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
//DevCon.Warning("%s rotational latency at sector %d is %d cycles", (cdvd.SpindlCtrl & CDVD_SPINDLE_CAV) ? "CAV" : "CLV", cdvd.SeekToSector, rotationalLatency);
seektime += rotationalLatency + cdvd.ReadTime;
CDVDSECTORREADY_INT(seektime);
seektime += (cdvd.BlockSize / 4);
seektime += (cdvd.BlockSize / 4) * 12;
}
return seektime;
}
+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
@@ -1076,7 +1076,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr)
case 0x41000200:
if (cdvd.WaitingDMA)
{
PSX_INT(IopEvt_CdvdRead, cdvd.BlockSize / 4); //Data should be already buffered so simulate DMA time
PSX_INT(IopEvt_CdvdRead, (cdvd.BlockSize / 4) * 12); //Data should be already buffered so simulate DMA time
}
//SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr);
return;
+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;
+28 -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
@@ -620,6 +618,7 @@ set(pcsx2GSSources
GS/GSLzma.cpp
GS/GSPerfMon.cpp
GS/GSPng.cpp
GS/GSRingHeap.cpp
GS/GSState.cpp
GS/GSTables.cpp
GS/GSUtil.cpp
@@ -639,21 +638,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 +654,7 @@ set(pcsx2GSSources
GS/Renderers/OpenGL/GSTextureCacheOGL.cpp
GS/Renderers/OpenGL/GSTextureOGL.cpp
GS/Window/GSSetting.cpp
GS/Window/GSwxDialog.cpp
)
# GS headers
@@ -678,13 +669,16 @@ 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
GS/GSPerfMon.h
GS/GSPng.h
GS/GSRingHeap.h
GS/GSState.h
GS/GSTables.h
GS/GSThread_CXX11.h
@@ -712,11 +706,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 +728,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 +793,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 +801,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 +816,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 +893,6 @@ else(WIN32)
list(APPEND pcsx2GSSources
GS/GS_res.cpp
GS/Window/GSLinuxDialog.cpp
)
list(APPEND pcsx2GSHeaders
@@ -969,6 +967,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 +1027,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 +1468,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
+78 -98
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);
}
@@ -762,7 +738,10 @@ const std::string root_hw("/tmp/GS_HW_dump32/");
void* vmalloc(size_t size, bool code)
{
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
void* ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
void vmfree(void* ptr, size_t size)
@@ -771,15 +750,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 +774,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 +812,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)
{
@@ -869,7 +848,10 @@ void* vmalloc(size_t size, bool code)
#endif
}
return mmap(NULL, size, prot, flags, -1, 0);
void* ptr = mmap(NULL, size, prot, flags, -1, 0);
if (ptr == MAP_FAILED)
throw std::bad_alloc();
return ptr;
}
void vmfree(void* ptr, size_t size)
@@ -906,8 +888,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 +1088,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 +1127,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 +1167,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 +1189,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 +1209,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 +1218,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 +1245,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 +1295,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 +1372,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 +1382,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
+9 -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);
@@ -32,6 +33,11 @@ public:
_aligned_free(p);
}
void* operator new(size_t size, void* ptr)
{
return ptr;
}
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);
};
+5 -4
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)
@@ -55,7 +56,7 @@ static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
static int reduce(int uv, int size)
{
while (size > 3 && (1 << (size - 1)) >= uv + 1)
while (size > 3 && (1 << (size - 1)) >= uv)
{
size--;
}
@@ -65,7 +66,7 @@ static int reduce(int uv, int size)
static int extend(int uv, int size)
{
while (size < 10 && (1 << size) < uv + 1)
while (size < 10 && (1 << size) < uv)
{
size++;
}
@@ -98,7 +99,7 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear,
uvf += GSVector4(-0.5f, 0.5f).xxyy();
}
GSVector4i uv = GSVector4i(uvf.floor());
GSVector4i uv = GSVector4i(uvf.floor().xyzw(uvf.ceil()));
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << th) - 1, wmt, minv, maxv);
@@ -153,7 +154,7 @@ void GSDrawingContext::ComputeFixedTEX0(const GSVector4& st)
int maxu = (int)CLAMP.MAXU;
int maxv = (int)CLAMP.MAXV;
GSVector4i uv = GSVector4i(st.floor());
GSVector4i uv = GSVector4i(st.floor().xyzw(st.ceil()));
uv.x = findmax(uv.x, uv.z, (1 << TEX0.TW) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << TEX0.TH) - 1, wmt, minv, maxv);
+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

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