Compare commits

...

103 Commits

Author SHA1 Message Date
Penguino
754057b496 GameDB: Add Ougon no Kaze VU1 clamping, JoJo romanization consistency
- Added VU1 Clamping (Extra + Preserve Sign) to Ougon no Kaze (SLPM-65140, SLPM-66853, SLPM-61030) to fix the shading of the enemy's Stand in Chapter 11-2
- Changed "Jojo" romanization to "JoJo" (SLPM-66853, SLPS-25686)
- Changed "Kimyouna" to "Kimyou na" in Ougon no Kaze [Best Price] (SLPM-66853)
2025-01-17 04:31:31 +01:00
lightningterror
513c44f07f DumpRunner: Fix compare when frames are missing. 2025-01-17 04:29:37 +01:00
nassau-tk
0090655899 GameDB: Fix Japanese Game Titles. (#12158) 2025-01-15 22:40:52 +01:00
JordanTheToaster
7103e9be1e 3rdparty: Sync cpuinfo to commit 8a1772a0c5c447df2d18edf33ec4603a8c9c04a6 2025-01-15 22:17:59 +01:00
JordanTheToaster
b04906c3e9 3rdparty: Update promptfont with new icons 2025-01-15 22:17:59 +01:00
JordanTheToaster
fc5fe8b48c Deps: Update webp to 1.5.0 2025-01-15 22:17:59 +01:00
JordanTheToaster
e32e91af5c Deps: Update libpng to 1.6.45 2025-01-15 22:17:59 +01:00
JordanTheToaster
aa5b026d4a SDLInputSource: Halve default LED brightness 2025-01-15 22:16:39 +01:00
PCSX2 Bot
9568f3305b [ci skip] PAD: Update to latest controller database. 2025-01-13 17:03:58 +01:00
TheLastRar
f33064a1e2 x86emitter: Backup and restore non-volatile SSE registers
XMM6-XMM15 are non-volatile on Windows
2025-01-13 10:12:57 -05:00
lightningterror
6c9a2e96e1 iR3000A/iR5900: Fix dev/debug build compile.
Remove JITCompileInBlock leftovers.
2025-01-13 03:22:44 +01:00
JordanTheToaster
8c98f5d928 iR5900: Remove mid block jumping 2025-01-12 17:40:36 -05:00
refractionpcsx2
19f0cfcf06 GS/HW: Fix misdetection of draw as clear with fog effect 2025-01-12 23:18:38 +01:00
refractionpcsx2
4f42d95d3c GS/HW: If HW Move is outside of target, make a new target instead 2025-01-12 23:18:38 +01:00
refractionpcsx2
68823c524f GS/HW: Backport target expansion change from RT in RT PR 2025-01-12 23:18:38 +01:00
refractionpcsx2
05917796a5 GS/HW: Backported fixes from RT in RT PR 2025-01-12 23:18:38 +01:00
refractionpcsx2
d64da07b7d DumpRunner: Fix "missing" messages to not break the image cycler 2025-01-12 23:18:38 +01:00
PCSX2 Bot
27074a809c [ci skip] Qt: Update Base Translation. 2025-01-12 01:34:23 +01:00
Silent
33b366180e Qt/Patches, Cheats: Reload lists if serial changes 2025-01-11 09:04:51 -05:00
Silent
d8e310e7bf Qt/Patches: Use the game list serial when populating patches for the ELF
This makes the Game Properties window match the behaviour of the VM
when booting into a game.

Fixes #11533
2025-01-11 09:04:51 -05:00
Silent
534ddd80ae Patch: When serial is empty, don't match files on empty serial
Fixes a bug where _crc.pnach files matched the regex if serial
was not set. Also grey out "All CRCs" when serial is not set,
as the option is then meaningless.
2025-01-11 09:04:51 -05:00
chaoticgd
d34f2ec142 Debugger: Add disassembler toggle to go to the PC address on pause 2025-01-11 09:03:24 -05:00
TheTechnician27
7381a02dae SIO: Fix save state OSD warning formatting 2025-01-11 09:02:45 -05:00
RedPanda4552
333c7ef61b Memcard: Track file size globally at open
Prevents FSeek64 hits on every retrieval of memcard attributes
2025-01-09 15:47:56 +01:00
RedPanda4552
77d5a04aa4 Memcard: Remove support for legacy PSX card types with headers
Supporting legacy PSX cards with headers required constant size checks, thrashing IOP performance.
2025-01-09 15:47:56 +01:00
TheLastRar
d3effdb176 CI/Windows: Use LLVM 19 with MSBuild and CMake
Now using the Chocolatey install of LLVM
2025-01-09 15:46:34 +01:00
JordanTheToaster
d7e1350b95 CI/Windows: Use Windows Server 2025 2025-01-09 15:46:34 +01:00
PCSX2 Bot
14ac653e45 [ci skip] Qt: Update Base Translation. 2025-01-09 15:45:02 +01:00
spixi
a5e4274cd2 common: Add support for MATE Desktop. (#12174)
This extends the screensaver inhibition function to MATE Desktop,
2025-01-09 15:07:09 +01:00
Ty Lamontagne
16b1095a7b EE Cache: Shrink tag size by 4 bytes 2025-01-08 18:34:30 -05:00
Silent
3b5b3ffa91 Patch: Re-run PPT_ONCE_ON_LOAD patches when enabling them as the game is running 2025-01-08 18:30:51 -05:00
Silent
7ebcca36d2 Patch: Actually apply type 2 patches on the entry point
Type 2 patches were supposed to be "Type 0 + Type 1",
but in reality they only executed on vblank, making them equivalent
to Type 1.
2025-01-08 18:30:51 -05:00
PCSX2 Bot
501c543d1b [ci skip] Qt: Update Base Translation. 2025-01-08 19:46:56 +01:00
lightningterror
4dafea65f2 GS/HW: Adjust need_aem_color and req_color conditions.
Improves LookupSource to not use dirty data when it shouldn't.
2025-01-06 18:09:34 +01:00
PCSX2 Bot
e7cdd89577 [ci skip] PAD: Update to latest controller database. 2025-01-06 17:01:53 +01:00
lightningterror
1a508439b3 GameDB: Rename Dynasty Warriors 3 and 4.
SLES-51441: Dynasty Warriors 3 - Extreme Legends -> Dynasty Warriors 3 - Xtreme Legends

SLUS-20812: Dynasty Warriors 4 - Extreme Edition -> Dynasty Warriors 4 - Xtreme Legends
2025-01-06 15:22:07 +01:00
JordanTheToaster
3548d103f4 3rdparty: Update vkmemoryallocator to v3.2.0 2025-01-06 13:55:39 +01:00
JordanTheToaster
b1d4101490 Deps: Update SDL to 2.30.11 2025-01-06 13:53:18 +01:00
Florin9doi
a714582c1c Memcard: Support for MemCardPro2/.mc2 files. (#12157) 2025-01-06 13:31:04 +01:00
chaoticgd
0e7da0f1a8 Debugger: Fix AST node ownership confusion bug 2025-01-06 13:28:21 +01:00
TheTechnician27
4f7c8a77f6 Tools: Fix typo in compression tool 2025-01-04 17:17:39 -05:00
Ty Lamontagne
1842fe6db8 EE Cache: Make the SIMD path x86 only to support ARM interpreters 2025-01-03 14:17:24 -05:00
Mrlinkwii
1feb31498d GameDB: fix some names 2025-01-02 21:19:35 +01:00
nassau-tk
f3632c44c8 GameDB: Fix&Add few Japanese Game Titles 2024-12-31 21:14:13 -06:00
PCSX2 Bot
32a6e62212 [ci skip] Qt: Update Base Translation. 2025-01-01 01:27:00 +01:00
Jordan
575ec07553 3rdparty: Update xxHash to v0.8.3 (#12137) 2024-12-31 18:14:47 -05:00
lightningterror
18308b6525 GS/GL: Properly name logs with GL prefix. 2024-12-31 20:11:25 +01:00
lightningterror
d52f29dcd7 GS/D3D12: Properly name logs with D3D12 prefix. 2024-12-31 20:11:25 +01:00
lightningterror
288d8047ae GS/VK: Properly name logs with VK prefix. 2024-12-31 20:11:25 +01:00
lightningterror
26b232292c GS/D3D11: Properly name logs with D3D11 prefix. 2024-12-31 20:11:25 +01:00
Tyler Wilding
1fff69b0aa translations: Syncing Crowdin translations (#12141)
* New translations pcsx2-qt_en.ts (Romanian)
[ci skip]

* New translations pcsx2-qt_en.ts (French)
[ci skip]

* New translations pcsx2-qt_en.ts (Spanish)
[ci skip]

* New translations pcsx2-qt_en.ts (Afrikaans)
[ci skip]

* New translations pcsx2-qt_en.ts (Arabic)
[ci skip]

* New translations pcsx2-qt_en.ts (Bulgarian)
[ci skip]

* New translations pcsx2-qt_en.ts (Catalan)
[ci skip]

* New translations pcsx2-qt_en.ts (Czech)
[ci skip]

* New translations pcsx2-qt_en.ts (Danish)
[ci skip]

* New translations pcsx2-qt_en.ts (German)
[ci skip]

* New translations pcsx2-qt_en.ts (Greek)
[ci skip]

* New translations pcsx2-qt_en.ts (Finnish)
[ci skip]

* New translations pcsx2-qt_en.ts (Hebrew)
[ci skip]

* New translations pcsx2-qt_en.ts (Hungarian)
[ci skip]

* New translations pcsx2-qt_en.ts (Italian)
[ci skip]

* New translations pcsx2-qt_en.ts (Japanese)
[ci skip]

* New translations pcsx2-qt_en.ts (Georgian)
[ci skip]

* New translations pcsx2-qt_en.ts (Korean)
[ci skip]

* New translations pcsx2-qt_en.ts (Lithuanian)
[ci skip]

* New translations pcsx2-qt_en.ts (Dutch)
[ci skip]

* New translations pcsx2-qt_en.ts (Norwegian)
[ci skip]

* New translations pcsx2-qt_en.ts (Polish)
[ci skip]

* New translations pcsx2-qt_en.ts (Portuguese)
[ci skip]

* New translations pcsx2-qt_en.ts (Russian)
[ci skip]

* New translations pcsx2-qt_en.ts (Serbian (Cyrillic))
[ci skip]

* New translations pcsx2-qt_en.ts (Swedish)
[ci skip]

* New translations pcsx2-qt_en.ts (Turkish)
[ci skip]

* New translations pcsx2-qt_en.ts (Ukrainian)
[ci skip]

* New translations pcsx2-qt_en.ts (Chinese Simplified)
[ci skip]

* New translations pcsx2-qt_en.ts (Chinese Traditional)
[ci skip]

* New translations pcsx2-qt_en.ts (Vietnamese)
[ci skip]

* New translations pcsx2-qt_en.ts (Portuguese, Brazilian)
[ci skip]

* New translations pcsx2-qt_en.ts (Indonesian)
[ci skip]

* New translations pcsx2-qt_en.ts (Persian)
[ci skip]

* New translations pcsx2-qt_en.ts (Croatian)
[ci skip]

* New translations pcsx2-qt_en.ts (Latvian)
[ci skip]

* New translations pcsx2-qt_en.ts (Hindi)
[ci skip]

* New translations pcsx2-qt_en.ts (Quechua)
[ci skip]

* New translations pcsx2-qt_en.ts (Guarani)
[ci skip]

* New translations pcsx2-qt_en.ts (Spanish, Latin America)
[ci skip]
2024-12-30 19:19:40 -05:00
PCSX2 Bot
4d347305b5 [ci skip] PAD: Update to latest controller database. 2024-12-30 17:03:52 +01:00
PCSX2 Bot
2fd6f8e4ac [ci skip] Qt: Update Base Translation. 2024-12-29 19:02:05 -05:00
Silent
97f316eca7 Qt/Patches: Gracefully migrate old per-game widescreen/no-interlace toggles to Patches
This old upgrade path telling users that the setting has been deprecated
can now be changed to perform the upgrade seamlessly for the user,
because the behaviour of the old per-game setting is identical to
the new behaviour of the Patches tab.
2024-12-29 14:03:56 -05:00
Silent
f7ba355697 Qt/Patches: Make WS/NI patches tri-state in the Patches screen, so disabling them per-game is possible
This solves a long-standing issue where globally enabled
widescreen/no-interlace patches visually appeared as disabled
on the patches list, but they were in fact enabled and could NOT be
disabled per-game.
2024-12-29 14:03:56 -05:00
Silent
c334040a96 Partially revert "Qt/Patches: Get rid of the global WS/NI toggle"
This reverts commit cc9f7e723a.
2024-12-29 14:03:56 -05:00
TheTechnician27
b01359e06f Tools: Port refraction's bulk compression script to Python 2024-12-28 12:09:19 -05:00
PCSX2 Bot
905f9431a5 [ci skip] Qt: Update Base Translation. 2024-12-28 11:30:16 -05:00
KamFretoZ
424951e1bb Logging: Adjust the formatting to be more consistent 2024-12-28 11:25:26 -05:00
KamFretoZ
2167d9e4f5 Settings/Log: Print advanced settings warning on the log
Warns the user through the log if they have advanced options enabled.
2024-12-28 11:25:26 -05:00
rtavarez98
82a38a7124 changed indentation from tab to space 2024-12-28 11:22:50 -05:00
Rain
eb6a52c55c replaced recursive_directory_iterator w/ FindFiles() 2024-12-28 11:22:50 -05:00
Rain
234b8f6abf Added rename input profile function 2024-12-28 11:22:50 -05:00
lightningterror
843566eb49 Qt: Properly disable all dumping options if draw dumping is disabled.
Also move around sone options.
2024-12-28 17:04:33 +01:00
nassau-tk
d63733830f GameDB: Disable MTVU for some games 2024-12-27 23:43:51 -06:00
nassau-tk
3ebd496c37 GameDB: Fix titles for Japanese games 2024-12-27 23:43:51 -06:00
Mrlinkwii
f0f2b013fc Redump: update database 2024-12-27 14:30:23 -05:00
Ty Lamontagne
9a75509614 EE Cache: Fix up TLB related register fetching 2024-12-27 14:18:32 -05:00
Ty Lamontagne
c513a29bcf EE Cache: Freeze cached entries in sstates
[SAVEVERSION+]
2024-12-27 14:18:32 -05:00
Ty Lamontagne
5d39c884b5 R5900: Improve the EE cache performance with SIMD 2024-12-27 14:18:32 -05:00
TheLastRar
6a0f811812 Build: Always set EnhancedInstructionSet for AVX2 configs
Replaces the march arguments for clang-cl
2024-12-24 22:05:50 -05:00
TheLastRar
f509fb6950 CI/Appimage: Suppress error when no tags are present 2024-12-24 12:00:56 -05:00
Ziemas
33a475a456 DebugTools: Fix GCC build, missing include 2024-12-24 13:47:49 +01:00
JordanTheToaster
d2fb90a700 GameDB: Various fixes 2024-12-23 19:40:29 -05:00
PCSX2 Bot
a34467dccd [ci skip] PAD: Update to latest controller database. 2024-12-23 17:58:45 +01:00
Hallkezz
c6d0f5e3cd GameDB: Change recommended blending level 2 to 4 for Twisted Metal: Head-On [Extra Twisted Edition]. (#12107)
Fixes menu text brightness in Twisted Metal: Head-On [Extra Twisted Edition].
2024-12-22 13:03:40 +01:00
PCSX2 Bot
34c9590cf1 [ci skip] Qt: Update Base Translation. 2024-12-18 19:06:27 -05:00
Ty Lamontagne
a2c7542e48 Savestates: Warn on savestate load and saves without mcd activity
[SAVEVERSION+]
2024-12-18 18:01:30 -05:00
TheLastRar
72a9f18456 3rdparty: Sync libchdr to commit cb077337d53392454e7100a0fd07139ca678e527 2024-12-18 17:58:44 -05:00
TheLastRar
7f59757eea 3rdparty/libchdr: Purge almost all remaining patches
Leaving only the chd_read_header_* functions, of which exists an equivalent in later libchdr versions
2024-12-18 17:58:44 -05:00
TheLastRar
3b89020082 3rdparty/libchdr: Purge now unused patches 2024-12-18 16:23:49 -05:00
TheLastRar
a7b07eb53f ChdReader: Use core_file to implement precaching 2024-12-18 16:23:49 -05:00
TheLastRar
58d13dac34 FileSystem: Add ReadFileWithPartialProgress for multiple files 2024-12-18 16:23:49 -05:00
Ty Lamontagne
5a8921dd22 IOPBios: Defer to iopMemSafeReadBytes when HLEing writes 2024-12-18 16:15:07 -05:00
Ty Lamontagne
f964dfaa5e IOPBios: Defer to iopMemSafeWriteBytes when HLEing reads 2024-12-18 16:15:07 -05:00
PCSX2 Bot
17274eb397 [ci skip] Qt: Update Base Translation. 2024-12-17 20:54:52 -05:00
TheLastRar
2f0b00a7a1 ChdFileReader: Migrate libchdr patch into PCSX2
Added function didn't need to be in libchdr
2024-12-17 13:35:10 -05:00
Mrlinkwii
260380abec CI: disable builds on controller database update 2024-12-17 19:22:03 +01:00
KamFretoZ
57fc87061d Cheats: Update notes on how PNACH 2.0 works
Co-Authored-By: Mrlinkwii <Mrlinkwii@users.noreply.github.com>
2024-12-17 11:27:45 -05:00
KamFretoZ
cc9f7e723a Qt/Patches: Get rid of the global WS/NI toggle 2024-12-17 11:27:45 -05:00
PCSX2 Bot
6a41e05694 PAD: Update to latest controller database. 2024-12-16 11:06:52 -05:00
TheLastRar
c8e1dc5328 ChdFileReader: Use core_file instead of modifing chd_open_file 2024-12-16 09:39:46 -05:00
lightningterror
c2ee5a0234 GS/HW: Get the proper context for the next draw if it's a split texture shuffle.
Draw might switch the context so make sure we get the correct one.
2024-12-16 08:37:39 +01:00
nassau-tk
3cafd2dc69 GameDB: Japanese game updates 2024-12-15 01:33:40 -06:00
JordanTheToaster
4b8890c438 3rdparty: Sync vkmemoryallocator to commit 5a53a198945ba8260fbc58fadb788745ce6aa263 2024-12-14 13:41:32 -05:00
JordanTheToaster
19882dc160 3rdparty: Sync d3d12memalloc to commit da380f69bd4547cd776c525ae225bb9d13df94e2 2024-12-14 13:41:32 -05:00
chaoticgd
0c21023bb2 Path: Prevent Path::RealPath from returning '.' and '..' components 2024-12-14 13:41:01 -05:00
chaoticgd
68e6ede47e Path: Add tests for Path::RealPath 2024-12-14 13:41:01 -05:00
chaoticgd
1ed3001358 FileSystem: Add CreateSymLink function 2024-12-14 13:41:01 -05:00
chaoticgd
b8ff171127 FileSystem: Improve directory deletion test slightly 2024-12-14 13:41:01 -05:00
lightningterror
7d16a915ed GS/HW: Adjust how we handle dithering on blend mix.
Allow dither adjust regardless of alpha. usually it is clamed to 1 anyway so we can expand it if alpha max is higher than 128.

Expand dither adjust to work in rev subtract conditions.
2024-12-13 08:27:00 +01:00
lightningterror
ecc24ce2e9 GS/TC: Use proper alpha min max for palettes.
If it's an old source made from target make sure it isn't a palette, alphas need to be used from the palette then.
2024-12-13 08:27:00 +01:00
TheLastRar
65748351c7 ChdFileReader: Correct extension check 2024-12-12 08:39:28 -05:00
144 changed files with 150572 additions and 96454 deletions

View File

@@ -22,7 +22,7 @@ jobs:
uses: peter-evans/create-pull-request@v7
with:
title: "PAD: Update to latest controller database"
commit-message: "PAD: Update to latest controller database."
commit-message: "[ci skip] PAD: 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."

View File

@@ -206,7 +206,7 @@ GIT_VERSION=$(git tag --points-at HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
# In the odd event that we run this script before the release gets tagged.
GIT_VERSION=$(git describe --tags)
GIT_VERSION=$(git describe --tags || true)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
fi

View File

@@ -16,10 +16,10 @@ fi
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
LIBJPEG=9f
LIBPNG=1.6.44
LIBWEBP=1.4.0
LIBPNG=1.6.45
LIBWEBP=1.5.0
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
SDL=SDL2-2.30.10
SDL=SDL2-2.30.11
QT=6.8.1
ZSTD=1.5.6
@@ -34,10 +34,10 @@ cd deps-build
cat > SHASUMS <<EOF
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
f59adf36a0fcf4c94198e7d3d776c1b3824211ab7aeebeb31fe19836661196aa $SDL.tar.gz
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
40b14562ef3bd779bc0e0418ea2ae08fa28235f8ea6e8c0cb3bce1d6ad58dcaf qtbase-everywhere-src-$QT.tar.xz
138cc2909aa98f5ff7283e36eb3936eb5e625d3ca3b4febae2ca21d8903dd237 qtimageformats-everywhere-src-$QT.tar.xz

View File

@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL2-2.30.10.tar.gz",
"sha256": "f59adf36a0fcf4c94198e7d3d776c1b3824211ab7aeebeb31fe19836661196aa"
"url": "https://libsdl.org/release/SDL2-2.30.11.tar.gz",
"sha256": "8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f"
}
],
"cleanup": [

View File

@@ -40,12 +40,12 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL2-2.30.10
SDL=SDL2-2.30.11
ZSTD=1.5.6
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.44
LIBPNG=1.6.45
LIBJPEG=9f
LIBWEBP=1.4.0
LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.9
QT=6.7.2
@@ -76,11 +76,11 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
f59adf36a0fcf4c94198e7d3d776c1b3824211ab7aeebeb31fe19836661196aa $SDL.tar.gz
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz

View File

@@ -22,12 +22,12 @@ fi
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL2-2.30.10
SDL=SDL2-2.30.11
ZSTD=1.5.6
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.44
LIBPNG=1.6.45
LIBJPEG=9f
LIBWEBP=1.4.0
LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.9
QT=6.7.2
@@ -56,11 +56,11 @@ CMAKE_COMMON=(
cat > SHASUMS <<EOF
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
f59adf36a0fcf4c94198e7d3d776c1b3824211ab7aeebeb31fe19836661196aa $SDL.tar.gz
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz

View File

@@ -45,12 +45,12 @@ cd "%BUILDDIR%"
set FREETYPE=2.13.3
set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1643
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.1
set QTMINOR=6.8
set SDL=SDL2-2.30.10
set WEBP=1.4.0
set SDL=SDL2-2.30.11
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.6
@@ -62,11 +62,11 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 14b06b30d3400953875e73b0c4771cad1483488a1ef816803610f22b32300ce8 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error

View File

@@ -43,12 +43,12 @@ cd "%BUILDDIR%"
set FREETYPE=2.13.3
set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1643
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.1
set QTMINOR=6.8
set SDL=SDL2-2.30.10
set WEBP=1.4.0
set SDL=SDL2-2.30.11
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.6
@@ -60,11 +60,11 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 14b06b30d3400953875e73b0c4771cad1483488a1ef816803610f22b32300ce8 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error

View File

@@ -13,7 +13,7 @@ jobs:
lint_vs_proj_files:
name: Lint VS Project Files
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
runs-on: windows-2019
runs-on: windows-2025
steps:
- name: Checkout Repository
uses: actions/checkout@v4

View File

@@ -12,7 +12,7 @@ on:
os:
required: false
type: string
default: windows-2022
default: windows-2025
platform:
required: false
type: string
@@ -55,13 +55,31 @@ jobs:
POWERSHELL_TELEMETRY_OPTOUT: 1
steps:
- name: Tempfix Clang
if: inputs.configuration == 'CMake'
run: choco uninstall llvm
- name: Checkout Repository
uses: actions/checkout@v4
- name: Configure MSBuild Clang Version
if: inputs.configuration != 'CMake'
shell: pwsh
run: |
[string[]] $clang_cl = &clang-cl.exe --version
$version = [Regex]::Match($clang_cl[0], "(\d+\.\d+\.\d+)")
$path = $clang_cl[3].TrimStart("InstalledDir: ").TrimEnd("\bin")
$output = @"
<Project>
<PropertyGroup>
<LLVMInstallDir>$path</LLVMInstallDir>
<LLVMToolsVersion>$version</LLVMToolsVersion>
</PropertyGroup>
</Project>
"@
Write-Host $output
$output | Out-File Directory.build.props
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
if: ${{ inputs.fetchTags }}

View File

@@ -419,6 +419,8 @@ enum cpuinfo_uarch {
cpuinfo_uarch_zen3 = 0x0020010B,
/** AMD Zen 4 microarchitecture. */
cpuinfo_uarch_zen4 = 0x0020010C,
/** AMD Zen 5 microarchitecture. */
cpuinfo_uarch_zen5 = 0x0020010D,
/** NSC Geode and AMD Geode GX and LX. */
cpuinfo_uarch_geode = 0x00200200,
@@ -818,6 +820,7 @@ struct cpuinfo_x86_isa {
bool avx512vp2intersect;
bool avx512_4vnniw;
bool avx512_4fmaps;
bool avx10_1;
bool amx_bf16;
bool amx_tile;
bool amx_int8;
@@ -1433,6 +1436,14 @@ static inline bool cpuinfo_has_x86_avx_ne_convert(void) {
#endif
}
static inline bool cpuinfo_has_x86_avx10_1(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.avx10_1;
#else
return false;
#endif
}
static inline bool cpuinfo_has_x86_hle(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.hle;

View File

@@ -1341,7 +1341,8 @@ void cpuinfo_arm_decode_cache(
* information, please refer to the technical manuals
* linked above
*/
const uint32_t min_l2_size_KB = uarch == cpuinfo_uarch_neoverse_v2 ? 1024 : 256;
const uint32_t min_l2_size_KB =
(uarch == cpuinfo_uarch_neoverse_v2 || midr_is_ampere_altra(midr)) ? 1024 : 256;
const uint32_t min_l3_size_KB = 0;
*l1i = (struct cpuinfo_cache){

View File

@@ -34,6 +34,7 @@
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
#define CPUINFO_ARM_MIDR_AMPERE_ALTRA UINT32_C(0x413fd0c1)
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
@@ -167,6 +168,11 @@ inline static bool midr_is_kryo_gold(uint32_t midr) {
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
}
inline static bool midr_is_ampere_altra(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_AMPERE_ALTRA & uarch_mask);
}
inline static uint32_t midr_score_core(uint32_t midr) {
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
switch (midr & core_mask) {

View File

@@ -429,6 +429,11 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
*/
isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
/*
* AVX 10.1 instructions:
*/
isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000));
/*
* AVX512PF instructions:
* - Intel: ebx[bit 26] in structured feature info (ecx = 0).

View File

@@ -387,6 +387,8 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
return cpuinfo_uarch_zen4;
}
break;
case 0x1a:
return cpuinfo_uarch_zen5;
}
break;
case cpuinfo_vendor_hygon:

View File

@@ -1,4 +1,4 @@
Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
Easy to integrate memory allocation library for Direct3D 12.
**Documentation:** Browse online: [D3D12 Memory Allocator](https://gpuopen-librariesandsdks.github.io/D3D12MemoryAllocator/html/) (generated from Doxygen-style comments in [src/D3D12MemAlloc.h](src/D3D12MemAlloc.h))
**Documentation:** Browse online: [D3D12 Memory Allocator](https://gpuopen-librariesandsdks.github.io/D3D12MemoryAllocator/html/) (generated from Doxygen-style comments in [include/D3D12MemAlloc.h](include/D3D12MemAlloc.h))
**License:** MIT. See [LICENSE.txt](LICENSE.txt)
@@ -36,6 +36,7 @@ Additional features:
- Customization and integration with custom engines: Predefine appropriate macros to provide your own implementation of external facilities used by the library, like assert, mutex, and atomic.
- Support for resource aliasing (overlap).
- Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size, custom `D3D12_HEAP_PROPERTIES` and `D3D12_HEAP_FLAGS`) and allocate memory out of it.
- Support for GPU Upload Heaps from preview Agility SDK (needs compilation with `D3D12MA_OPTIONS16_SUPPORTED` macro).
- Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
- Defragmentation: Let the library move data around to free some memory blocks and make your allocations better compacted.
- Statistics: Obtain brief or detailed statistics about the amount of memory used, unused, number of allocated heaps, number of allocations etc. - globally and per memory heap type. Current memory usage and budget as reported by the system can also be queried.
@@ -101,15 +102,18 @@ This software package uses third party software:
For more information see [NOTICES.txt](NOTICES.txt).
# Software using this library
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
- **[Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
[Some other projects on GitHub](https://github.com/search?q=D3D12MemAlloc.h&type=Code) and some game development studios that use DX12 in their games.
# See also
- **[Vcpkg](https://github.com/Microsoft/vcpkg)** dependency manager from Microsoft offers a port of this library that is easy to install.
- **[Vulkan Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/)** - equivalent library for Vulkan. License: MIT.
- **[d3d12ma.c](https://github.com/milliewalky/d3d12ma.c)** - C bindings for this library. Author: Mateusz Maciejewski (Matt Walky). License: MIT.
- **[TerraFX.Interop.D3D12MemoryAllocator](https://github.com/terrafx/terrafx.interop.d3d12memoryallocator)** - interop bindings for this library for C#, as used by [TerraFX](https://github.com/terrafx/terrafx). License: MIT.
- **[Vulkan Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/)** - equivalent library for Vulkan. License: MIT.
# Software using this library
- **[Qt Project](https://github.com/qt)**
- **[Ghost of Tsushima: Director's Cut PC](https://www.youtube.com/watch?v=cPKBDbCYctc&t=698s)** - Information avaliable in 11:38 of credits
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
- **[Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
[Some other projects on GitHub](https://github.com/search?q=D3D12MemAlloc.h&type=Code) and some game development studios that use DX12 in their games.

View File

@@ -24,9 +24,9 @@
/** \mainpage D3D12 Memory Allocator
<b>Version 2.1.0-development</b> (2023-07-05)
<b>Version 2.1.0-development</b> (2024-07-05)
Copyright (c) 2019-2023 Advanced Micro Devices, Inc. All rights reserved. \n
Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved. \n
License: MIT
Documentation of all members: D3D12MemAlloc.h
@@ -160,9 +160,9 @@ class D3D12MA_API IUnknownImpl : public IUnknown
{
public:
virtual ~IUnknownImpl() = default;
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;
protected:
virtual void ReleaseThis() { delete this; }
private:
@@ -265,18 +265,18 @@ enum ALLOCATION_FLAGS
*/
ALLOCATION_FLAG_CAN_ALIAS = 0x10,
/** Allocation strategy that chooses smallest possible free range for the allocation
/** %Allocation strategy that chooses smallest possible free range for the allocation
to minimize memory usage and fragmentation, possibly at the expense of allocation time.
*/
ALLOCATION_FLAG_STRATEGY_MIN_MEMORY = 0x00010000,
/** Allocation strategy that chooses first suitable free range for the allocation -
/** %Allocation strategy that chooses first suitable free range for the allocation -
not necessarily in terms of the smallest offset but the one that is easiest and fastest to find
to minimize allocation time, possibly at the expense of allocation quality.
*/
ALLOCATION_FLAG_STRATEGY_MIN_TIME = 0x00020000,
/** Allocation strategy that chooses always the lowest offset in available space.
/** %Allocation strategy that chooses always the lowest offset in available space.
This is not the most efficient strategy but achieves highly packed data.
Used internally by defragmentation, not recomended in typical usage.
*/
@@ -402,8 +402,9 @@ struct TotalStatistics
- 1 = `D3D12_HEAP_TYPE_UPLOAD`
- 2 = `D3D12_HEAP_TYPE_READBACK`
- 3 = `D3D12_HEAP_TYPE_CUSTOM`
- 4 = `D3D12_HEAP_TYPE_GPU_UPLOAD`
*/
DetailedStatistics HeapType[4];
DetailedStatistics HeapType[5];
/** \brief One element for each memory segment group located at the following indices:
- 0 = `DXGI_MEMORY_SEGMENT_GROUP_LOCAL`
@@ -413,9 +414,9 @@ struct TotalStatistics
- When `IsUMA() == FALSE` (discrete graphics card):
- `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` (index 0) represents GPU memory
(resources allocated in `D3D12_HEAP_TYPE_DEFAULT` or `D3D12_MEMORY_POOL_L1`).
(resources allocated in `D3D12_HEAP_TYPE_DEFAULT`, `D3D12_HEAP_TYPE_GPU_UPLOAD` or `D3D12_MEMORY_POOL_L1`).
- `DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL` (index 1) represents system memory
(resources allocated in `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`, or `D3D12_MEMORY_POOL_L0`).
(resources allocated in `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`, or `D3D12_MEMORY_POOL_L0`).
- When `IsUMA() == TRUE` (integrated graphics chip):
- `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` = (index 0) represents memory shared for all the resources.
- `DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL` = (index 1) is unused and always 0.
@@ -542,26 +543,6 @@ public:
*/
LPCWSTR GetName() const { return m_Name; }
/** \brief Returns `TRUE` if the memory of the allocation was filled with zeros when the allocation was created.
Returns `TRUE` only if the allocator is sure that the entire memory where the
allocation was created was filled with zeros at the moment the allocation was made.
Returns `FALSE` if the memory could potentially contain garbage data.
If it's a render-target or depth-stencil texture, it then needs proper
initialization with `ClearRenderTargetView`, `ClearDepthStencilView`, `DiscardResource`,
or a copy operation, as described on page
"ID3D12Device::CreatePlacedResource method - Notes on the required resource initialization" in Microsoft documentation.
Please note that rendering a fullscreen triangle or quad to the texture as
a render target is not a proper way of initialization!
See also articles:
- "Coming to DirectX 12: More control over memory allocation" on DirectX Developer Blog
- ["Initializing DX12 Textures After Allocation and Aliasing"](https://asawicki.info/news_1724_initializing_dx12_textures_after_allocation_and_aliasing).
*/
BOOL WasZeroInitialized() const { return m_PackedData.WasZeroInitialized(); }
protected:
void ReleaseThis() override;
@@ -620,29 +601,26 @@ private:
{
public:
PackedData() :
m_Type(0), m_ResourceDimension(0), m_ResourceFlags(0), m_TextureLayout(0), m_WasZeroInitialized(0) { }
m_Type(0), m_ResourceDimension(0), m_ResourceFlags(0), m_TextureLayout(0) { }
Type GetType() const { return (Type)m_Type; }
D3D12_RESOURCE_DIMENSION GetResourceDimension() const { return (D3D12_RESOURCE_DIMENSION)m_ResourceDimension; }
D3D12_RESOURCE_FLAGS GetResourceFlags() const { return (D3D12_RESOURCE_FLAGS)m_ResourceFlags; }
D3D12_TEXTURE_LAYOUT GetTextureLayout() const { return (D3D12_TEXTURE_LAYOUT)m_TextureLayout; }
BOOL WasZeroInitialized() const { return (BOOL)m_WasZeroInitialized; }
void SetType(Type type);
void SetResourceDimension(D3D12_RESOURCE_DIMENSION resourceDimension);
void SetResourceFlags(D3D12_RESOURCE_FLAGS resourceFlags);
void SetTextureLayout(D3D12_TEXTURE_LAYOUT textureLayout);
void SetWasZeroInitialized(BOOL wasZeroInitialized) { m_WasZeroInitialized = wasZeroInitialized ? 1 : 0; }
private:
UINT m_Type : 2; // enum Type
UINT m_ResourceDimension : 3; // enum D3D12_RESOURCE_DIMENSION
UINT m_ResourceFlags : 24; // flags D3D12_RESOURCE_FLAGS
UINT m_TextureLayout : 9; // enum D3D12_TEXTURE_LAYOUT
UINT m_WasZeroInitialized : 1; // BOOL
} m_PackedData;
Allocation(AllocatorPimpl* allocator, UINT64 size, UINT64 alignment, BOOL wasZeroInitialized);
Allocation(AllocatorPimpl* allocator, UINT64 size, UINT64 alignment);
// Nothing here, everything already done in Release.
virtual ~Allocation() = default;
@@ -1065,6 +1043,16 @@ enum ALLOCATOR_FLAGS
to create its heaps on smaller alignment not suitable for MSAA textures.
*/
ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED = 0x8,
/** \brief Disable optimization that prefers creating small buffers as committed to avoid 64 KB alignment.
By default, the library prefers creating small buffers <= 32 KB as committed,
because drivers tend to pack them better, while placed buffers require 64 KB alignment.
This, however, may decrease performance, as creating committed resources involves allocation of implicit heaps,
which may take longer than creating placed resources in existing heaps.
Passing this flag will disable this committed preference globally for the allocator.
It can also be disabled for a single allocation by using #ALLOCATION_FLAG_STRATEGY_MIN_TIME.
*/
ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED = 0x10,
};
/// \brief Parameters of created Allocator object. To be used with CreateAllocator().
@@ -1130,6 +1118,15 @@ public:
- "ID3D12Device::GetCustomHeapProperties method (d3d12.h)"
*/
BOOL IsCacheCoherentUMA() const;
/** \brief Returns true if GPU Upload Heaps are supported on the current system.
When true, you can use `D3D12_HEAP_TYPE_GPU_UPLOAD`.
This flag is fetched from `D3D12_FEATURE_D3D12_OPTIONS16::GPUUploadHeapSupported`.
`#define D3D12MA_OPTIONS16_SUPPORTED 1` is needed for the compilation of this library. Otherwise the flag is always false.
*/
BOOL IsGPUUploadHeapSupported() const;
/** \brief Returns total amount of memory of specific segment group, in bytes.
\param memorySegmentGroup use `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` or DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL`.
@@ -1447,11 +1444,11 @@ enum VIRTUAL_ALLOCATION_FLAGS
*/
VIRTUAL_ALLOCATION_FLAG_UPPER_ADDRESS = ALLOCATION_FLAG_UPPER_ADDRESS,
/// Allocation strategy that tries to minimize memory usage.
/// %Allocation strategy that tries to minimize memory usage.
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_MEMORY = ALLOCATION_FLAG_STRATEGY_MIN_MEMORY,
/// Allocation strategy that tries to minimize allocation time.
/// %Allocation strategy that tries to minimize allocation time.
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_TIME = ALLOCATION_FLAG_STRATEGY_MIN_TIME,
/** \brief Allocation strategy that chooses always the lowest offset in available space.
/** %Allocation strategy that chooses always the lowest offset in available space.
This is not the most efficient strategy but achieves highly packed data.
*/
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_OFFSET = ALLOCATION_FLAG_STRATEGY_MIN_OFFSET,
@@ -1640,6 +1637,9 @@ ID3D12Device* device = (...)
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
allocatorDesc.pDevice = device;
allocatorDesc.pAdapter = adapter;
// These flags are optional but recommended.
allocatorDesc.Flags = D3D12MA::ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED |
D3D12MA::ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED;
D3D12MA::Allocator* allocator;
HRESULT hr = D3D12MA::CreateAllocator(&allocatorDesc, &allocator);
@@ -1864,6 +1864,9 @@ to obtain object D3D12MA::Pool. Example:
\code
POOL_DESC poolDesc = {};
poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
// These flags are optional but recommended.
poolDesc.Flags = D3D12MA::POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED;
poolDesc.HeapFlags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
Pool* pool;
HRESULT hr = allocator->CreatePool(&poolDesc, &pool);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,12 +10,10 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CDROM_H__
#define __CDROM_H__
#include <stdint.h>
#include <stdbool.h>
#include <libchdr/chdconfig.h>
/***************************************************************************
@@ -49,15 +47,11 @@ enum
enum
{
CD_SUB_NONE = 0, /* no subcode data stored */
CD_SUB_RAW_INTERLEAVED, /* raw interleaved 96 bytes per sector */
CD_SUB_RAW, /* raw non-interleaved 96 bytes per sector */
CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
CD_SUB_NONE /* no subcode data stored */
};
const char* cdrom_get_subtype_string(uint32_t subtype);
bool cdrom_parse_subtype_string(const char* typestring, uint32_t* subtype, uint32_t* subsize);
#define CD_FLAG_GDROM 0x00000001 /* disc is a GD-ROM, all tracks should be stored with GD-ROM metadata */
#define CD_FLAG_GDROMLE 0x00000002 /* legacy GD-ROM, with little-endian CDDA data */
@@ -87,10 +81,10 @@ static inline uint32_t lba_to_msf(uint32_t lba)
{
uint8_t m, s, f;
m = (uint8_t)(lba / (60 * 75));
m = lba / (60 * 75);
lba -= m * (60 * 75);
s = (uint8_t)(lba / 75);
f = (uint8_t)(lba % 75);
s = lba / 75;
f = lba % 75;
return ((m / 10) << 20) | ((m % 10) << 16) |
((s / 10) << 12) | ((s % 10) << 8) |
@@ -113,6 +107,4 @@ static inline uint32_t lba_to_msf_alt(int lba)
return ret;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* __CDROM_H__ */

View File

@@ -48,7 +48,6 @@ extern "C" {
#include <libchdr/coretypes.h>
#include <libchdr/chdconfig.h>
#include <stdbool.h>
/***************************************************************************
@@ -59,67 +58,67 @@ extern "C" {
V1 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] UINT32 length; // length of header (including tag and length fields)
[ 12] UINT32 version; // drive format version
[ 16] UINT32 flags; // flags (see below)
[ 20] UINT32 compression; // compression type
[ 24] UINT32 hunksize; // 512-byte sectors per hunk
[ 28] UINT32 totalhunks; // total # of hunks represented
[ 32] UINT32 cylinders; // number of cylinders on hard disk
[ 36] UINT32 heads; // number of heads on hard disk
[ 40] UINT32 sectors; // number of sectors on hard disk
[ 44] UINT8 md5[16]; // MD5 checksum of raw data
[ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
[ 8] uint32_t length; // length of header (including tag and length fields)
[ 12] uint32_t version; // drive format version
[ 16] uint32_t flags; // flags (see below)
[ 20] uint32_t compression; // compression type
[ 24] uint32_t hunksize; // 512-byte sectors per hunk
[ 28] uint32_t totalhunks; // total # of hunks represented
[ 32] uint32_t cylinders; // number of cylinders on hard disk
[ 36] uint32_t heads; // number of heads on hard disk
[ 40] uint32_t sectors; // number of sectors on hard disk
[ 44] uint8_t md5[16]; // MD5 checksum of raw data
[ 60] uint8_t parentmd5[16]; // MD5 checksum of parent file
[ 76] (V1 header length)
V2 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] UINT32 length; // length of header (including tag and length fields)
[ 12] UINT32 version; // drive format version
[ 16] UINT32 flags; // flags (see below)
[ 20] UINT32 compression; // compression type
[ 24] UINT32 hunksize; // seclen-byte sectors per hunk
[ 28] UINT32 totalhunks; // total # of hunks represented
[ 32] UINT32 cylinders; // number of cylinders on hard disk
[ 36] UINT32 heads; // number of heads on hard disk
[ 40] UINT32 sectors; // number of sectors on hard disk
[ 44] UINT8 md5[16]; // MD5 checksum of raw data
[ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
[ 76] UINT32 seclen; // number of bytes per sector
[ 8] uint32_t length; // length of header (including tag and length fields)
[ 12] uint32_t version; // drive format version
[ 16] uint32_t flags; // flags (see below)
[ 20] uint32_t compression; // compression type
[ 24] uint32_t hunksize; // seclen-byte sectors per hunk
[ 28] uint32_t totalhunks; // total # of hunks represented
[ 32] uint32_t cylinders; // number of cylinders on hard disk
[ 36] uint32_t heads; // number of heads on hard disk
[ 40] uint32_t sectors; // number of sectors on hard disk
[ 44] uint8_t md5[16]; // MD5 checksum of raw data
[ 60] uint8_t parentmd5[16]; // MD5 checksum of parent file
[ 76] uint32_t seclen; // number of bytes per sector
[ 80] (V2 header length)
V3 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] UINT32 length; // length of header (including tag and length fields)
[ 12] UINT32 version; // drive format version
[ 16] UINT32 flags; // flags (see below)
[ 20] UINT32 compression; // compression type
[ 24] UINT32 totalhunks; // total # of hunks represented
[ 28] UINT64 logicalbytes; // logical size of the data (in bytes)
[ 36] UINT64 metaoffset; // offset to the first blob of metadata
[ 44] UINT8 md5[16]; // MD5 checksum of raw data
[ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
[ 76] UINT32 hunkbytes; // number of bytes per hunk
[ 80] UINT8 sha1[20]; // SHA1 checksum of raw data
[100] UINT8 parentsha1[20];// SHA1 checksum of parent file
[ 8] uint32_t length; // length of header (including tag and length fields)
[ 12] uint32_t version; // drive format version
[ 16] uint32_t flags; // flags (see below)
[ 20] uint32_t compression; // compression type
[ 24] uint32_t totalhunks; // total # of hunks represented
[ 28] uint64_t logicalbytes; // logical size of the data (in bytes)
[ 36] uint64_t metaoffset; // offset to the first blob of metadata
[ 44] uint8_t md5[16]; // MD5 checksum of raw data
[ 60] uint8_t parentmd5[16]; // MD5 checksum of parent file
[ 76] uint32_t hunkbytes; // number of bytes per hunk
[ 80] uint8_t sha1[20]; // SHA1 checksum of raw data
[100] uint8_t parentsha1[20];// SHA1 checksum of parent file
[120] (V3 header length)
V4 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] UINT32 length; // length of header (including tag and length fields)
[ 12] UINT32 version; // drive format version
[ 16] UINT32 flags; // flags (see below)
[ 20] UINT32 compression; // compression type
[ 24] UINT32 totalhunks; // total # of hunks represented
[ 28] UINT64 logicalbytes; // logical size of the data (in bytes)
[ 36] UINT64 metaoffset; // offset to the first blob of metadata
[ 44] UINT32 hunkbytes; // number of bytes per hunk
[ 48] UINT8 sha1[20]; // combined raw+meta SHA1
[ 68] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent
[ 88] UINT8 rawsha1[20]; // raw data SHA1
[ 8] uint32_t length; // length of header (including tag and length fields)
[ 12] uint32_t version; // drive format version
[ 16] uint32_t flags; // flags (see below)
[ 20] uint32_t compression; // compression type
[ 24] uint32_t totalhunks; // total # of hunks represented
[ 28] uint64_t logicalbytes; // logical size of the data (in bytes)
[ 36] uint64_t metaoffset; // offset to the first blob of metadata
[ 44] uint32_t hunkbytes; // number of bytes per hunk
[ 48] uint8_t sha1[20]; // combined raw+meta SHA1
[ 68] uint8_t parentsha1[20];// combined raw+meta SHA1 of parent
[ 88] uint8_t rawsha1[20]; // raw data SHA1
[108] (V4 header length)
Flags:
@@ -131,17 +130,17 @@ extern "C" {
V5 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] uint32_t length; // length of header (including tag and length fields)
[ 12] uint32_t version; // drive format version
[ 16] uint32_t compressors[4];// which custom compressors are used?
[ 32] uint64_t logicalbytes; // logical size of the data (in bytes)
[ 40] uint64_t mapoffset; // offset to the map
[ 48] uint64_t metaoffset; // offset to the first blob of metadata
[ 56] uint32_t hunkbytes; // number of bytes per hunk (512k maximum)
[ 60] uint32_t unitbytes; // number of bytes per unit within each hunk
[ 64] uint8_t rawsha1[20]; // raw data SHA1
[ 84] uint8_t sha1[20]; // combined raw+meta SHA1
[104] uint8_t parentsha1[20];// combined raw+meta SHA1 of parent
[ 8] uint32_t_t length; // length of header (including tag and length fields)
[ 12] uint32_t_t version; // drive format version
[ 16] uint32_t_t compressors[4];// which custom compressors are used?
[ 32] uint64_t_t logicalbytes; // logical size of the data (in bytes)
[ 40] uint64_t_t mapoffset; // offset to the map
[ 48] uint64_t_t metaoffset; // offset to the first blob of metadata
[ 56] uint32_t_t hunkbytes; // number of bytes per hunk (512k maximum)
[ 60] uint32_t_t unitbytes; // number of bytes per unit within each hunk
[ 64] uint8_t_t rawsha1[20]; // raw data SHA1
[ 84] uint8_t_t sha1[20]; // combined raw+meta SHA1
[104] uint8_t_t parentsha1[20];// combined raw+meta SHA1 of parent
[124] (V5 header length)
If parentsha1 != 0, we have a parent (no need for flags)
@@ -149,22 +148,22 @@ extern "C" {
V5 uncompressed map format:
[ 0] uint32_t offset; // starting offset / hunk size
[ 0] uint32_t_t offset; // starting offset / hunk size
V5 compressed map format header:
[ 0] uint32_t length; // length of compressed map
[ 0] uint32_t_t length; // length of compressed map
[ 4] UINT48 datastart; // offset of first block
[ 10] uint16_t crc; // crc-16 of the map
[ 12] uint8_t lengthbits; // bits used to encode complength
[ 13] uint8_t hunkbits; // bits used to encode self-refs
[ 14] uint8_t parentunitbits; // bits used to encode parent unit refs
[ 15] uint8_t reserved; // future use
[ 12] uint8_t_t lengthbits; // bits used to encode complength
[ 13] uint8_t_t hunkbits; // bits used to encode self-refs
[ 14] uint8_t_t parentunitbits; // bits used to encode parent unit refs
[ 15] uint8_t_t reserved; // future use
[ 16] (compressed header length)
Each compressed map entry, once expanded, looks like:
[ 0] uint8_t compression; // compression type
[ 0] uint8_t_t compression; // compression type
[ 1] UINT24 complength; // compressed length
[ 4] UINT48 offset; // offset
[ 10] uint16_t crc; // crc-16 of the data
@@ -221,7 +220,7 @@ extern "C" {
/* metadata parameters */
#define CHDMETATAG_WILDCARD 0
#define CHD_METAINDEX_APPEND ((UINT32)-1)
#define CHD_METAINDEX_APPEND ((uint32_t)-1)
/* metadata flags */
#define CHD_MDFLAGS_CHECKSUM 0x01 /* indicates data is checksummed */
@@ -259,7 +258,6 @@ extern "C" {
/* CHD open values */
#define CHD_OPEN_READ 1
#define CHD_OPEN_READWRITE 2
#define CHD_OPEN_TRANSFER_FILE 4 /* Freeing of the FILE* is now libchdr's responsibility if open was successful */
/* error types */
enum _chd_error
@@ -291,8 +289,7 @@ enum _chd_error
CHDERR_INVALID_STATE,
CHDERR_OPERATION_PENDING,
CHDERR_NO_ASYNC_OPERATION,
CHDERR_UNSUPPORTED_FORMAT,
CHDERR_CANCELLED,
CHDERR_UNSUPPORTED_FORMAT
};
typedef enum _chd_error chd_error;
@@ -310,32 +307,32 @@ typedef struct _chd_file chd_file;
typedef struct _chd_header chd_header;
struct _chd_header
{
UINT32 length; /* length of header data */
UINT32 version; /* drive format version */
UINT32 flags; /* flags field */
UINT32 compression[4]; /* compression type */
UINT32 hunkbytes; /* number of bytes per hunk */
UINT32 totalhunks; /* total # of hunks represented */
UINT64 logicalbytes; /* logical size of the data */
UINT64 metaoffset; /* offset in file of first metadata */
UINT64 mapoffset; /* TOOD V5 */
UINT8 md5[CHD_MD5_BYTES]; /* overall MD5 checksum */
UINT8 parentmd5[CHD_MD5_BYTES]; /* overall MD5 checksum of parent */
UINT8 sha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum */
UINT8 rawsha1[CHD_SHA1_BYTES]; /* SHA1 checksum of raw data */
UINT8 parentsha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum of parent */
UINT32 unitbytes; /* TODO V5 */
UINT64 unitcount; /* TODO V5 */
UINT32 hunkcount; /* TODO V5 */
uint32_t length; /* length of header data */
uint32_t version; /* drive format version */
uint32_t flags; /* flags field */
uint32_t compression[4]; /* compression type */
uint32_t hunkbytes; /* number of bytes per hunk */
uint32_t totalhunks; /* total # of hunks represented */
uint64_t logicalbytes; /* logical size of the data */
uint64_t metaoffset; /* offset in file of first metadata */
uint64_t mapoffset; /* TOOD V5 */
uint8_t md5[CHD_MD5_BYTES]; /* overall MD5 checksum */
uint8_t parentmd5[CHD_MD5_BYTES]; /* overall MD5 checksum of parent */
uint8_t sha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum */
uint8_t rawsha1[CHD_SHA1_BYTES]; /* SHA1 checksum of raw data */
uint8_t parentsha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum of parent */
uint32_t unitbytes; /* TODO V5 */
uint64_t unitcount; /* TODO V5 */
uint32_t hunkcount; /* TODO V5 */
/* map information */
UINT32 mapentrybytes; /* length of each entry in a map (V5) */
UINT8* rawmap; /* raw map data */
uint32_t mapentrybytes; /* length of each entry in a map (V5) */
uint8_t* rawmap; /* raw map data */
UINT32 obsolete_cylinders; /* obsolete field -- do not use! */
UINT32 obsolete_sectors; /* obsolete field -- do not use! */
UINT32 obsolete_heads; /* obsolete field -- do not use! */
UINT32 obsolete_hunksize; /* obsolete field -- do not use! */
uint32_t obsolete_cylinders; /* obsolete field -- do not use! */
uint32_t obsolete_sectors; /* obsolete field -- do not use! */
uint32_t obsolete_heads; /* obsolete field -- do not use! */
uint32_t obsolete_hunksize; /* obsolete field -- do not use! */
};
@@ -343,10 +340,10 @@ struct _chd_header
typedef struct _chd_verify_result chd_verify_result;
struct _chd_verify_result
{
UINT8 md5[CHD_MD5_BYTES]; /* overall MD5 checksum */
UINT8 sha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum */
UINT8 rawsha1[CHD_SHA1_BYTES]; /* SHA1 checksum of raw data */
UINT8 metasha1[CHD_SHA1_BYTES]; /* SHA1 checksum of metadata */
uint8_t md5[CHD_MD5_BYTES]; /* overall MD5 checksum */
uint8_t sha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum */
uint8_t rawsha1[CHD_SHA1_BYTES]; /* SHA1 checksum of raw data */
uint8_t metasha1[CHD_SHA1_BYTES]; /* SHA1 checksum of metadata */
};
@@ -372,10 +369,10 @@ struct _chd_verify_result
/* ----- CHD file management ----- */
/* create a new CHD file fitting the given description */
/* chd_error chd_create(const char *filename, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */
/* chd_error chd_create(const char *filename, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t compression, chd_file *parent); */
/* same as chd_create(), but accepts an already-opened core_file object */
/* chd_error chd_create_file(core_file *file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */
/* chd_error chd_create_file(core_file *file, uint64_t logicalbytes, uint32_t hunkbytes, uint32_t compression, chd_file *parent); */
/* open an existing CHD file */
CHD_EXPORT chd_error chd_open_core_file(core_file *file, int mode, chd_file *parent, chd_file **chd);
@@ -384,7 +381,6 @@ CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent,
/* precache underlying file */
CHD_EXPORT chd_error chd_precache(chd_file *chd);
CHD_EXPORT chd_error chd_precache_progress(chd_file* chd, bool(*progress)(size_t pos, size_t total, void* param), void* param);
/* close a CHD file */
CHD_EXPORT void chd_close(chd_file *chd);
@@ -392,13 +388,11 @@ CHD_EXPORT void chd_close(chd_file *chd);
/* return the associated core_file */
CHD_EXPORT core_file *chd_core_file(chd_file *chd);
/* return the overall size of a CHD, and any of its parents */
CHD_EXPORT UINT64 chd_get_compressed_size(chd_file* chd);
/* return an error string for the given CHD error */
CHD_EXPORT const char *chd_error_string(chd_error err);
/* ----- CHD header management ----- */
/* return a pointer to the extracted CHD header data */
@@ -408,21 +402,20 @@ CHD_EXPORT const chd_header *chd_get_header(chd_file *chd);
CHD_EXPORT chd_error chd_read_header_core_file(core_file *file, chd_header *header);
CHD_EXPORT chd_error chd_read_header_file(FILE *file, chd_header *header);
CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header);
CHD_EXPORT bool chd_is_matching_parent(const chd_header* header, const chd_header* parent_header);
/* ----- core data read/write ----- */
/* read one hunk from the CHD file */
CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer);
CHD_EXPORT chd_error chd_read(chd_file *chd, uint32_t hunknum, void *buffer);
/* ----- metadata management ----- */
/* get indexed metadata of a particular sort */
CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags);
CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, uint32_t searchtag, uint32_t searchindex, void *output, uint32_t outputlen, uint32_t *resultlen, uint32_t *resulttag, uint8_t *resultflags);
@@ -433,7 +426,7 @@ CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 se
CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config);
/* return a string description of a codec */
CHD_EXPORT const char *chd_get_codec_name(UINT32 codec);
CHD_EXPORT const char *chd_get_codec_name(uint32_t codec);
#ifdef __cplusplus
}

View File

@@ -8,26 +8,13 @@
#include <streams/file_stream_transforms.h>
#endif
#ifndef ARRAY_LENGTH
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
#if defined(__PS3__) || defined(__PSL1GHT__)
#undef UINT32
#undef UINT16
#undef UINT8
#undef INT32
#undef INT16
#undef INT8
#endif
typedef uint64_t UINT64;
typedef uint32_t UINT32;
typedef uint16_t UINT16;
typedef uint8_t UINT8;
typedef int64_t INT64;
typedef int32_t INT32;
typedef int16_t INT16;
typedef int8_t INT8;
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#endif
typedef struct chd_core_file {
/*
@@ -41,9 +28,9 @@ typedef struct chd_core_file {
* undefined because many implementations will seek to the end of the
* file and call ftell.
*
* on error, (UINT64)-1 is returned.
* on error, (uint64_t)-1 is returned.
*/
UINT64(*fsize)(struct chd_core_file*);
uint64_t(*fsize)(struct chd_core_file*);
/*
* should match the behavior of fread, except the FILE* argument at the end
@@ -55,7 +42,7 @@ typedef struct chd_core_file {
int (*fclose)(struct chd_core_file*);
// fseek clone
int (*fseek)(struct chd_core_file*, INT64, int);
int (*fseek)(struct chd_core_file*, int64_t, int);
} core_file;
static inline int core_fclose(core_file *fp) {
@@ -66,11 +53,11 @@ static inline size_t core_fread(core_file *fp, void *ptr, size_t len) {
return fp->fread(ptr, 1, len, fp);
}
static inline int core_fseek(core_file* fp, INT64 offset, int whence) {
static inline int core_fseek(core_file* fp, int64_t offset, int whence) {
return fp->fseek(fp, offset, whence);
}
static inline UINT64 core_fsize(core_file *fp)
static inline uint64_t core_fsize(core_file *fp)
{
return fp->fsize(fp);
}

View File

@@ -85,6 +85,6 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder);
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder);
void huffman_build_lookup_table(struct huffman_decoder* decoder);
enum huffman_error huffman_build_lookup_table(struct huffman_decoder* decoder);
#endif

View File

@@ -20,35 +20,6 @@
#include <libchdr/cdrom.h>
const char* cdrom_get_subtype_string(uint32_t subtype)
{
switch (subtype)
{
case CD_SUB_RAW: return "RW";
case CD_SUB_RAW_INTERLEAVED: return "RW_RAW";
default: return "NONE";
}
}
bool cdrom_parse_subtype_string(const char* typestring, uint32_t* subtype, uint32_t* subsize)
{
// https://github.com/mamedev/mame/blob/d2d54fb8ed53a2e86d308067da8414f85b5929b0/src/lib/util/cdrom.cpp#L767
if (!strcmp(typestring, "RW"))
{
*subtype = CD_SUB_RAW;
*subsize = 96;
return true;
}
else if (!strcmp(typestring, "RW_RAW"))
{
*subtype = CD_SUB_RAW_INTERLEAVED;
*subsize = 96;
return true;
}
return false;
}
#ifdef WANT_RAW_DATA_SECTOR
/***************************************************************************

File diff suppressed because it is too large Load Diff

View File

@@ -230,7 +230,9 @@ enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, stru
return error;
/* build the lookup table */
huffman_build_lookup_table(decoder);
error = huffman_build_lookup_table(decoder);
if (error != HUFFERR_NONE)
return error;
/* determine final input length and report errors */
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
@@ -271,8 +273,16 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
/* then regenerate the tree */
error = huffman_assign_canonical_codes(smallhuff);
if (error != HUFFERR_NONE)
{
delete_huffman_decoder(smallhuff);
return error;
huffman_build_lookup_table(smallhuff);
}
error = huffman_build_lookup_table(smallhuff);
if (error != HUFFERR_NONE)
{
delete_huffman_decoder(smallhuff);
return error;
}
/* determine the maximum length of an RLE count */
temp = decoder->numcodes - 9;
@@ -308,7 +318,9 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
return error;
/* build the lookup table */
huffman_build_lookup_table(decoder);
error = huffman_build_lookup_table(decoder);
if (error != HUFFERR_NONE)
return error;
/* determine final input length and report errors */
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
@@ -523,8 +535,9 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode
*-------------------------------------------------
*/
void huffman_build_lookup_table(struct huffman_decoder* decoder)
enum huffman_error huffman_build_lookup_table(struct huffman_decoder* decoder)
{
const lookup_value* lookupend = &decoder->lookup[(1u << decoder->maxbits)];
uint32_t curcode;
/* iterate over all codes */
for (curcode = 0; curcode < decoder->numcodes; curcode++)
@@ -533,9 +546,10 @@ void huffman_build_lookup_table(struct huffman_decoder* decoder)
struct node_t* node = &decoder->huffnode[curcode];
if (node->numbits > 0)
{
int shift;
lookup_value *dest;
lookup_value *destend;
int shift;
lookup_value *dest;
lookup_value *destend;
/* set up the entry */
lookup_value value = MAKE_LOOKUP(curcode, node->numbits);
@@ -543,8 +557,12 @@ void huffman_build_lookup_table(struct huffman_decoder* decoder)
shift = decoder->maxbits - node->numbits;
dest = &decoder->lookup[node->bits << shift];
destend = &decoder->lookup[((node->bits + 1) << shift) - 1];
if (dest >= lookupend || destend >= lookupend || destend < dest)
return HUFFERR_INTERNAL_INCONSISTENCY;
while (dest <= destend)
*dest++ = value;
}
}
return HUFFERR_NONE;
}

View File

@@ -23,7 +23,7 @@ OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0
CreationTime: 1544355305
ModificationTime: 1712653578
ModificationTime: 1736751870
PfmFamily: 33
TTFWeight: 400
TTFWidth: 5
@@ -65,7 +65,7 @@ NameList: AGL For New Fonts
DisplaySize: -48
AntiAlias: 1
FitToEm: 0
WinInfo: 8816 38 14
WinInfo: 8360 38 14
BeginPrivate: 8
BlueValues 29 [0 0 380 380 490 490 660 660]
OtherBlues 39 [-210 -210 -180 -180 -160 -160 280 280]
@@ -77,7 +77,7 @@ StemSnapV 13 [140 180 200]
ForceBold 4 true
EndPrivate
TeXData: 1 0 0 335544 167772 111848 513802 1048576 111848 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
BeginChars: 1114112 731
BeginChars: 1114112 733
StartChar: exclam
Encoding: 33 33 0
@@ -19511,40 +19511,40 @@ VStem: 92.5596 41.7305<171.236 408.764> 189.39 149.051<176.142 403.858> 699.66 1
LayerCount: 2
Fore
SplineSet
500 600.610351562 m 1
671.459960938 600.610351562 810.610351562 461.459960938 810.610351562 290 c 0
810.610351562 118.540039062 671.459960938 -20.6103515625 500 -20.6103515625 c 0
328.540039062 -20.6103515625 189.389648438 118.540039062 189.389648438 290 c 0
189.389648438 461.459960938 328.540039062 600.610351562 500 600.610351562 c 1
699.66015625 102.129882812 m 1
699.66015625 167.830078125 l 1
456.870117188 167.830078125 l 1
456.870117188 463.459960938 l 1
338.440429688 463.459960938 l 1
338.440429688 102.129882812 l 1
699.66015625 102.129882812 l 1
500 -117.440429688 m 0
445 -117.440429688 391.639648438 -106.66015625 341.400390625 -85.41015625 c 0
292.879882812 -64.8896484375 249.309570312 -35.509765625 211.900390625 1.900390625 c 0
174.490234375 39.3095703125 145.110351562 82.8798828125 124.58984375 131.400390625 c 0
103.33984375 181.639648438 92.5595703125 235.009765625 92.5595703125 290 c 0
92.5595703125 344.990234375 103.33984375 398.360351562 124.58984375 448.599609375 c 0
145.110351562 497.120117188 174.490234375 540.690429688 211.900390625 578.099609375 c 0
249.309570312 615.509765625 292.879882812 644.889648438 341.400390625 665.41015625 c 0
391.639648438 686.66015625 445.009765625 697.440429688 500 697.440429688 c 0
554.990234375 697.440429688 608.360351562 686.66015625 658.599609375 665.41015625 c 0
707.120117188 644.889648438 750.690429688 615.509765625 788.099609375 578.099609375 c 0
825.509765625 540.690429688 854.889648438 497.120117188 875.41015625 448.599609375 c 0
896.66015625 398.360351562 907.440429688 344.990234375 907.440429688 290 c 0
907.440429688 235.009765625 896.66015625 181.639648438 875.41015625 131.400390625 c 0
854.889648438 82.8798828125 825.509765625 39.3095703125 788.099609375 1.900390625 c 0
750.690429688 -35.509765625 707.120117188 -64.8896484375 658.599609375 -85.41015625 c 0
608.360351562 -106.66015625 554.990234375 -117.440429688 500 -117.440429688 c 0
500 655.709960938 m 0
298.349609375 655.709960938 134.290039062 491.66015625 134.290039062 290 c 0
134.290039062 88.33984375 298.33984375 -75.7099609375 500 -75.7099609375 c 0
701.66015625 -75.7099609375 865.709960938 88.349609375 865.709960938 290 c 0
865.709960938 491.650390625 701.66015625 655.709960938 500 655.709960938 c 0
500 600.610351562 m 5
671.459960938 600.610351562 810.610351562 461.459960938 810.610351562 290 c 4
810.610351562 118.540039062 671.459960938 -20.6103515625 500 -20.6103515625 c 4
328.540039062 -20.6103515625 189.389648438 118.540039062 189.389648438 290 c 4
189.389648438 461.459960938 328.540039062 600.610351562 500 600.610351562 c 5
699.66015625 102.129882812 m 5
699.66015625 167.830078125 l 5
456.870117188 167.830078125 l 5
456.870117188 463.459960938 l 5
338.440429688 463.459960938 l 5
338.440429688 102.129882812 l 5
699.66015625 102.129882812 l 5
500 -117.440429688 m 4
445 -117.440429688 391.639648438 -106.66015625 341.400390625 -85.41015625 c 4
292.879882812 -64.8896484375 249.309570312 -35.509765625 211.900390625 1.900390625 c 4
174.490234375 39.3095703125 145.110351562 82.8798828125 124.58984375 131.400390625 c 4
103.33984375 181.639648438 92.5595703125 235.009765625 92.5595703125 290 c 4
92.5595703125 344.990234375 103.33984375 398.360351562 124.58984375 448.599609375 c 4
145.110351562 497.120117188 174.490234375 540.690429688 211.900390625 578.099609375 c 4
249.309570312 615.509765625 292.879882812 644.889648438 341.400390625 665.41015625 c 4
391.639648438 686.66015625 445.009765625 697.440429688 500 697.440429688 c 4
554.990234375 697.440429688 608.360351562 686.66015625 658.599609375 665.41015625 c 4
707.120117188 644.889648438 750.690429688 615.509765625 788.099609375 578.099609375 c 4
825.509765625 540.690429688 854.889648438 497.120117188 875.41015625 448.599609375 c 4
896.66015625 398.360351562 907.440429688 344.990234375 907.440429688 290 c 4
907.440429688 235.009765625 896.66015625 181.639648438 875.41015625 131.400390625 c 4
854.889648438 82.8798828125 825.509765625 39.3095703125 788.099609375 1.900390625 c 4
750.690429688 -35.509765625 707.120117188 -64.8896484375 658.599609375 -85.41015625 c 4
608.360351562 -106.66015625 554.990234375 -117.440429688 500 -117.440429688 c 4
500 655.709960938 m 4
298.349609375 655.709960938 134.290039062 491.66015625 134.290039062 290 c 4
134.290039062 88.33984375 298.33984375 -75.7099609375 500 -75.7099609375 c 4
701.66015625 -75.7099609375 865.709960938 88.349609375 865.709960938 290 c 4
865.709960938 491.650390625 701.66015625 655.709960938 500 655.709960938 c 4
EndSplineSet
Validated: 5
EndChar
@@ -30101,7 +30101,7 @@ SplineSet
79 -59.400390625 120 -102.200195312 170.799804688 -102.200195312 c 2
838.200195312 -102.200195312 l 2
EndSplineSet
Validated: 524321
Validated: 33
EndChar
StartChar: uni23F6
@@ -30171,7 +30171,7 @@ SplineSet
79 -59.400390625 120 -102.200195312 170.799804688 -102.200195312 c 2
838.200195312 -102.200195312 l 1
EndSplineSet
Validated: 524321
Validated: 33
EndChar
StartChar: uni23F7
@@ -35271,5 +35271,218 @@ SplineSet
EndSplineSet
Validated: 1
EndChar
StartChar: uni2446
Encoding: 9286 9286 731
Width: 1000
HStem: 98.667 78.666<441.304 558.479> 298.667 80.666<211.095 321.99 686.039 796.635> 364 81.333<440.808 559.266> 544.667 80.666<210.809 321.868 685.514 796.925>
VStem: 104 80<406.859 516.049> 326.667 80<269.844 311.038> 349.333 80<429.563 517.407> 578.667 80<424.535 517.66> 593.333 80.667<270.25 314.708> 824 80<406.439 515.845>
LayerCount: 2
Fore
SplineSet
869.333007812 361.333007812 m 1x9840
887.333007812 310.666992188 925.333007812 194 915.333007812 116.666992188 c 0
902 10.6669921875 842.666992188 -30.6669921875 836 -35.3330078125 c 0
832 -38.6669921875 827.333007812 -40 822 -41.3330078125 c 0
812 -43.3330078125 802 -44 792 -44 c 0
770.666992188 -44 750 -39.3330078125 732.666992188 -30.6669921875 c 0
708 -18.6669921875 690 1.3330078125 676 30 c 0
654 76 656 148 662 194.666992188 c 1
661.333007812 194 658.666992188 194.666992188 655.333007812 195.333007812 c 0
627.333007812 138 568 98.6669921875 500 98.6669921875 c 0
431.333007812 98.6669921875 372 138.666992188 344 196 c 0
340 195.333007812 336 194 334.666992188 194.666992188 c 1
342.666992188 135.333007812 344.666992188 73.3330078125 324 30 c 0
310 1.3330078125 291.333007812 -18.6669921875 267.333007812 -30.6669921875 c 0
241.333007812 -43.3330078125 210 -46.6669921875 178 -40.6669921875 c 0
172.666992188 -40 168 -38 164 -35.3330078125 c 0
157.333007812 -31.3330078125 98 10.6669921875 84.6669921875 116.666992188 c 0
74.6669921875 199.333007812 116 323.333007812 133.333007812 369.333007812 c 1
114.666992188 396 104 428 104 462.666992188 c 0
104 552 176.666992188 625.333007812 266.666992188 625.333007812 c 0
299.333007812 625.333007812 329.333007812 615.333007812 354.666992188 599.333007812 c 1
385.333007812 646 436 677.333007812 492.666992188 681.333007812 c 0
557.333007812 685.333007812 619.333007812 653.333007812 655.333007812 600 c 1
680.666992188 615.333007812 710 624.666992188 741.333007812 624.666992188 c 0
830.666992188 624.666992188 904 552 904 462 c 0
904 424 891.333007812 389.333007812 869.333007812 361.333007812 c 1x9840
741.333007812 544.666992188 m 0
695.333007812 544.666992188 658.666992188 507.333007812 658.666992188 462 c 0
658.666992188 416.666992188 696 379.333007812 741.333007812 379.333007812 c 0xd940
786.666992188 379.333007812 824 416.666992188 824 462 c 0
824 507.333007812 786.666992188 544.666992188 741.333007812 544.666992188 c 0
498 601.333007812 m 0
459.333007812 598.666992188 426 572.666992188 411.333007812 536.666992188 c 0
422.666992188 514.666992188 429.333007812 489.333007812 429.333007812 462.666992188 c 0
429.333007812 450.666992188 428 439.333007812 426 428.666992188 c 1
448 439.333007812 473.333007812 445.333007812 500 445.333007812 c 0xbb40
530.666992188 445.333007812 558.666992188 437.333007812 583.333007812 424 c 1
580 436 578.666992188 448.666992188 578.666992188 462 c 0
578.666992188 490 585.333007812 516 598 539.333007812 c 0
580 579.333007812 540 604 498 601.333007812 c 0
266.666992188 544.666992188 m 0
220.666992188 544.666992188 184 507.333007812 184 462 c 0
184 416.666992188 221.333007812 379.333007812 266.666992188 379.333007812 c 0xda40
312 379.333007812 349.333007812 416.666992188 349.333007812 462 c 0
349.333007812 507.333007812 312 544.666992188 266.666992188 544.666992188 c 0
305.333007812 270 m 2
310.666992188 271.333007812 318.666992188 273.333007812 326.666992188 274 c 0xdc40
326.666992188 287.333007812 328 300 331.333007812 312 c 1
311.333007812 303.333007812 290 298.666992188 266.666992188 298.666992188 c 0
240.666992188 298.666992188 216 305.333007812 194 316 c 1
174.666992188 259.333007812 152.666992188 176 159.333007812 123.333007812 c 0
164 82.6669921875 178 56 189.333007812 39.3330078125 c 0
198.666992188 26.6669921875 216 20.6669921875 230.666992188 28 c 1
234 29.3330078125 244 34.6669921875 254 56 c 0
273.333007812 96 260 180 255.333007812 212 c 2
255.333007812 212.666992188 l 2
251.333007812 236.666992188 267.333007812 259.333007812 293.333007812 266.666992188 c 2
305.333007812 270 l 2
500 177.333007812 m 0
551.333007812 177.333007812 593.333007812 219.333007812 593.333007812 270.666992188 c 0
593.333007812 322 551.333007812 364 500 364 c 0xbcc0
448.666992188 364 406.666992188 322 406.666992188 270.666992188 c 0
406.666992188 219.333007812 448.666992188 177.333007812 500 177.333007812 c 0
840.666992188 123.333007812 m 0
846.666992188 174.666992188 826 256 808 311.333007812 c 1
788 302.666992188 765.333007812 297.333007812 742 297.333007812 c 0
715.333007812 297.333007812 690 304 668 315.333007812 c 1
671.333007812 302 673.333007812 288 674 274 c 0
684 273.333007812 694.666992188 271.333007812 701.333007812 268 c 2
708.666992188 264.666992188 l 2
729.333007812 254.666992188 741.333007812 234.666992188 738 213.333007812 c 2
738 212 l 2
734 183.333007812 726.666992188 95.3330078125 746 55.3330078125 c 0
756 34 766 29.3330078125 769.333007812 27.3330078125 c 1
784 20.6669921875 801.333007812 26 810.666992188 39.3330078125 c 0
822 56 835.333007812 82.6669921875 840.666992188 123.333007812 c 0
EndSplineSet
Validated: 524321
EndChar
StartChar: uni221B
Encoding: 8731 8731 732
Width: 1000
HStem: -209.992 21.2588<741.927 862.934> -160.664 62.5283<723.687 881.174> 85.9395 69.8691<723.687 780.459> 183.879 21.2588<741.929 862.934>
VStem: 594.865 21.2588<-62.9303 58.0754> 644.194 75.9316<-81.1715 76.316> 904.145 56.5225<-89.7754 -64.665> 988.736 21.2598<-62.9292 58.0743>
LayerCount: 2
Fore
SplineSet
133.1953125 240.114257812 m 1
128.731445312 224.2734375 135.630859375 215.740234375 135.630859375 215.740234375 c 1
158.787109375 176.336914062 l 1
148.629882812 119.875976562 174.627929688 78.4345703125 190.466796875 57.7236328125 c 0
206.305664062 37.001953125 310.713867188 -99.0751953125 323.712890625 -114.518554688 c 0
336.711914062 -129.954101562 389.11328125 -183.991210938 445.583984375 -142.953125 c 0
502.044921875 -101.926757812 483.362304688 -32.052734375 483.362304688 -32.052734375 c 1
459.1875 57.931640625 l 1
589.7890625 74.3857421875 547.140625 186.911132812 547.140625 186.911132812 c 1
601.831054688 241.602539062 l 1
601.831054688 241.602539062 714.356445312 198.951171875 730.811523438 329.545898438 c 1
820.79296875 305.37890625 l 1
820.79296875 305.37890625 890.669921875 286.688476562 931.6953125 343.159179688 c 0
972.721679688 399.619140625 918.696289062 452.03125 903.262695312 465.030273438 c 0
887.829101562 478.029296875 751.73828125 582.424804688 731.018554688 598.275390625 c 0
710.296875 614.114257812 668.864257812 640.114257812 612.404296875 629.965820312 c 1
573.001953125 653.122070312 l 1
573.001953125 653.122070312 564.466796875 660.03125 548.627929688 655.55859375 c 2
548.627929688 655.55859375 543.954101562 661.450195312 532.172851562 654.5390625 c 0
520.391601562 647.627929688 493.986328125 630.569335938 477.126953125 596.651367188 c 1
477.126953125 596.651367188 474.28515625 591.78125 480.166015625 586.296875 c 1
480.166015625 586.296875 474.078125 568.424804688 482.6015625 555.021484375 c 0
491.13671875 541.616210938 501.688476562 524.559570312 501.688476562 524.559570312 c 1
264.205078125 287.03125 l 1
264.205078125 287.03125 247.146484375 297.59375 233.741210938 306.119140625 c 0
220.337890625 314.654296875 202.465820312 308.553710938 202.465820312 308.553710938 c 1
196.981445312 314.444335938 192.1015625 311.604492188 192.1015625 311.604492188 c 1
158.18359375 294.744140625 141.125 268.340820312 134.213867188 256.559570312 c 0
127.3046875 244.786132812 133.1953125 240.114257812 133.1953125 240.114257812 c 1
829.455078125 781.646484375 m 1
829.455078125 781.645507812 l 1
792.041015625 795.248046875 760.869140625 792.16796875 741.635742188 772.922851562 c 0
733.508789062 764.796875 733.508789062 751.620117188 741.635742188 743.482421875 c 0
749.764648438 735.364257812 762.939453125 735.354492188 771.069335938 743.482421875 c 0
777.907226562 750.30859375 794.809570312 749.956054688 815.208007812 742.526367188 c 0
841.3828125 732.993164062 871.2109375 712.708007812 897.041015625 686.876953125 c 0
952.763671875 631.153320312 967.78125 575.046875 953.635742188 560.903320312 c 0
945.508789062 552.776367188 945.508789062 539.599609375 953.635742188 531.4609375 c 0
957.70703125 527.401367188 963.024414062 525.373046875 968.352539062 525.373046875 c 0
973.680664062 525.373046875 979 527.401367188 983.067382812 531.47265625 c 0
1019.61816406 568.0234375 995.288085938 647.485351562 926.47265625 716.319335938 c 0
896.052734375 746.73046875 861.592773438 769.926757812 829.455078125 781.646484375 c 1
748.963867188 663.739257812 m 1
748.96484375 663.73828125 l 1
755.135742188 669.899414062 792.102539062 663.115234375 832.69140625 622.525390625 c 0
873.270507812 581.946289062 880.076171875 544.970703125 873.904296875 538.798828125 c 0
865.788085938 530.669921875 865.788085938 517.484375 873.915039062 509.357421875 c 0
877.984375 505.297851562 883.303710938 503.268554688 888.631835938 503.268554688 c 0
893.958984375 503.268554688 899.2890625 505.297851562 903.356445312 509.3671875 c 0
932.717773438 538.74609375 915.375976562 598.71484375 862.123046875 651.959960938 c 0
808.888671875 705.224609375 748.888671875 722.555664062 719.528320312 693.184570312 c 0
711.401367188 685.056640625 711.401367188 671.879882812 719.528320312 663.743164062 c 0
727.661132812 655.600585938 740.825195312 655.62109375 748.963867188 663.739257812 c 1
213.166015625 -210 m 1
231.399414062 -210 247.083984375 -204.524414062 258.532226562 -193.078125 c 0
266.661132812 -184.94921875 266.661132812 -171.772460938 258.532226562 -163.635742188 c 0
250.403320312 -155.497070312 237.227539062 -155.506835938 229.098632812 -163.635742188 c 0
214.944335938 -177.799804688 158.858398438 -162.770507812 103.127929688 -107.0390625 c 0
77.3056640625 -81.208984375 57.01171875 -51.380859375 47.478515625 -25.2060546875 c 0
40.046875 -4.818359375 39.6826171875 12.095703125 46.5205078125 18.931640625 c 0
54.6494140625 27.0595703125 54.6494140625 40.2353515625 46.5205078125 48.3740234375 c 0
38.3935546875 56.5126953125 25.2177734375 56.5009765625 17.0888671875 48.3740234375 c 0
-2.1630859375 29.1337890625 -5.2548828125 -2.056640625 8.3583984375 -39.4521484375 c 0
20.06640625 -71.5888671875 43.2763671875 -106.049804688 73.6953125 -136.470703125 c 0
120.946289062 -183.729492188 173.2109375 -210.008789062 213.166015625 -210 c 1
138.03515625 -72.1201171875 m 1
160.764648438 -94.8388671875 186.5859375 -112.198242188 210.741210938 -120.9921875 c 0
223.53125 -125.655273438 234.375976562 -127.456054688 243.53515625 -127.456054688 c 0
262.7890625 -127.456054688 274.487304688 -119.473632812 280.627929688 -113.333007812 c 0
288.744140625 -105.204101562 288.744140625 -92.017578125 280.6171875 -83.890625 c 0
272.490234375 -75.7744140625 259.302734375 -75.7626953125 251.17578125 -83.890625 c 0
248.990234375 -86.1083984375 240.174804688 -87.408203125 224.979492188 -81.880859375 c 0
206.673828125 -75.2099609375 185.711914062 -60.921875 167.458007812 -42.67578125 c 0
149.212890625 -24.4306640625 134.924804688 -3.458984375 128.252929688 14.845703125 c 0
122.7265625 30.01953125 124.02734375 38.8251953125 126.245117188 41.041015625 c 0
134.374023438 49.16796875 134.374023438 62.34375 126.245117188 70.4833984375 c 0
118.116210938 78.6220703125 104.940429688 78.6103515625 96.8134765625 70.4833984375 c 0
87.748046875 61.4169921875 74.6875 40.279296875 89.1416015625 0.5966796875 c 0
97.9560546875 -23.5703125 115.315429688 -49.400390625 138.03515625 -72.1201171875 c 1
802.430664062 155.80859375 m 0
715.083007812 155.80859375 644.194335938 84.919921875 644.194335938 -2.427734375 c 0
644.194335938 -89.775390625 715.083007812 -160.6640625 802.430664062 -160.6640625 c 0
889.778320312 -160.6640625 960.666992188 -89.775390625 960.666992188 -2.427734375 c 0
960.666992188 84.919921875 889.778320312 155.80859375 802.430664062 155.80859375 c 0
904.14453125 -98.1357421875 m 1
720.125976562 -98.1357421875 l 1
720.125976562 85.939453125 l 1
780.458984375 85.939453125 l 1
780.458984375 -64.6650390625 l 1
904.14453125 -64.6650390625 l 1
904.14453125 -98.1357421875 l 1
802.430664062 -209.9921875 m 0
830.4453125 -209.9921875 857.633789062 -204.500976562 883.227539062 -193.674804688 c 0
907.9453125 -183.221679688 930.141601562 -168.25390625 949.19921875 -149.196289062 c 0
968.2578125 -130.138671875 983.224609375 -107.942382812 993.678710938 -83.2236328125 c 0
1004.50390625 -57.6298828125 1009.99609375 -30.44140625 1009.99609375 -2.427734375 c 0
1009.99609375 25.5869140625 1004.50390625 52.775390625 993.678710938 78.369140625 c 0
983.224609375 103.087890625 968.2578125 125.284179688 949.19921875 144.341796875 c 0
930.141601562 163.399414062 907.9453125 178.3671875 883.227539062 188.8203125 c 0
857.6328125 199.646484375 830.4453125 205.137695312 802.430664062 205.137695312 c 0
774.416015625 205.137695312 747.227539062 199.646484375 721.633789062 188.8203125 c 0
696.916015625 178.3671875 674.719726562 163.399414062 655.662109375 144.341796875 c 0
636.603515625 125.284179688 621.63671875 103.087890625 611.182617188 78.369140625 c 0
600.357421875 52.775390625 594.865234375 25.5869140625 594.865234375 -2.427734375 c 0
594.865234375 -30.44140625 600.357421875 -57.6298828125 611.182617188 -83.2236328125 c 0
621.63671875 -107.942382812 636.603515625 -130.138671875 655.662109375 -149.196289062 c 0
674.719726562 -168.25390625 696.916015625 -183.221679688 721.633789062 -193.674804688 c 0
747.228515625 -204.500976562 774.411132812 -209.9921875 802.430664062 -209.9921875 c 0
802.430664062 183.87890625 m 0
905.1640625 183.87890625 988.736328125 100.299804688 988.736328125 -2.427734375 c 0
988.736328125 -105.155273438 905.1640625 -188.733398438 802.430664062 -188.733398438 c 0
699.697265625 -188.733398438 616.124023438 -105.161132812 616.124023438 -2.427734375 c 0
616.124023438 100.305664062 699.703125 183.87890625 802.430664062 183.87890625 c 0
EndSplineSet
Validated: 524325
EndChar
EndChars
EndSplineFont

217
3rdparty/vulkan/include/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,217 @@
# 3.2.0 (2024-12-30)
Additions to the library API:
- Added support for Vulkan 1.4.
- Added support for VK_KHR_external_memory_win32 extension - `VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT` flag, `vmaGetMemoryWin32Handle` function, and a whole new documentation chapter about it (#442).
Other changes:
- Fixed thread safety issue (#451).
- Many other bug fixes and improvements in the library code, documentation, sample app, Cmake script, mostly to improve compatibility with various compilers and GPUs.
# 3.1.0 (2024-05-27)
This release gathers fixes and improvements made during many months of continuous development on the main branch, mostly based on issues and pull requests on GitHub.
Additions to the library API:
- Added convenience functions `vmaCopyMemoryToAllocation`, `vmaCopyAllocationToMemory`.
- Added functions `vmaCreateAliasingBuffer2`, `vmaCreateAliasingImage2` that offer creating a buffer/image in an existing allocation with additional `allocationLocalOffset`.
- Added function `vmaGetAllocationInfo2`, structure `VmaAllocationInfo2` that return additional information about an allocation, useful for interop with other APIs (#383, #340).
- Added callback `VmaDefragmentationInfo::pfnBreakCallback` that allows breaking long execution of `vmaBeginDefragmentation`.
Also added `PFN_vmaCheckDefragmentationBreakFunction`, `VmaDefragmentationInfo::pBreakCallbackUserData`.
- Added support for VK_KHR_maintenance4 extension - `VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT` flag (#397).
- Added support for VK_KHR_maintenance5 extension - `VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT` flag (#411).
Other changes:
- Changes in debug and configuration macros:
- Split macros into separate `VMA_DEBUG_LOG` and `VMA_DEBUG_LOG_FORMAT` (#297).
- Added macros `VMA_ASSERT_LEAK`, `VMA_LEAK_LOG_FORMAT` separate from normal `VMA_ASSERT`, `VMA_DEBUG_LOG_FORMAT` (#379, #385).
- Added macro `VMA_EXTENDS_VK_STRUCT` (#347).
- Countless bug fixes and improvements in the code and documentation, mostly to improve compatibility with various compilers and GPUs, including:
- Fixed missing `#include` that resulted in compilation error about `snprintf` not declared on some compilers (#312).
- Fixed main memory type selection algorithm for GPUs that have no `HOST_CACHED` memory type, like Raspberry Pi (#362).
- Major changes in Cmake script.
- Fixes in GpuMemDumpVis.py script.
# 3.0.1 (2022-05-26)
- Fixes in defragmentation algorithm.
- Fixes in GpuMemDumpVis.py regarding image height calculation.
- Other bug fixes, optimizations, and improvements in the code and documentation.
# 3.0.0 (2022-03-25)
It has been a long time since the previous official release, so hopefully everyone has been using the latest code from "master" branch, which is always maintained in a good state, not the old version. For completeness, here is the list of changes since v2.3.0. The major version number has changed, so there are some compatibility-breaking changes, but the basic API stays the same and is mostly backward-compatible.
Major features added (some compatibility-breaking):
- Added new API for selecting preferred memory type: flags `VMA_MEMORY_USAGE_AUTO`, `VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE`, `VMA_MEMORY_USAGE_AUTO_PREFER_HOST`, `VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT`, `VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT`, `VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT`. Old values like `VMA_MEMORY_USAGE_GPU_ONLY` still work as before, for backward compatibility, but are not recommended.
- Added new defragmentation API and algorithm, replacing the old one. See structure `VmaDefragmentationInfo`, `VmaDefragmentationMove`, `VmaDefragmentationPassMoveInfo`, `VmaDefragmentationStats`, function `vmaBeginDefragmentation`, `vmaEndDefragmentation`, `vmaBeginDefragmentationPass`, `vmaEndDefragmentationPass`.
- Redesigned API for statistics, replacing the old one. See structures: `VmaStatistics`, `VmaDetailedStatistics`, `VmaTotalStatistics`. `VmaBudget`, functions: `vmaGetHeapBudgets`, `vmaCalculateStatistics`, `vmaGetPoolStatistics`, `vmaCalculatePoolStatistics`, `vmaGetVirtualBlockStatistics`, `vmaCalculateVirtualBlockStatistics`.
- Added "Virtual allocator" feature - possibility to use core allocation algorithms for allocation of custom memory, not necessarily Vulkan device memory. See functions like `vmaCreateVirtualBlock`, `vmaDestroyVirtualBlock` and many more.
- `VmaAllocation` now keeps both `void* pUserData` and `char* pName`. Added function `vmaSetAllocationName`, member `VmaAllocationInfo::pName`. Flag `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` is now deprecated.
- Clarified and cleaned up various ways of importing Vulkan functions. See macros `VMA_STATIC_VULKAN_FUNCTIONS`, `VMA_DYNAMIC_VULKAN_FUNCTIONS`, structure `VmaVulkanFunctions`. Added members `VmaVulkanFunctions::vkGetInstanceProcAddr`, `vkGetDeviceProcAddr`, which are now required when using `VMA_DYNAMIC_VULKAN_FUNCTIONS`.
Removed (compatibility-breaking):
- Removed whole "lost allocations" feature. Removed from the interface: `VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT`, `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT`, `vmaCreateLostAllocation`, `vmaMakePoolAllocationsLost`, `vmaTouchAllocation`, `VmaAllocatorCreateInfo::frameInUseCount`, `VmaPoolCreateInfo::frameInUseCount`.
- Removed whole "record & replay" feature. Removed from the API: `VmaAllocatorCreateInfo::pRecordSettings`, `VmaRecordSettings`, `VmaRecordFlagBits`, `VmaRecordFlags`. Removed VmaReplay application.
- Removed "buddy" algorithm - removed flag `VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT`.
Minor but compatibility-breaking changes:
- Changes in `ALLOCATION_CREATE_STRATEGY` flags. Removed flags: `VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT`, `VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT`, which were aliases to other existing flags.
- Added a member `void* pUserData` to `VmaDeviceMemoryCallbacks`. Updated `PFN_vmaAllocateDeviceMemoryFunction`, `PFN_vmaFreeDeviceMemoryFunction` to use the new `pUserData` member.
- Removed function `vmaResizeAllocation` that was already deprecated.
Other major changes:
- Added new features to custom pools: support for dedicated allocations, new member `VmaPoolCreateInfo::pMemoryAllocateNext`, `minAllocationAlignment`.
- Added support for Vulkan 1.2, 1.3.
- Added support for VK_KHR_buffer_device_address extension - flag `VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT`.
- Added support for VK_EXT_memory_priority extension - flag `VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT`, members `VmaAllocationCreateInfo::priority`, `VmaPoolCreateInfo::priority`.
- Added support for VK_AMD_device_coherent_memory extension - flag `VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT`.
- Added member `VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes`.
- Added function `vmaGetAllocatorInfo`, structure `VmaAllocatorInfo`.
- Added functions `vmaFlushAllocations`, `vmaInvalidateAllocations` for multiple allocations at once.
- Added flag `VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT`.
- Added function `vmaCreateBufferWithAlignment`.
- Added convenience function `vmaGetAllocationMemoryProperties`.
- Added convenience functions: `vmaCreateAliasingBuffer`, `vmaCreateAliasingImage`.
Other minor changes:
- Implemented Two-Level Segregated Fit (TLSF) allocation algorithm, replacing previous default one. It is much faster, especially when freeing many allocations at once or when `bufferImageGranularity` is large.
- Renamed debug macro `VMA_DEBUG_ALIGNMENT` to `VMA_MIN_ALIGNMENT`.
- Added CMake support - CMakeLists.txt files. Removed Premake support.
- Changed `vmaInvalidateAllocation` and `vmaFlushAllocation` to return `VkResult`.
- Added nullability annotations for Clang: `VMA_NULLABLE`, `VMA_NOT_NULL`, `VMA_NULLABLE_NON_DISPATCHABLE`, `VMA_NOT_NULL_NON_DISPATCHABLE`, `VMA_LEN_IF_NOT_NULL`.
- JSON dump format has changed.
- Countless fixes and improvements, including performance optimizations, compatibility with various platforms and compilers, documentation.
# 2.3.0 (2019-12-04)
Major release after a year of development in "master" branch and feature branches. Notable new features: supporting Vulkan 1.1, supporting query for memory budget.
Major changes:
- Added support for Vulkan 1.1.
- Added member `VmaAllocatorCreateInfo::vulkanApiVersion`.
- When Vulkan 1.1 is used, there is no need to enable VK_KHR_dedicated_allocation or VK_KHR_bind_memory2 extensions, as they are promoted to Vulkan itself.
- Added support for query for memory budget and staying within the budget.
- Added function `vmaGetBudget`, structure `VmaBudget`. This can also serve as simple statistics, more efficient than `vmaCalculateStats`.
- By default the budget it is estimated based on memory heap sizes. It may be queried from the system using VK_EXT_memory_budget extension if you use `VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT` flag and `VmaAllocatorCreateInfo::instance` member.
- Added flag `VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT` that fails an allocation if it would exceed the budget.
- Added new memory usage options:
- `VMA_MEMORY_USAGE_CPU_COPY` for memory that is preferably not `DEVICE_LOCAL` but not guaranteed to be `HOST_VISIBLE`.
- `VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED` for memory that is `LAZILY_ALLOCATED`.
- Added support for VK_KHR_bind_memory2 extension:
- Added `VMA_ALLOCATION_CREATE_DONT_BIND_BIT` flag that lets you create both buffer/image and allocation, but don't bind them together.
- Added flag `VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT`, functions `vmaBindBufferMemory2`, `vmaBindImageMemory2` that let you specify additional local offset and `pNext` pointer while binding.
- Added functions `vmaSetPoolName`, `vmaGetPoolName` that let you assign string names to custom pools. JSON dump file format and VmaDumpVis tool is updated to show these names.
- Defragmentation is legal only on buffers and images in `VK_IMAGE_TILING_LINEAR`. This is due to the way it is currently implemented in the library and the restrictions of the Vulkan specification. Clarified documentation in this regard. See discussion in #59.
Minor changes:
- Made `vmaResizeAllocation` function deprecated, always returning failure.
- Made changes in the internal algorithm for the choice of memory type. Be careful! You may now get a type that is not `HOST_VISIBLE` or `HOST_COHERENT` if it's not stated as always ensured by some `VMA_MEMORY_USAGE_*` flag.
- Extended VmaReplay application with more detailed statistics printed at the end.
- Added macros `VMA_CALL_PRE`, `VMA_CALL_POST` that let you decorate declarations of all library functions if you want to e.g. export/import them as dynamically linked library.
- Optimized `VmaAllocation` objects to be allocated out of an internal free-list allocator. This makes allocation and deallocation causing 0 dynamic CPU heap allocations on average.
- Updated recording CSV file format version to 1.8, to support new functions.
- Many additions and fixes in documentation. Many compatibility fixes for various compilers and platforms. Other internal bugfixes, optimizations, updates, refactoring...
# 2.2.0 (2018-12-13)
Major release after many months of development in "master" branch and feature branches. Notable new features: defragmentation of GPU memory, buddy algorithm, convenience functions for sparse binding.
Major changes:
- New, more powerful defragmentation:
- Added structure `VmaDefragmentationInfo2`, functions `vmaDefragmentationBegin`, `vmaDefragmentationEnd`.
- Added support for defragmentation of GPU memory.
- Defragmentation of CPU memory now uses `memmove`, so it can move data to overlapping regions.
- Defragmentation of CPU memory is now available for memory types that are `HOST_VISIBLE` but not `HOST_COHERENT`.
- Added structure member `VmaVulkanFunctions::vkCmdCopyBuffer`.
- Major internal changes in defragmentation algorithm.
- VmaReplay: added parameters: `--DefragmentAfterLine`, `--DefragmentationFlags`.
- Old interface (structure `VmaDefragmentationInfo`, function `vmaDefragment`) is now deprecated.
- Added buddy algorithm, available for custom pools - flag `VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT`.
- Added convenience functions for multiple allocations and deallocations at once, intended for sparse binding resources - functions `vmaAllocateMemoryPages`, `vmaFreeMemoryPages`.
- Added function that tries to resize existing allocation in place: `vmaResizeAllocation`.
- Added flags for allocation strategy: `VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT`, and their aliases: `VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT`.
Minor changes:
- Changed behavior of allocation functions to return `VK_ERROR_VALIDATION_FAILED_EXT` when trying to allocate memory of size 0, create buffer with size 0, or image with one of the dimensions 0.
- VmaReplay: Added support for Windows end of lines.
- Updated recording CSV file format version to 1.5, to support new functions.
- Internal optimization: using read-write mutex on some platforms.
- Many additions and fixes in documentation. Many compatibility fixes for various compilers. Other internal bugfixes, optimizations, refactoring, added more internal validation...
# 2.1.0 (2018-09-10)
Minor bugfixes.
# 2.1.0-beta.1 (2018-08-27)
Major release after many months of development in "development" branch and features branches. Many new features added, some bugs fixed. API stays backward-compatible.
Major changes:
- Added linear allocation algorithm, accessible for custom pools, that can be used as free-at-once, stack, double stack, or ring buffer. See "Linear allocation algorithm" documentation chapter.
- Added `VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT`, `VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT`.
- Added feature to record sequence of calls to the library to a file and replay it using dedicated application. See documentation chapter "Record and replay".
- Recording: added `VmaAllocatorCreateInfo::pRecordSettings`.
- Replaying: added VmaReplay project.
- Recording file format: added document "docs/Recording file format.md".
- Improved support for non-coherent memory.
- Added functions: `vmaFlushAllocation`, `vmaInvalidateAllocation`.
- `nonCoherentAtomSize` is now respected automatically.
- Added `VmaVulkanFunctions::vkFlushMappedMemoryRanges`, `vkInvalidateMappedMemoryRanges`.
- Improved debug features related to detecting incorrect mapped memory usage. See documentation chapter "Debugging incorrect memory usage".
- Added debug macro `VMA_DEBUG_DETECT_CORRUPTION`, functions `vmaCheckCorruption`, `vmaCheckPoolCorruption`.
- Added debug macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to initialize contents of allocations with a bit pattern.
- Changed behavior of `VMA_DEBUG_MARGIN` macro - it now adds margin also before first and after last allocation in a block.
- Changed format of JSON dump returned by `vmaBuildStatsString` (not backward compatible!).
- Custom pools and memory blocks now have IDs that don't change after sorting.
- Added properties: "CreationFrameIndex", "LastUseFrameIndex", "Usage".
- Changed VmaDumpVis tool to use these new properties for better coloring.
- Changed behavior of `vmaGetAllocationInfo` and `vmaTouchAllocation` to update `allocation.lastUseFrameIndex` even if allocation cannot become lost.
Minor changes:
- Changes in custom pools:
- Added new structure member `VmaPoolStats::blockCount`.
- Changed behavior of `VmaPoolCreateInfo::blockSize` = 0 (default) - it now means that pool may use variable block sizes, just like default pools do.
- Improved logic of `vmaFindMemoryTypeIndex` for some cases, especially integrated GPUs.
- VulkanSample application: Removed dependency on external library MathFu. Added own vector and matrix structures.
- Changes that improve compatibility with various platforms, including: Visual Studio 2012, 32-bit code, C compilers.
- Changed usage of "VK_KHR_dedicated_allocation" extension in the code to be optional, driven by macro `VMA_DEDICATED_ALLOCATION`, for compatibility with Android.
- Many additions and fixes in documentation, including description of new features, as well as "Validation layer warnings".
- Other bugfixes.
# 2.0.0 (2018-03-19)
A major release with many compatibility-breaking changes.
Notable new features:
- Introduction of `VmaAllocation` handle that you must retrieve from allocation functions and pass to deallocation functions next to normal `VkBuffer` and `VkImage`.
- Introduction of `VmaAllocationInfo` structure that you can retrieve from `VmaAllocation` handle to access parameters of the allocation (like `VkDeviceMemory` and offset) instead of retrieving them directly from allocation functions.
- Support for reference-counted mapping and persistently mapped allocations - see `vmaMapMemory`, `VMA_ALLOCATION_CREATE_MAPPED_BIT`.
- Support for custom memory pools - see `VmaPool` handle, `VmaPoolCreateInfo` structure, `vmaCreatePool` function.
- Support for defragmentation (compaction) of allocations - see function `vmaDefragment` and related structures.
- Support for "lost allocations" - see appropriate chapter on documentation Main Page.
# 1.0.1 (2017-07-04)
- Fixes for Linux GCC compilation.
- Changed "CONFIGURATION SECTION" to contain #ifndef so you can define these macros before including this header, not necessarily change them in the file.
# 1.0.0 (2017-06-16)
First public release.

196
3rdparty/vulkan/include/README.md vendored Normal file
View File

@@ -0,0 +1,196 @@
# Vulkan Memory Allocator
Easy to integrate Vulkan memory allocation library.
**Documentation:** Browse online: [Vulkan Memory Allocator](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/) (generated from Doxygen-style comments in [include/vk_mem_alloc.h](include/vk_mem_alloc.h))
**License:** MIT. See [LICENSE.txt](LICENSE.txt)
**Changelog:** See [CHANGELOG.md](CHANGELOG.md)
**Product page:** [Vulkan Memory Allocator on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/)
**Build status:**
- Windows: [![Build status](https://ci.appveyor.com/api/projects/status/4vlcrb0emkaio2pn/branch/master?svg=true)](https://ci.appveyor.com/project/adam-sawicki-amd/vulkanmemoryallocator/branch/master)
- Linux: [![Build Status](https://app.travis-ci.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.svg?branch=master)](https://app.travis-ci.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.svg)](http://isitmaintained.com/project/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator "Average time to resolve an issue")
# Problem
Memory allocation and resource (buffer and image) creation in Vulkan is difficult (comparing to older graphics APIs, like D3D11 or OpenGL) for several reasons:
- It requires a lot of boilerplate code, just like everything else in Vulkan, because it is a low-level and high-performance API.
- There is additional level of indirection: `VkDeviceMemory` is allocated separately from creating `VkBuffer`/`VkImage` and they must be bound together.
- Driver must be queried for supported memory heaps and memory types. Different GPU vendors provide different types of it.
- It is recommended to allocate bigger chunks of memory and assign parts of them to particular resources, as there is a limit on maximum number of memory blocks that can be allocated.
# Features
This library can help game developers to manage memory allocations and resource creation by offering some higher-level functions:
1. Functions that help to choose correct and optimal memory type based on intended usage of the memory.
- Required or preferred traits of the memory are expressed using higher-level description comparing to Vulkan flags.
2. Functions that allocate memory blocks, reserve and return parts of them (`VkDeviceMemory` + offset + size) to the user.
- Library keeps track of allocated memory blocks, used and unused ranges inside them, finds best matching unused ranges for new allocations, respects all the rules of alignment and buffer/image granularity.
3. Functions that can create an image/buffer, allocate memory for it and bind them together - all in one call.
Additional features:
- Well-documented - description of all functions and structures provided, along with chapters that contain general description and example code.
- Thread-safety: Library is designed to be used in multithreaded code. Access to a single device memory block referred by different buffers and textures (binding, mapping) is synchronized internally. Memory mapping is reference-counted.
- Configuration: Fill optional members of `VmaAllocatorCreateInfo` structure to provide custom CPU memory allocator, pointers to Vulkan functions and other parameters.
- Customization and integration with custom engines: Predefine appropriate macros to provide your own implementation of all external facilities used by the library like assert, mutex, atomic.
- Support for memory mapping, reference-counted internally. Support for persistently mapped memory: Just allocate with appropriate flag and access the pointer to already mapped memory.
- Support for non-coherent memory. Functions that flush/invalidate memory. `nonCoherentAtomSize` is respected automatically.
- Support for resource aliasing (overlap).
- Support for sparse binding and sparse residency: Convenience functions that allocate or free multiple memory pages at once.
- Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size) and allocate memory out of it.
- Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
- Support for Vulkan 1.0...1.4.
- Support for extensions (and equivalent functionality included in new Vulkan versions):
- VK_KHR_dedicated_allocation: Just enable it and it will be used automatically by the library.
- VK_KHR_bind_memory2.
- VK_KHR_maintenance4.
- VK_KHR_maintenance5, including `VkBufferUsageFlags2CreateInfoKHR`.
- VK_EXT_memory_budget: Used internally if available to query for current usage and budget. If not available, it falls back to an estimation based on memory heap sizes.
- VK_KHR_buffer_device_address: Flag `VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR` is automatically added to memory allocations where needed.
- VK_EXT_memory_priority: Set `priority` of allocations or custom pools and it will be set automatically using this extension.
- VK_AMD_device_coherent_memory.
- VK_KHR_external_memory_win32.
- Defragmentation of GPU and CPU memory: Let the library move data around to free some memory blocks and make your allocations better compacted.
- Statistics: Obtain brief or detailed statistics about the amount of memory used, unused, number of allocated blocks, number of allocations etc. - globally, per memory heap, and per memory type.
- Debug annotations: Associate custom `void* pUserData` and debug `char* pName` with each allocation.
- JSON dump: Obtain a string in JSON format with detailed map of internal state, including list of allocations, their string names, and gaps between them.
- Convert this JSON dump into a picture to visualize your memory. See [tools/GpuMemDumpVis](tools/GpuMemDumpVis/README.md).
- Debugging incorrect memory usage: Enable initialization of all allocated memory with a bit pattern to detect usage of uninitialized or freed memory. Enable validation of a magic number after every allocation to detect out-of-bounds memory corruption.
- Support for interoperability with OpenGL.
- Virtual allocator: Interface for using core allocation algorithm to allocate any custom data, e.g. pieces of one large buffer.
# Prerequisites
- Self-contained C++ library in single header file. No external dependencies other than standard C and C++ library and of course Vulkan. Some features of C++14 used. STL containers, RTTI, or C++ exceptions are not used.
- Public interface in C, in same convention as Vulkan API. Implementation in C++.
- Error handling implemented by returning `VkResult` error codes - same way as in Vulkan.
- Interface documented using Doxygen-style comments.
- Platform-independent, but developed and tested on Windows using Visual Studio. Continuous integration setup for Windows and Linux. Used also on Android, MacOS, and other platforms.
# Example
Basic usage of this library is very simple. Advanced features are optional. After you created global `VmaAllocator` object, a complete code needed to create a buffer may look like this:
```cpp
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = 65536;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
```
With this one function call:
1. `VkBuffer` is created.
2. `VkDeviceMemory` block is allocated if needed.
3. An unused region of the memory block is bound to this buffer.
`VmaAllocation` is an object that represents memory assigned to this buffer. It can be queried for parameters like `VkDeviceMemory` handle and offset.
# How to build
On Windows it is recommended to use [CMake GUI](https://cmake.org/runningcmake/).
Alternatively you can generate/open a Visual Studio from the command line:
```sh
# By default CMake picks the newest version of Visual Studio it can use
cmake -S . -B build -D VMA_BUILD_SAMPLES=ON
cmake --open build
```
On Linux:
```sh
cmake -S . -B build
# Since VMA has no source files, you can skip to installation immediately
cmake --install build --prefix build/install
```
## How to use
After calling either `find_package` or `add_subdirectory` simply link the library.
This automatically handles configuring the include directory. Example:
```cmake
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
target_link_libraries(YourGameEngine PRIVATE GPUOpen::VulkanMemoryAllocator)
```
For more info on using CMake visit the official [CMake documentation](https://cmake.org/cmake/help/latest/index.html).
## Building using vcpkg
You can download and install VulkanMemoryAllocator using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install vulkan-memory-allocator
The VulkanMemoryAllocator port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
# Binaries
The release comes with precompiled binary executable for "VulkanSample" application which contains test suite. It is compiled using Visual Studio 2022, so it requires appropriate libraries to work, including "MSVCP140.dll", "VCRUNTIME140.dll", "VCRUNTIME140_1.dll". If the launch fails with error message telling about those files missing, please download and install [Microsoft Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), "X64" version.
# Read more
See **[Documentation](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/)**.
# Software using this library
- **[Blender](https://www.blender.org)**
- **[Qt Project](https://github.com/qt)**
- **[Baldur's Gate III](https://www.mobygames.com/game/150689/baldurs-gate-iii/credits/windows/?autoplatform=true)**
- **[Cyberpunk 2077](https://www.mobygames.com/game/128136/cyberpunk-2077/credits/windows/?autoplatform=true)**
- **[X-Plane](https://x-plane.com/)**
- **[Detroit: Become Human](https://gpuopen.com/learn/porting-detroit-3/)**
- **[Vulkan Samples](https://github.com/LunarG/VulkanSamples)** - official Khronos Vulkan samples. License: Apache-style.
- **[GFXReconstruct](https://github.com/LunarG/gfxreconstruct)** - a tools for the capture and replay of graphics API calls. License: MIT.
- **[Anvil](https://github.com/GPUOpen-LibrariesAndSDKs/Anvil)** - cross-platform framework for Vulkan. License: MIT.
- **[Filament](https://github.com/google/filament)** - physically based rendering engine for Android, Windows, Linux and macOS, from Google. Apache License 2.0.
- **[Atypical Games - proprietary game engine](https://developer.samsung.com/galaxy-gamedev/gamedev-blog/infinitejet.html)**
- **[Flax Engine](https://flaxengine.com/)**
- **[Godot Engine](https://github.com/godotengine/godot/)** - multi-platform 2D and 3D game engine. License: MIT.
- **[Lightweight Java Game Library (LWJGL)](https://www.lwjgl.org/)** - includes binding of the library for Java. License: BSD.
- **[LightweightVK](https://github.com/corporateshark/lightweightvk)** - lightweight C++ bindless Vulkan 1.3 wrapper. License: MIT.
- **[PowerVR SDK](https://github.com/powervr-graphics/Native_SDK)** - C++ cross-platform 3D graphics SDK, from Imagination. License: MIT.
- **[Skia](https://github.com/google/skia)** - complete 2D graphic library for drawing Text, Geometries, and Images, from Google.
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
- **[VK9](https://github.com/disks86/VK9)** - Direct3D 9 compatibility layer using Vulkan. Zlib license.
- **[vkDOOM3](https://github.com/DustinHLand/vkDOOM3)** - Vulkan port of GPL DOOM 3 BFG Edition. License: GNU GPL.
- **[vkQuake2](https://github.com/kondrak/vkQuake2)** - vanilla Quake 2 with Vulkan support. License: GNU GPL.
- **[Vulkan Best Practice for Mobile Developers](https://github.com/ARM-software/vulkan_best_practice_for_mobile_developers)** from ARM. License: MIT.
- **[RPCS3](https://github.com/RPCS3/rpcs3)** - PlayStation 3 emulator/debugger. License: GNU GPLv2.
- **[PPSSPP](https://github.com/hrydgard/ppsspp)** - Playstation Portable emulator/debugger. License: GNU GPLv2+.
- **[Wicked Engine](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
[Many other projects on GitHub](https://github.com/search?q=AMD_VULKAN_MEMORY_ALLOCATOR_H&type=Code) and some game development studios that use Vulkan in their games.
# See also
- **[D3D12 Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator)** - equivalent library for Direct3D 12. License: MIT.
- **[Awesome Vulkan](https://github.com/vinjn/awesome-vulkan)** - a curated list of awesome Vulkan libraries, debuggers and resources.
- **[vcpkg](https://github.com/Microsoft/vcpkg)** dependency manager from Microsoft also offers a port of this library.
- **[VulkanMemoryAllocator-Hpp](https://github.com/YaaZ/VulkanMemoryAllocator-Hpp)** - C++ binding for this library. License: CC0-1.0.
- **[PyVMA](https://github.com/realitix/pyvma)** - Python wrapper for this library. Author: Jean-Sébastien B. (@realitix). License: Apache 2.0.
- **[vk-mem](https://github.com/gwihlidal/vk-mem-rs)** - Rust binding for this library. Author: Graham Wihlidal. License: Apache 2.0 or MIT.
- **[Haskell bindings](https://hackage.haskell.org/package/VulkanMemoryAllocator)**, **[github](https://github.com/expipiplus1/vulkan/tree/master/VulkanMemoryAllocator)** - Haskell bindings for this library. Author: Ellie Hermaszewska (@expipiplus1). License BSD-3-Clause.
- **[vma_sample_sdl](https://github.com/rextimmy/vma_sample_sdl)** - SDL port of the sample app of this library (with the goal of running it on multiple platforms, including MacOS). Author: @rextimmy. License: MIT.
- **[vulkan-malloc](https://github.com/dylanede/vulkan-malloc)** - Vulkan memory allocation library for Rust. Based on version 1 of this library. Author: Dylan Ede (@dylanede). License: MIT / Apache 2.0.

View File

@@ -25,7 +25,7 @@
/** \mainpage Vulkan Memory Allocator
<b>Version 3.1.0</b>
<b>Version 3.2.0</b>
Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved. \n
License: MIT \n
@@ -95,6 +95,7 @@ See also: [product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-me
- \subpage enabling_buffer_device_address
- \subpage vk_ext_memory_priority
- \subpage vk_amd_device_coherent_memory
- \subpage vk_khr_external_memory_win32
- \subpage general_considerations
- [Thread safety](@ref general_considerations_thread_safety)
- [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility)
@@ -127,10 +128,14 @@ See documentation chapter: \ref statistics.
extern "C" {
#endif
#if !defined(VULKAN_H_)
#include <vulkan/vulkan.h>
#endif
#if !defined(VMA_VULKAN_VERSION)
#if defined(VK_VERSION_1_3)
#if defined(VK_VERSION_1_4)
#define VMA_VULKAN_VERSION 1004000
#elif defined(VK_VERSION_1_3)
#define VMA_VULKAN_VERSION 1003000
#elif defined(VK_VERSION_1_2)
#define VMA_VULKAN_VERSION 1002000
@@ -240,6 +245,15 @@ extern "C" {
#endif
#endif
// Defined to 1 when VK_KHR_external_memory_win32 device extension is defined in Vulkan headers.
#if !defined(VMA_EXTERNAL_MEMORY_WIN32)
#if VK_KHR_external_memory_win32
#define VMA_EXTERNAL_MEMORY_WIN32 1
#else
#define VMA_EXTERNAL_MEMORY_WIN32 0
#endif
#endif
// Define these macros to decorate all public functions with additional code,
// before and after returned type, appropriately. This may be useful for
// exporting the functions when compiling VMA as a separate library. Example:
@@ -459,6 +473,15 @@ typedef enum VmaAllocatorCreateFlagBits
*/
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT = 0x00000100,
/**
Enables usage of VK_KHR_external_memory_win32 extension in the library.
You should set this flag if you found available and enabled this device extension,
while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
For more information, see \ref vk_khr_external_memory_win32.
*/
VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT = 0x00000200,
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocatorCreateFlagBits;
/// See #VmaAllocatorCreateFlagBits.
@@ -1033,6 +1056,11 @@ typedef struct VmaVulkanFunctions
/// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
PFN_vkGetDeviceImageMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
PFN_vkGetMemoryWin32HandleKHR VMA_NULLABLE vkGetMemoryWin32HandleKHR;
#else
void* VMA_NULLABLE vkGetMemoryWin32HandleKHR;
#endif
} VmaVulkanFunctions;
/// Description of a Allocator to be created.
@@ -1095,7 +1123,7 @@ typedef struct VmaAllocatorCreateInfo
It must be a value in the format as created by macro `VK_MAKE_VERSION` or a constant like: `VK_API_VERSION_1_1`, `VK_API_VERSION_1_0`.
The patch version number specified is ignored. Only the major and minor versions are considered.
Only versions 1.0, 1.1, 1.2, 1.3 are supported by the current implementation.
Only versions 1.0...1.4 are supported by the current implementation.
Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`.
It must match the Vulkan version used by the application and supported on the selected physical device,
so it must be no higher than `VkApplicationInfo::apiVersion` passed to `vkCreateInstance`
@@ -1810,6 +1838,9 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool(
\param allocator Allocator object.
\param pool Pool object.
\param[out] pPoolStats Statistics of specified pool.
Note that when using the pool from multiple threads, returned information may immediately
become outdated.
*/
VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics(
VmaAllocator VMA_NOT_NULL allocator,
@@ -2050,6 +2081,40 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
VmaAllocation VMA_NOT_NULL allocation,
VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
#if VMA_EXTERNAL_MEMORY_WIN32
/**
\brief Given an allocation, returns Win32 handle that may be imported by other processes or APIs.
\param hTargetProcess Must be a valid handle to target process or null. If it's null, the function returns
handle for the current process.
\param[out] pHandle Output parameter that returns the handle.
The function fills `pHandle` with handle that can be used in target process.
The handle is fetched using function `vkGetMemoryWin32HandleKHR`.
When no longer needed, you must close it using:
\code
CloseHandle(handle);
\endcode
You can close it any time, before or after destroying the allocation object.
It is reference-counted internally by Windows.
Note the handle is returned for the entire `VkDeviceMemory` block that the allocation belongs to.
If the allocation is sub-allocated from a larger block, you may need to consider the offset of the allocation
(VmaAllocationInfo::offset).
If the function fails with `VK_ERROR_FEATURE_NOT_PRESENT` error code, please double-check
that VmaVulkanFunctions::vkGetMemoryWin32HandleKHR function pointer is set, e.g. either by using `VMA_DYNAMIC_VULKAN_FUNCTIONS`
or by manually passing it through VmaAllocatorCreateInfo::pVulkanFunctions.
For more information, see chapter \ref vk_khr_external_memory_win32.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle);
#endif // VMA_EXTERNAL_MEMORY_WIN32
/** \brief Maps memory represented by given allocation and returns pointer to it.
Maps memory represented by given allocation to make it accessible to CPU code.
@@ -3097,7 +3162,7 @@ static void vma_aligned_free(void* VMA_NULLABLE ptr)
std::shared_mutex m_Mutex;
};
#define VMA_RW_MUTEX VmaRWMutex
#elif defined(_WIN32) && defined(WINVER) && WINVER >= 0x0600
#elif defined(_WIN32) && defined(WINVER) && defined(SRWLOCK_INIT) && WINVER >= 0x0600
// Use SRWLOCK from WinAPI.
// Minimum supported client = Windows Vista, server = Windows Server 2008.
class VmaRWMutex
@@ -3838,12 +3903,6 @@ struct VmaBufferImageUsage
const VmaBufferImageUsage VmaBufferImageUsage::UNKNOWN = VmaBufferImageUsage(0);
static void swap(VmaBufferImageUsage& lhs, VmaBufferImageUsage& rhs) noexcept
{
using std::swap;
swap(lhs.Value, rhs.Value);
}
VmaBufferImageUsage::VmaBufferImageUsage(const VkBufferCreateInfo &createInfo,
bool useKhrMaintenance5)
{
@@ -6073,6 +6132,84 @@ private:
#endif // _VMA_MAPPING_HYSTERESIS
#if VMA_EXTERNAL_MEMORY_WIN32
class VmaWin32Handle
{
public:
VmaWin32Handle() noexcept : m_hHandle(VMA_NULL) { }
explicit VmaWin32Handle(HANDLE hHandle) noexcept : m_hHandle(hHandle) { }
~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL) { ::CloseHandle(m_hHandle); } }
VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
public:
// Strengthened
VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
{
*pHandle = VMA_NULL;
// Try to get handle first.
if (m_hHandle != VMA_NULL)
{
*pHandle = Duplicate(hTargetProcess);
return VK_SUCCESS;
}
VkResult res = VK_SUCCESS;
// If failed, try to create it.
{
VmaMutexLockWrite lock(m_Mutex, useMutex);
if (m_hHandle == VMA_NULL)
{
res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &m_hHandle);
}
}
*pHandle = Duplicate(hTargetProcess);
return res;
}
operator bool() const noexcept { return m_hHandle != VMA_NULL; }
private:
// Not atomic
static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE* pHandle) noexcept
{
VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
if (pvkGetMemoryWin32HandleKHR != VMA_NULL)
{
VkMemoryGetWin32HandleInfoKHR handleInfo{ };
handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
handleInfo.memory = memory;
handleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
res = pvkGetMemoryWin32HandleKHR(device, &handleInfo, pHandle);
}
return res;
}
HANDLE Duplicate(HANDLE hTargetProcess = VMA_NULL) const noexcept
{
if (!m_hHandle)
return m_hHandle;
HANDLE hCurrentProcess = ::GetCurrentProcess();
HANDLE hDupHandle = VMA_NULL;
if (!::DuplicateHandle(hCurrentProcess, m_hHandle, hTargetProcess ? hTargetProcess : hCurrentProcess, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
VMA_ASSERT(0 && "Failed to duplicate handle.");
}
return hDupHandle;
}
private:
HANDLE m_hHandle;
VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
};
#else
class VmaWin32Handle
{
// ABI compatibility
void* placeholder = VMA_NULL;
VMA_RW_MUTEX placeholder2;
};
#endif // VMA_EXTERNAL_MEMORY_WIN32
#ifndef _VMA_DEVICE_MEMORY_BLOCK
/*
Represents a single block of device memory (`VkDeviceMemory`) with all the
@@ -6139,7 +6276,13 @@ public:
VkDeviceSize allocationLocalOffset,
VkImage hImage,
const void* pNext);
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult CreateWin32Handle(
const VmaAllocator hAllocator,
PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR,
HANDLE hTargetProcess,
HANDLE* pHandle)noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
private:
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
uint32_t m_MemoryTypeIndex;
@@ -6155,10 +6298,18 @@ private:
VmaMappingHysteresis m_MappingHysteresis;
uint32_t m_MapCount;
void* m_pMappedData;
VmaWin32Handle m_Handle;
};
#endif // _VMA_DEVICE_MEMORY_BLOCK
#ifndef _VMA_ALLOCATION_T
struct VmaAllocationExtraData
{
void* m_pMappedData = VMA_NULL; // Not null means memory is mapped.
VmaWin32Handle m_Handle;
};
struct VmaAllocation_T
{
friend struct VmaDedicatedAllocationListItemTraits;
@@ -6191,12 +6342,14 @@ public:
bool mapped);
// pMappedData not null means allocation is created with MAPPED flag.
void InitDedicatedAllocation(
VmaAllocator allocator,
VmaPool hParentPool,
uint32_t memoryTypeIndex,
VkDeviceMemory hMemory,
VmaSuballocationType suballocationType,
void* pMappedData,
VkDeviceSize size);
void Destroy(VmaAllocator allocator);
ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; }
VkDeviceSize GetAlignment() const { return m_Alignment; }
@@ -6240,6 +6393,10 @@ public:
void PrintParameters(class VmaJsonWriter& json) const;
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
private:
// Allocation out of VmaDeviceMemoryBlock.
struct BlockAllocation
@@ -6252,7 +6409,7 @@ private:
{
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
VkDeviceMemory m_hMemory;
void* m_pMappedData; // Not null means memory is mapped.
VmaAllocationExtraData* m_ExtraData;
VmaAllocation_T* m_Prev;
VmaAllocation_T* m_Next;
};
@@ -6277,6 +6434,8 @@ private:
#if VMA_STATS_STRING_ENABLED
VmaBufferImageUsage m_BufferImageUsage; // 0 if unknown.
#endif
void EnsureExtraData(VmaAllocator hAllocator);
};
#endif // _VMA_ALLOCATION_T
@@ -10075,6 +10234,7 @@ public:
bool m_UseExtMemoryPriority;
bool m_UseKhrMaintenance4;
bool m_UseKhrMaintenance5;
bool m_UseKhrExternalMemoryWin32;
const VkDevice m_hDevice;
const VkInstance m_hInstance;
const bool m_AllocationCallbacksSpecified;
@@ -10438,7 +10598,7 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
m_Id(0),
m_hMemory(VK_NULL_HANDLE),
m_MapCount(0),
m_pMappedData(VMA_NULL) {}
m_pMappedData(VMA_NULL){}
VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
{
@@ -10681,6 +10841,14 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
}
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
VMA_ASSERT(pHandle);
return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
#ifndef _VMA_ALLOCATION_T_FUNCTIONS
@@ -10733,6 +10901,7 @@ void VmaAllocation_T::InitBlockAllocation(
}
void VmaAllocation_T::InitDedicatedAllocation(
VmaAllocator allocator,
VmaPool hParentPool,
uint32_t memoryTypeIndex,
VkDeviceMemory hMemory,
@@ -10747,16 +10916,29 @@ void VmaAllocation_T::InitDedicatedAllocation(
m_Size = size;
m_MemoryTypeIndex = memoryTypeIndex;
m_SuballocationType = (uint8_t)suballocationType;
if(pMappedData != VMA_NULL)
m_DedicatedAllocation.m_ExtraData = VMA_NULL;
m_DedicatedAllocation.m_hParentPool = hParentPool;
m_DedicatedAllocation.m_hMemory = hMemory;
m_DedicatedAllocation.m_Prev = VMA_NULL;
m_DedicatedAllocation.m_Next = VMA_NULL;
if (pMappedData != VMA_NULL)
{
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
EnsureExtraData(allocator);
m_DedicatedAllocation.m_ExtraData->m_pMappedData = pMappedData;
}
}
void VmaAllocation_T::Destroy(VmaAllocator allocator)
{
FreeName(allocator);
if (GetType() == ALLOCATION_TYPE_DEDICATED)
{
vma_delete(allocator, m_DedicatedAllocation.m_ExtraData);
}
m_DedicatedAllocation.m_hParentPool = hParentPool;
m_DedicatedAllocation.m_hMemory = hMemory;
m_DedicatedAllocation.m_pMappedData = pMappedData;
m_DedicatedAllocation.m_Prev = VMA_NULL;
m_DedicatedAllocation.m_Next = VMA_NULL;
}
void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName)
@@ -10861,8 +11043,9 @@ void* VmaAllocation_T::GetMappedData() const
}
break;
case ALLOCATION_TYPE_DEDICATED:
VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap()));
return m_DedicatedAllocation.m_pMappedData;
VMA_ASSERT((m_DedicatedAllocation.m_ExtraData != VMA_NULL && m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL) ==
(m_MapCount != 0 || IsPersistentMap()));
return m_DedicatedAllocation.m_ExtraData != VMA_NULL ? m_DedicatedAllocation.m_ExtraData->m_pMappedData : VMA_NULL;
default:
VMA_ASSERT(0);
return VMA_NULL;
@@ -10903,12 +11086,14 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
EnsureExtraData(hAllocator);
if (m_MapCount != 0 || IsPersistentMap())
{
if (m_MapCount < 0xFF)
{
VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);
*ppData = m_DedicatedAllocation.m_pMappedData;
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL);
*ppData = m_DedicatedAllocation.m_ExtraData->m_pMappedData;
++m_MapCount;
return VK_SUCCESS;
}
@@ -10929,7 +11114,7 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
ppData);
if (result == VK_SUCCESS)
{
m_DedicatedAllocation.m_pMappedData = *ppData;
m_DedicatedAllocation.m_ExtraData->m_pMappedData = *ppData;
m_MapCount = 1;
}
return result;
@@ -10945,7 +11130,8 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator)
--m_MapCount;
if (m_MapCount == 0 && !IsPersistentMap())
{
m_DedicatedAllocation.m_pMappedData = VMA_NULL;
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData != VMA_NULL);
m_DedicatedAllocation.m_ExtraData->m_pMappedData = VMA_NULL;
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(
hAllocator->m_hDevice,
m_DedicatedAllocation.m_hMemory);
@@ -10981,8 +11167,33 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
json.WriteString(m_pName);
}
}
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
switch (m_Type)
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
case ALLOCATION_TYPE_DEDICATED:
EnsureExtraData(hAllocator);
return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
default:
VMA_ASSERT(0);
return VK_ERROR_FEATURE_NOT_PRESENT;
}
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // VMA_STATS_STRING_ENABLED
void VmaAllocation_T::EnsureExtraData(VmaAllocator hAllocator)
{
if (m_DedicatedAllocation.m_ExtraData == VMA_NULL)
{
m_DedicatedAllocation.m_ExtraData = vma_new(hAllocator, VmaAllocationExtraData)();
}
}
void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
{
if(m_pName)
@@ -11399,6 +11610,10 @@ void VmaBlockVector::Free(const VmaAllocation hAllocation)
}
IncrementallySortBlocks();
m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
hAllocation->Destroy(m_hAllocator);
m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
}
// Destruction of a free block. Deferred until this point, outside of mutex
@@ -11409,9 +11624,6 @@ void VmaBlockVector::Free(const VmaAllocation hAllocation)
pBlockToDelete->Destroy(m_hAllocator);
vma_delete(m_hAllocator, pBlockToDelete);
}
m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
}
VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const
@@ -12711,6 +12923,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
m_UseKhrMaintenance4((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT) != 0),
m_UseKhrMaintenance5((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT) != 0),
m_UseKhrExternalMemoryWin32((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT) != 0),
m_hDevice(pCreateInfo->device),
m_hInstance(pCreateInfo->instance),
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
@@ -12766,23 +12979,17 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT is set but required extension or Vulkan 1.2 is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if VMA_VULKAN_VERSION < 1004000
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 4, 0) && "vulkanApiVersion >= VK_API_VERSION_1_4 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1003000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_3 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 3, 0) && "vulkanApiVersion >= VK_API_VERSION_1_3 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1002000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 2, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 2, 0) && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1001000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0) && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if !(VMA_MEMORY_PRIORITY)
if(m_UseExtMemoryPriority)
@@ -12802,6 +13009,19 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if !(VMA_KHR_MAINTENANCE5)
if(m_UseKhrMaintenance5)
{
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if !(VMA_EXTERNAL_MEMORY_WIN32)
if(m_UseKhrExternalMemoryWin32)
{
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
@@ -13026,7 +13246,9 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul
VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
VMA_COPY_IF_NOT_NULL(vkGetMemoryWin32HandleKHR);
#endif
#undef VMA_COPY_IF_NOT_NULL
}
@@ -13128,7 +13350,12 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR");
}
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
if (m_UseKhrExternalMemoryWin32)
{
VMA_FETCH_DEVICE_FUNC(vkGetMemoryWin32HandleKHR, PFN_vkGetMemoryWin32HandleKHR, "vkGetMemoryWin32HandleKHR");
}
#endif
#undef VMA_FETCH_DEVICE_FUNC
#undef VMA_FETCH_INSTANCE_FUNC
}
@@ -13177,6 +13404,12 @@ void VmaAllocator_T::ValidateVulkanFunctions()
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
}
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
if (m_UseKhrExternalMemoryWin32)
{
VMA_ASSERT(m_VulkanFunctions.vkGetMemoryWin32HandleKHR != VMA_NULL);
}
#endif
// Not validating these due to suspected driver bugs with these function
// pointers being null despite correct extension or Vulkan version is enabled.
@@ -13527,7 +13760,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
}
*pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed);
(*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
(*pAllocation)->InitDedicatedAllocation(this, pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
if (isUserDataString)
(*pAllocation)->SetName(this, (const char*)pUserData);
else
@@ -13863,8 +14096,6 @@ void VmaAllocator_T::FreeMemory(
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
}
allocation->FreeName(this);
switch(allocation->GetType())
{
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
@@ -14335,7 +14566,6 @@ VkResult VmaAllocator_T::Map(VmaAllocation hAllocation, void** ppData)
}
return res;
}
VMA_FALLTHROUGH; // Fallthrough
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
return hAllocation->DedicatedAllocMap(this, ppData);
default:
@@ -14549,6 +14779,7 @@ void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation)
FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize());
allocation->Destroy(this);
m_AllocationObjectAllocator.Free(allocation);
VMA_DEBUG_LOG_FORMAT(" Freed DedicatedMemory MemoryTypeIndex=%" PRIu32, memTypeIndex);
@@ -16169,7 +16400,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
pImageCreateInfo,
allocator->GetAllocationCallbacks(),
pImage);
if(res >= 0)
if(res == VK_SUCCESS)
{
VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
@@ -16194,14 +16425,14 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
1, // allocationCount
pAllocation);
if(res >= 0)
if(res == VK_SUCCESS)
{
// 3. Bind image with memory.
if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
{
res = allocator->BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL);
}
if(res >= 0)
if(res == VK_SUCCESS)
{
// All steps succeeded.
#if VMA_STATS_STRING_ENABLED
@@ -16434,6 +16665,15 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V
VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
}
}
#if VMA_EXTERNAL_MEMORY_WIN32
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
{
VMA_ASSERT(allocator && allocation && pHandle);
VMA_DEBUG_GLOBAL_MUTEX_LOCK;
return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // VMA_STATS_STRING_ENABLED
#endif // _VMA_PUBLIC_INTERFACE
#endif // VMA_IMPLEMENTATION
@@ -16567,6 +16807,7 @@ VK_EXT_memory_budget | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
VK_KHR_buffer_device_address | #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
VK_EXT_memory_priority | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
VK_AMD_device_coherent_memory | #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
VK_KHR_external_memory_win32 | #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
Example with fetching pointers to Vulkan functions dynamically:
@@ -17053,7 +17294,7 @@ implementation whether the allocation succeeds or fails. You can change this beh
by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is
not made if it would exceed the budget or if the budget is already exceeded.
VMA then tries to make the allocation from the next eligible Vulkan memory type.
The all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
If all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag
when creating resources that are not essential for the application (e.g. the texture
of a specific object) and not to pass it when creating critically important resources
@@ -18193,7 +18434,8 @@ allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VkBuffer buf;
VmaAllocation alloc;
VmaAllocationInfo allocInfo;
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
VkResult result = vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
// Check result...
VkMemoryPropertyFlags memPropFlags;
vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags);
@@ -18204,10 +18446,24 @@ if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
// [Executed in runtime]:
memcpy(allocInfo.pMappedData, myData, myDataSize);
result = vmaFlushAllocation(allocator, alloc, 0, VK_WHOLE_SIZE);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
bufMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.buffer = buf;
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
}
else
{
// Allocation ended up in a non-mappable memory - need to transfer.
// Allocation ended up in a non-mappable memory - a transfer using a staging buffer is required.
VkBufferCreateInfo stagingBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
stagingBufCreateInfo.size = 65536;
stagingBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
@@ -18220,18 +18476,46 @@ else
VkBuffer stagingBuf;
VmaAllocation stagingAlloc;
VmaAllocationInfo stagingAllocInfo;
vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
&stagingBuf, &stagingAlloc, stagingAllocInfo);
result = vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
&stagingBuf, &stagingAlloc, &stagingAllocInfo);
// Check result...
// [Executed in runtime]:
memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);
vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
//vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT
result = vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
bufMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.buffer = stagingBuf;
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
VkBufferCopy bufCopy = {
0, // srcOffset
0, // dstOffset,
myDataSize); // size
myDataSize, // size
};
vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy);
VkBufferMemoryBarrier bufMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
bufMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // We created a uniform buffer
bufMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier2.buffer = buf;
bufMemBarrier2.offset = 0;
bufMemBarrier2.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier2, 0, nullptr);
}
\endcode
@@ -18264,14 +18548,22 @@ Please check "CONFIGURATION SECTION" in the code to find macros that you can def
before each include of this file or change directly in this file to provide
your own implementation of basic facilities like assert, `min()` and `max()` functions,
mutex, atomic etc.
The library uses its own implementation of containers by default, but you can switch to using
STL containers instead.
For example, define `VMA_ASSERT(expr)` before including the library to provide
custom implementation of the assertion, compatible with your project.
By default it is defined to standard C `assert(expr)` in `_DEBUG` configuration
and empty otherwise.
Similarly, you can define `VMA_LEAK_LOG_FORMAT` macro to enable printing of leaked (unfreed) allocations,
including their names and other parameters. Example:
\code
#define VMA_LEAK_LOG_FORMAT(format, ...) do { \
printf((format), __VA_ARGS__); \
printf("\n"); \
} while(false)
\endcode
\section config_Vulkan_functions Pointers to Vulkan functions
There are multiple ways to import pointers to Vulkan functions in the library.
@@ -18526,6 +18818,145 @@ Example use of this extension can be found in the code of the sample and test su
accompanying this library.
\page vk_khr_external_memory_win32 VK_KHR_external_memory_win32
On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 `HANDLE`
of a `VkDeviceMemory` block, to be able to reference the memory on other Vulkan logical devices or instances,
in multiple processes, and/or in multiple APIs.
VMA offers support for it.
\section vk_khr_external_memory_win32_initialization Initialization
1) Make sure the extension is defined in the code by including following header before including VMA:
\code
#include <vulkan/vulkan_win32.h>
\endcode
2) Check if "VK_KHR_external_memory_win32" is available among device extensions.
Enable it when creating the `VkDevice` object.
3) Enable the usage of this extension in VMA by setting flag #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
when calling vmaCreateAllocator().
4) Make sure that VMA has access to the `vkGetMemoryWin32HandleKHR` function by either enabling `VMA_DYNAMIC_VULKAN_FUNCTIONS` macro
or setting VmaVulkanFunctions::vkGetMemoryWin32HandleKHR explicitly.
For more information, see \ref quick_start_initialization_importing_vulkan_functions.
\section vk_khr_external_memory_win32_preparations Preparations
You can find example usage among tests, in file "Tests.cpp", function `TestWin32Handles()`.
To use the extenion, buffers need to be created with `VkExternalMemoryBufferCreateInfoKHR` attached to their `pNext` chain,
and memory allocations need to be made with `VkExportMemoryAllocateInfoKHR` attached to their `pNext` chain.
To make use of them, you need to use \ref custom_memory_pools. Example:
\code
// Define an example buffer and allocation parameters.
VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
exampleBufCreateInfo.size = 0x10000; // Doesn't matter here.
exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
exampleBufCreateInfo.pNext = &externalMemBufCreateInfo;
VmaAllocationCreateInfo exampleAllocCreateInfo = {};
exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
// Find memory type index to use for the custom pool.
uint32_t memTypeIndex;
VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_Allocator,
&exampleBufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
// Check res...
// Create a custom pool.
constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = memTypeIndex;
poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
VmaPool pool;
res = vmaCreatePool(g_Allocator, &poolCreateInfo, &pool);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, don't forget to destroy it!
vmaDestroyPool(g_Allocator, pool);
\endcode
Note that the structure passed as VmaPoolCreateInfo::pMemoryAllocateNext must remain alive and unchanged
for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block.
No copy is made internally. This is why variable `exportMemAllocInfo` is defined as `static`.
\section vk_khr_external_memory_win32_memory_allocation Memory allocation
Finally, you can create a buffer with an allocation out of the custom pool.
The buffer should use same flags as the sample buffer used to find the memory type.
It should also specify `VkExternalMemoryBufferCreateInfoKHR` in its `pNext` chain.
\code
VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = // Your desired buffer size.
bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufCreateInfo.pNext = &externalMemBufCreateInfo;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.pool = pool; // It is enough to set this one member.
VkBuffer buf;
VmaAllocation alloc;
res = vmaCreateBuffer(g_Allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, don't forget to destroy it!
vmaDestroyBuffer(g_Allocator, buf, alloc);
\endcode
If you need each allocation to have its own device memory block and start at offset 0, you can still do
by using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag. It works also with custom pools.
\section vk_khr_external_memory_win32_exporting_win32_handle Exporting Win32 handle
After the allocation is created, you can acquire a Win32 `HANDLE` to the `VkDeviceMemory` block it belongs to.
VMA function vmaGetMemoryWin32Handle() is a replacement of the Vulkan function `vkGetMemoryWin32HandleKHR`.
\code
HANDLE handle;
res = vmaGetMemoryWin32Handle(g_Allocator, alloc, nullptr, &handle);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, you must close the handle.
CloseHandle(handle);
\endcode
Documentation of the VK_KHR_external_memory_win32 extension states that:
> If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType.
This is ensured automatically inside VMA.
The library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed.
Every time you call vmaGetMemoryWin32Handle(), VMA calls `DuplicateHandle` and returns a new handle that you need to close.
For further information, please check documentation of the vmaGetMemoryWin32Handle() function.
\page enabling_buffer_device_address Enabling buffer device address
Device extension VK_KHR_buffer_device_address

View File

@@ -25,7 +25,7 @@
/** \mainpage Vulkan Memory Allocator
<b>Version 3.1.0</b>
<b>Version 3.2.0</b>
Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved. \n
License: MIT \n
@@ -95,6 +95,7 @@ See also: [product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-me
- \subpage enabling_buffer_device_address
- \subpage vk_ext_memory_priority
- \subpage vk_amd_device_coherent_memory
- \subpage vk_khr_external_memory_win32
- \subpage general_considerations
- [Thread safety](@ref general_considerations_thread_safety)
- [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility)
@@ -127,10 +128,14 @@ See documentation chapter: \ref statistics.
extern "C" {
#endif
#if !defined(VULKAN_H_)
#include <vulkan/vulkan.h>
#endif
#if !defined(VMA_VULKAN_VERSION)
#if defined(VK_VERSION_1_3)
#if defined(VK_VERSION_1_4)
#define VMA_VULKAN_VERSION 1004000
#elif defined(VK_VERSION_1_3)
#define VMA_VULKAN_VERSION 1003000
#elif defined(VK_VERSION_1_2)
#define VMA_VULKAN_VERSION 1002000
@@ -240,6 +245,15 @@ extern "C" {
#endif
#endif
// Defined to 1 when VK_KHR_external_memory_win32 device extension is defined in Vulkan headers.
#if !defined(VMA_EXTERNAL_MEMORY_WIN32)
#if VK_KHR_external_memory_win32
#define VMA_EXTERNAL_MEMORY_WIN32 1
#else
#define VMA_EXTERNAL_MEMORY_WIN32 0
#endif
#endif
// Define these macros to decorate all public functions with additional code,
// before and after returned type, appropriately. This may be useful for
// exporting the functions when compiling VMA as a separate library. Example:
@@ -459,6 +473,15 @@ typedef enum VmaAllocatorCreateFlagBits
*/
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT = 0x00000100,
/**
Enables usage of VK_KHR_external_memory_win32 extension in the library.
You should set this flag if you found available and enabled this device extension,
while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
For more information, see \ref vk_khr_external_memory_win32.
*/
VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT = 0x00000200,
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocatorCreateFlagBits;
/// See #VmaAllocatorCreateFlagBits.
@@ -1033,6 +1056,11 @@ typedef struct VmaVulkanFunctions
/// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
PFN_vkGetDeviceImageMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
PFN_vkGetMemoryWin32HandleKHR VMA_NULLABLE vkGetMemoryWin32HandleKHR;
#else
void* VMA_NULLABLE vkGetMemoryWin32HandleKHR;
#endif
} VmaVulkanFunctions;
/// Description of a Allocator to be created.
@@ -1095,7 +1123,7 @@ typedef struct VmaAllocatorCreateInfo
It must be a value in the format as created by macro `VK_MAKE_VERSION` or a constant like: `VK_API_VERSION_1_1`, `VK_API_VERSION_1_0`.
The patch version number specified is ignored. Only the major and minor versions are considered.
Only versions 1.0, 1.1, 1.2, 1.3 are supported by the current implementation.
Only versions 1.0...1.4 are supported by the current implementation.
Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`.
It must match the Vulkan version used by the application and supported on the selected physical device,
so it must be no higher than `VkApplicationInfo::apiVersion` passed to `vkCreateInstance`
@@ -1810,6 +1838,9 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool(
\param allocator Allocator object.
\param pool Pool object.
\param[out] pPoolStats Statistics of specified pool.
Note that when using the pool from multiple threads, returned information may immediately
become outdated.
*/
VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics(
VmaAllocator VMA_NOT_NULL allocator,
@@ -2050,6 +2081,40 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
VmaAllocation VMA_NOT_NULL allocation,
VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
#if VMA_EXTERNAL_MEMORY_WIN32
/**
\brief Given an allocation, returns Win32 handle that may be imported by other processes or APIs.
\param hTargetProcess Must be a valid handle to target process or null. If it's null, the function returns
handle for the current process.
\param[out] pHandle Output parameter that returns the handle.
The function fills `pHandle` with handle that can be used in target process.
The handle is fetched using function `vkGetMemoryWin32HandleKHR`.
When no longer needed, you must close it using:
\code
CloseHandle(handle);
\endcode
You can close it any time, before or after destroying the allocation object.
It is reference-counted internally by Windows.
Note the handle is returned for the entire `VkDeviceMemory` block that the allocation belongs to.
If the allocation is sub-allocated from a larger block, you may need to consider the offset of the allocation
(VmaAllocationInfo::offset).
If the function fails with `VK_ERROR_FEATURE_NOT_PRESENT` error code, please double-check
that VmaVulkanFunctions::vkGetMemoryWin32HandleKHR function pointer is set, e.g. either by using `VMA_DYNAMIC_VULKAN_FUNCTIONS`
or by manually passing it through VmaAllocatorCreateInfo::pVulkanFunctions.
For more information, see chapter \ref vk_khr_external_memory_win32.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle);
#endif // VMA_EXTERNAL_MEMORY_WIN32
/** \brief Maps memory represented by given allocation and returns pointer to it.
Maps memory represented by given allocation to make it accessible to CPU code.
@@ -3097,7 +3162,7 @@ static void vma_aligned_free(void* VMA_NULLABLE ptr)
std::shared_mutex m_Mutex;
};
#define VMA_RW_MUTEX VmaRWMutex
#elif defined(_WIN32) && defined(WINVER) && WINVER >= 0x0600
#elif defined(_WIN32) && defined(WINVER) && defined(SRWLOCK_INIT) && WINVER >= 0x0600
// Use SRWLOCK from WinAPI.
// Minimum supported client = Windows Vista, server = Windows Server 2008.
class VmaRWMutex
@@ -3838,12 +3903,6 @@ struct VmaBufferImageUsage
const VmaBufferImageUsage VmaBufferImageUsage::UNKNOWN = VmaBufferImageUsage(0);
static void swap(VmaBufferImageUsage& lhs, VmaBufferImageUsage& rhs) noexcept
{
using std::swap;
swap(lhs.Value, rhs.Value);
}
VmaBufferImageUsage::VmaBufferImageUsage(const VkBufferCreateInfo &createInfo,
bool useKhrMaintenance5)
{
@@ -6073,6 +6132,84 @@ private:
#endif // _VMA_MAPPING_HYSTERESIS
#if VMA_EXTERNAL_MEMORY_WIN32
class VmaWin32Handle
{
public:
VmaWin32Handle() noexcept : m_hHandle(VMA_NULL) { }
explicit VmaWin32Handle(HANDLE hHandle) noexcept : m_hHandle(hHandle) { }
~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL) { ::CloseHandle(m_hHandle); } }
VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
public:
// Strengthened
VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
{
*pHandle = VMA_NULL;
// Try to get handle first.
if (m_hHandle != VMA_NULL)
{
*pHandle = Duplicate(hTargetProcess);
return VK_SUCCESS;
}
VkResult res = VK_SUCCESS;
// If failed, try to create it.
{
VmaMutexLockWrite lock(m_Mutex, useMutex);
if (m_hHandle == VMA_NULL)
{
res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &m_hHandle);
}
}
*pHandle = Duplicate(hTargetProcess);
return res;
}
operator bool() const noexcept { return m_hHandle != VMA_NULL; }
private:
// Not atomic
static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE* pHandle) noexcept
{
VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
if (pvkGetMemoryWin32HandleKHR != VMA_NULL)
{
VkMemoryGetWin32HandleInfoKHR handleInfo{ };
handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
handleInfo.memory = memory;
handleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
res = pvkGetMemoryWin32HandleKHR(device, &handleInfo, pHandle);
}
return res;
}
HANDLE Duplicate(HANDLE hTargetProcess = VMA_NULL) const noexcept
{
if (!m_hHandle)
return m_hHandle;
HANDLE hCurrentProcess = ::GetCurrentProcess();
HANDLE hDupHandle = VMA_NULL;
if (!::DuplicateHandle(hCurrentProcess, m_hHandle, hTargetProcess ? hTargetProcess : hCurrentProcess, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
VMA_ASSERT(0 && "Failed to duplicate handle.");
}
return hDupHandle;
}
private:
HANDLE m_hHandle;
VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
};
#else
class VmaWin32Handle
{
// ABI compatibility
void* placeholder = VMA_NULL;
VMA_RW_MUTEX placeholder2;
};
#endif // VMA_EXTERNAL_MEMORY_WIN32
#ifndef _VMA_DEVICE_MEMORY_BLOCK
/*
Represents a single block of device memory (`VkDeviceMemory`) with all the
@@ -6139,7 +6276,13 @@ public:
VkDeviceSize allocationLocalOffset,
VkImage hImage,
const void* pNext);
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult CreateWin32Handle(
const VmaAllocator hAllocator,
PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR,
HANDLE hTargetProcess,
HANDLE* pHandle)noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
private:
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
uint32_t m_MemoryTypeIndex;
@@ -6155,10 +6298,18 @@ private:
VmaMappingHysteresis m_MappingHysteresis;
uint32_t m_MapCount;
void* m_pMappedData;
VmaWin32Handle m_Handle;
};
#endif // _VMA_DEVICE_MEMORY_BLOCK
#ifndef _VMA_ALLOCATION_T
struct VmaAllocationExtraData
{
void* m_pMappedData = VMA_NULL; // Not null means memory is mapped.
VmaWin32Handle m_Handle;
};
struct VmaAllocation_T
{
friend struct VmaDedicatedAllocationListItemTraits;
@@ -6191,12 +6342,14 @@ public:
bool mapped);
// pMappedData not null means allocation is created with MAPPED flag.
void InitDedicatedAllocation(
VmaAllocator allocator,
VmaPool hParentPool,
uint32_t memoryTypeIndex,
VkDeviceMemory hMemory,
VmaSuballocationType suballocationType,
void* pMappedData,
VkDeviceSize size);
void Destroy(VmaAllocator allocator);
ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; }
VkDeviceSize GetAlignment() const { return m_Alignment; }
@@ -6240,6 +6393,10 @@ public:
void PrintParameters(class VmaJsonWriter& json) const;
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
private:
// Allocation out of VmaDeviceMemoryBlock.
struct BlockAllocation
@@ -6252,7 +6409,7 @@ private:
{
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
VkDeviceMemory m_hMemory;
void* m_pMappedData; // Not null means memory is mapped.
VmaAllocationExtraData* m_ExtraData;
VmaAllocation_T* m_Prev;
VmaAllocation_T* m_Next;
};
@@ -6277,6 +6434,8 @@ private:
#if VMA_STATS_STRING_ENABLED
VmaBufferImageUsage m_BufferImageUsage; // 0 if unknown.
#endif
void EnsureExtraData(VmaAllocator hAllocator);
};
#endif // _VMA_ALLOCATION_T
@@ -10075,6 +10234,7 @@ public:
bool m_UseExtMemoryPriority;
bool m_UseKhrMaintenance4;
bool m_UseKhrMaintenance5;
bool m_UseKhrExternalMemoryWin32;
const VkDevice m_hDevice;
const VkInstance m_hInstance;
const bool m_AllocationCallbacksSpecified;
@@ -10438,7 +10598,7 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
m_Id(0),
m_hMemory(VK_NULL_HANDLE),
m_MapCount(0),
m_pMappedData(VMA_NULL) {}
m_pMappedData(VMA_NULL){}
VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
{
@@ -10681,6 +10841,14 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
}
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
VMA_ASSERT(pHandle);
return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
#ifndef _VMA_ALLOCATION_T_FUNCTIONS
@@ -10733,6 +10901,7 @@ void VmaAllocation_T::InitBlockAllocation(
}
void VmaAllocation_T::InitDedicatedAllocation(
VmaAllocator allocator,
VmaPool hParentPool,
uint32_t memoryTypeIndex,
VkDeviceMemory hMemory,
@@ -10747,16 +10916,29 @@ void VmaAllocation_T::InitDedicatedAllocation(
m_Size = size;
m_MemoryTypeIndex = memoryTypeIndex;
m_SuballocationType = (uint8_t)suballocationType;
if(pMappedData != VMA_NULL)
m_DedicatedAllocation.m_ExtraData = VMA_NULL;
m_DedicatedAllocation.m_hParentPool = hParentPool;
m_DedicatedAllocation.m_hMemory = hMemory;
m_DedicatedAllocation.m_Prev = VMA_NULL;
m_DedicatedAllocation.m_Next = VMA_NULL;
if (pMappedData != VMA_NULL)
{
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
EnsureExtraData(allocator);
m_DedicatedAllocation.m_ExtraData->m_pMappedData = pMappedData;
}
}
void VmaAllocation_T::Destroy(VmaAllocator allocator)
{
FreeName(allocator);
if (GetType() == ALLOCATION_TYPE_DEDICATED)
{
vma_delete(allocator, m_DedicatedAllocation.m_ExtraData);
}
m_DedicatedAllocation.m_hParentPool = hParentPool;
m_DedicatedAllocation.m_hMemory = hMemory;
m_DedicatedAllocation.m_pMappedData = pMappedData;
m_DedicatedAllocation.m_Prev = VMA_NULL;
m_DedicatedAllocation.m_Next = VMA_NULL;
}
void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName)
@@ -10861,8 +11043,9 @@ void* VmaAllocation_T::GetMappedData() const
}
break;
case ALLOCATION_TYPE_DEDICATED:
VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap()));
return m_DedicatedAllocation.m_pMappedData;
VMA_ASSERT((m_DedicatedAllocation.m_ExtraData != VMA_NULL && m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL) ==
(m_MapCount != 0 || IsPersistentMap()));
return m_DedicatedAllocation.m_ExtraData != VMA_NULL ? m_DedicatedAllocation.m_ExtraData->m_pMappedData : VMA_NULL;
default:
VMA_ASSERT(0);
return VMA_NULL;
@@ -10903,12 +11086,14 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
EnsureExtraData(hAllocator);
if (m_MapCount != 0 || IsPersistentMap())
{
if (m_MapCount < 0xFF)
{
VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);
*ppData = m_DedicatedAllocation.m_pMappedData;
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData->m_pMappedData != VMA_NULL);
*ppData = m_DedicatedAllocation.m_ExtraData->m_pMappedData;
++m_MapCount;
return VK_SUCCESS;
}
@@ -10929,7 +11114,7 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa
ppData);
if (result == VK_SUCCESS)
{
m_DedicatedAllocation.m_pMappedData = *ppData;
m_DedicatedAllocation.m_ExtraData->m_pMappedData = *ppData;
m_MapCount = 1;
}
return result;
@@ -10945,7 +11130,8 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator)
--m_MapCount;
if (m_MapCount == 0 && !IsPersistentMap())
{
m_DedicatedAllocation.m_pMappedData = VMA_NULL;
VMA_ASSERT(m_DedicatedAllocation.m_ExtraData != VMA_NULL);
m_DedicatedAllocation.m_ExtraData->m_pMappedData = VMA_NULL;
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(
hAllocator->m_hDevice,
m_DedicatedAllocation.m_hMemory);
@@ -10981,8 +11167,33 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
json.WriteString(m_pName);
}
}
#if VMA_EXTERNAL_MEMORY_WIN32
VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
switch (m_Type)
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
case ALLOCATION_TYPE_DEDICATED:
EnsureExtraData(hAllocator);
return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
default:
VMA_ASSERT(0);
return VK_ERROR_FEATURE_NOT_PRESENT;
}
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // VMA_STATS_STRING_ENABLED
void VmaAllocation_T::EnsureExtraData(VmaAllocator hAllocator)
{
if (m_DedicatedAllocation.m_ExtraData == VMA_NULL)
{
m_DedicatedAllocation.m_ExtraData = vma_new(hAllocator, VmaAllocationExtraData)();
}
}
void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
{
if(m_pName)
@@ -11399,6 +11610,10 @@ void VmaBlockVector::Free(const VmaAllocation hAllocation)
}
IncrementallySortBlocks();
m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
hAllocation->Destroy(m_hAllocator);
m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
}
// Destruction of a free block. Deferred until this point, outside of mutex
@@ -11409,9 +11624,6 @@ void VmaBlockVector::Free(const VmaAllocation hAllocation)
pBlockToDelete->Destroy(m_hAllocator);
vma_delete(m_hAllocator, pBlockToDelete);
}
m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
}
VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const
@@ -12711,6 +12923,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
m_UseKhrMaintenance4((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT) != 0),
m_UseKhrMaintenance5((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT) != 0),
m_UseKhrExternalMemoryWin32((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT) != 0),
m_hDevice(pCreateInfo->device),
m_hInstance(pCreateInfo->instance),
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
@@ -12766,23 +12979,17 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT is set but required extension or Vulkan 1.2 is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if VMA_VULKAN_VERSION < 1004000
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 4, 0) && "vulkanApiVersion >= VK_API_VERSION_1_4 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1003000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_3 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 3, 0) && "vulkanApiVersion >= VK_API_VERSION_1_3 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1002000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 2, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 2, 0) && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if VMA_VULKAN_VERSION < 1001000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros.");
}
VMA_ASSERT(m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0) && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros.");
#endif
#if !(VMA_MEMORY_PRIORITY)
if(m_UseExtMemoryPriority)
@@ -12802,6 +13009,19 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if !(VMA_KHR_MAINTENANCE5)
if(m_UseKhrMaintenance5)
{
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
#if !(VMA_EXTERNAL_MEMORY_WIN32)
if(m_UseKhrExternalMemoryWin32)
{
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
}
#endif
memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
@@ -13026,7 +13246,9 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul
VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
VMA_COPY_IF_NOT_NULL(vkGetMemoryWin32HandleKHR);
#endif
#undef VMA_COPY_IF_NOT_NULL
}
@@ -13128,7 +13350,12 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR");
}
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
if (m_UseKhrExternalMemoryWin32)
{
VMA_FETCH_DEVICE_FUNC(vkGetMemoryWin32HandleKHR, PFN_vkGetMemoryWin32HandleKHR, "vkGetMemoryWin32HandleKHR");
}
#endif
#undef VMA_FETCH_DEVICE_FUNC
#undef VMA_FETCH_INSTANCE_FUNC
}
@@ -13177,6 +13404,12 @@ void VmaAllocator_T::ValidateVulkanFunctions()
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
}
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
if (m_UseKhrExternalMemoryWin32)
{
VMA_ASSERT(m_VulkanFunctions.vkGetMemoryWin32HandleKHR != VMA_NULL);
}
#endif
// Not validating these due to suspected driver bugs with these function
// pointers being null despite correct extension or Vulkan version is enabled.
@@ -13527,7 +13760,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
}
*pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed);
(*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
(*pAllocation)->InitDedicatedAllocation(this, pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
if (isUserDataString)
(*pAllocation)->SetName(this, (const char*)pUserData);
else
@@ -13863,8 +14096,6 @@ void VmaAllocator_T::FreeMemory(
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
}
allocation->FreeName(this);
switch(allocation->GetType())
{
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
@@ -14335,7 +14566,6 @@ VkResult VmaAllocator_T::Map(VmaAllocation hAllocation, void** ppData)
}
return res;
}
VMA_FALLTHROUGH; // Fallthrough
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
return hAllocation->DedicatedAllocMap(this, ppData);
default:
@@ -14549,6 +14779,7 @@ void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation)
FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize());
allocation->Destroy(this);
m_AllocationObjectAllocator.Free(allocation);
VMA_DEBUG_LOG_FORMAT(" Freed DedicatedMemory MemoryTypeIndex=%" PRIu32, memTypeIndex);
@@ -16169,7 +16400,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
pImageCreateInfo,
allocator->GetAllocationCallbacks(),
pImage);
if(res >= 0)
if(res == VK_SUCCESS)
{
VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
@@ -16194,14 +16425,14 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
1, // allocationCount
pAllocation);
if(res >= 0)
if(res == VK_SUCCESS)
{
// 3. Bind image with memory.
if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
{
res = allocator->BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL);
}
if(res >= 0)
if(res == VK_SUCCESS)
{
// All steps succeeded.
#if VMA_STATS_STRING_ENABLED
@@ -16434,6 +16665,15 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V
VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
}
}
#if VMA_EXTERNAL_MEMORY_WIN32
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
{
VMA_ASSERT(allocator && allocation && pHandle);
VMA_DEBUG_GLOBAL_MUTEX_LOCK;
return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // VMA_STATS_STRING_ENABLED
#endif // _VMA_PUBLIC_INTERFACE
#endif // VMA_IMPLEMENTATION
@@ -16567,6 +16807,7 @@ VK_EXT_memory_budget | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
VK_KHR_buffer_device_address | #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
VK_EXT_memory_priority | #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
VK_AMD_device_coherent_memory | #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
VK_KHR_external_memory_win32 | #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
Example with fetching pointers to Vulkan functions dynamically:
@@ -17053,7 +17294,7 @@ implementation whether the allocation succeeds or fails. You can change this beh
by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is
not made if it would exceed the budget or if the budget is already exceeded.
VMA then tries to make the allocation from the next eligible Vulkan memory type.
The all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
If all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag
when creating resources that are not essential for the application (e.g. the texture
of a specific object) and not to pass it when creating critically important resources
@@ -18193,7 +18434,8 @@ allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VkBuffer buf;
VmaAllocation alloc;
VmaAllocationInfo allocInfo;
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
VkResult result = vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
// Check result...
VkMemoryPropertyFlags memPropFlags;
vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags);
@@ -18204,10 +18446,24 @@ if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
// [Executed in runtime]:
memcpy(allocInfo.pMappedData, myData, myDataSize);
result = vmaFlushAllocation(allocator, alloc, 0, VK_WHOLE_SIZE);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
bufMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.buffer = buf;
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
}
else
{
// Allocation ended up in a non-mappable memory - need to transfer.
// Allocation ended up in a non-mappable memory - a transfer using a staging buffer is required.
VkBufferCreateInfo stagingBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
stagingBufCreateInfo.size = 65536;
stagingBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
@@ -18220,18 +18476,46 @@ else
VkBuffer stagingBuf;
VmaAllocation stagingAlloc;
VmaAllocationInfo stagingAllocInfo;
vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
&stagingBuf, &stagingAlloc, stagingAllocInfo);
result = vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
&stagingBuf, &stagingAlloc, &stagingAllocInfo);
// Check result...
// [Executed in runtime]:
memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);
vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
//vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT
result = vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
bufMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.buffer = stagingBuf;
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
VkBufferCopy bufCopy = {
0, // srcOffset
0, // dstOffset,
myDataSize); // size
myDataSize, // size
};
vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy);
VkBufferMemoryBarrier bufMemBarrier2 = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier2.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
bufMemBarrier2.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; // We created a uniform buffer
bufMemBarrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier2.buffer = buf;
bufMemBarrier2.offset = 0;
bufMemBarrier2.size = VK_WHOLE_SIZE;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier2, 0, nullptr);
}
\endcode
@@ -18264,14 +18548,22 @@ Please check "CONFIGURATION SECTION" in the code to find macros that you can def
before each include of this file or change directly in this file to provide
your own implementation of basic facilities like assert, `min()` and `max()` functions,
mutex, atomic etc.
The library uses its own implementation of containers by default, but you can switch to using
STL containers instead.
For example, define `VMA_ASSERT(expr)` before including the library to provide
custom implementation of the assertion, compatible with your project.
By default it is defined to standard C `assert(expr)` in `_DEBUG` configuration
and empty otherwise.
Similarly, you can define `VMA_LEAK_LOG_FORMAT` macro to enable printing of leaked (unfreed) allocations,
including their names and other parameters. Example:
\code
#define VMA_LEAK_LOG_FORMAT(format, ...) do { \
printf((format), __VA_ARGS__); \
printf("\n"); \
} while(false)
\endcode
\section config_Vulkan_functions Pointers to Vulkan functions
There are multiple ways to import pointers to Vulkan functions in the library.
@@ -18526,6 +18818,145 @@ Example use of this extension can be found in the code of the sample and test su
accompanying this library.
\page vk_khr_external_memory_win32 VK_KHR_external_memory_win32
On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 `HANDLE`
of a `VkDeviceMemory` block, to be able to reference the memory on other Vulkan logical devices or instances,
in multiple processes, and/or in multiple APIs.
VMA offers support for it.
\section vk_khr_external_memory_win32_initialization Initialization
1) Make sure the extension is defined in the code by including following header before including VMA:
\code
#include <vulkan/vulkan_win32.h>
\endcode
2) Check if "VK_KHR_external_memory_win32" is available among device extensions.
Enable it when creating the `VkDevice` object.
3) Enable the usage of this extension in VMA by setting flag #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
when calling vmaCreateAllocator().
4) Make sure that VMA has access to the `vkGetMemoryWin32HandleKHR` function by either enabling `VMA_DYNAMIC_VULKAN_FUNCTIONS` macro
or setting VmaVulkanFunctions::vkGetMemoryWin32HandleKHR explicitly.
For more information, see \ref quick_start_initialization_importing_vulkan_functions.
\section vk_khr_external_memory_win32_preparations Preparations
You can find example usage among tests, in file "Tests.cpp", function `TestWin32Handles()`.
To use the extenion, buffers need to be created with `VkExternalMemoryBufferCreateInfoKHR` attached to their `pNext` chain,
and memory allocations need to be made with `VkExportMemoryAllocateInfoKHR` attached to their `pNext` chain.
To make use of them, you need to use \ref custom_memory_pools. Example:
\code
// Define an example buffer and allocation parameters.
VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
exampleBufCreateInfo.size = 0x10000; // Doesn't matter here.
exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
exampleBufCreateInfo.pNext = &externalMemBufCreateInfo;
VmaAllocationCreateInfo exampleAllocCreateInfo = {};
exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
// Find memory type index to use for the custom pool.
uint32_t memTypeIndex;
VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_Allocator,
&exampleBufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
// Check res...
// Create a custom pool.
constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = memTypeIndex;
poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
VmaPool pool;
res = vmaCreatePool(g_Allocator, &poolCreateInfo, &pool);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, don't forget to destroy it!
vmaDestroyPool(g_Allocator, pool);
\endcode
Note that the structure passed as VmaPoolCreateInfo::pMemoryAllocateNext must remain alive and unchanged
for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block.
No copy is made internally. This is why variable `exportMemAllocInfo` is defined as `static`.
\section vk_khr_external_memory_win32_memory_allocation Memory allocation
Finally, you can create a buffer with an allocation out of the custom pool.
The buffer should use same flags as the sample buffer used to find the memory type.
It should also specify `VkExternalMemoryBufferCreateInfoKHR` in its `pNext` chain.
\code
VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
nullptr,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
};
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = // Your desired buffer size.
bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufCreateInfo.pNext = &externalMemBufCreateInfo;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.pool = pool; // It is enough to set this one member.
VkBuffer buf;
VmaAllocation alloc;
res = vmaCreateBuffer(g_Allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, don't forget to destroy it!
vmaDestroyBuffer(g_Allocator, buf, alloc);
\endcode
If you need each allocation to have its own device memory block and start at offset 0, you can still do
by using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag. It works also with custom pools.
\section vk_khr_external_memory_win32_exporting_win32_handle Exporting Win32 handle
After the allocation is created, you can acquire a Win32 `HANDLE` to the `VkDeviceMemory` block it belongs to.
VMA function vmaGetMemoryWin32Handle() is a replacement of the Vulkan function `vkGetMemoryWin32HandleKHR`.
\code
HANDLE handle;
res = vmaGetMemoryWin32Handle(g_Allocator, alloc, nullptr, &handle);
// Check res...
// YOUR OTHER CODE COMES HERE....
// At the end, you must close the handle.
CloseHandle(handle);
\endcode
Documentation of the VK_KHR_external_memory_win32 extension states that:
> If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType.
This is ensured automatically inside VMA.
The library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed.
Every time you call vmaGetMemoryWin32Handle(), VMA calls `DuplicateHandle` and returns a new handle that you need to close.
For further information, please check documentation of the vmaGetMemoryWin32Handle() function.
\page enabling_buffer_device_address Enabling buffer device address
Device extension VK_KHR_buffer_device_address

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -593,6 +593,7 @@
030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
030000009b2800008000000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
03000000790000008f18000000000000,Rapoo Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
0300000032150000a602000000000000,Razer Huntsman V3 Pro,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b12,dpright:b13,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000f8270000bf0b000000000000,Razer Kishi,a:b6,b:b7,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,leftshoulder:b12,leftstick:b19,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b13,rightstick:b20,righttrigger:b15,rightx:a3,righty:a4,start:b17,x:b9,y:b10,platform:Windows,
03000000321500000204000000000000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -701,7 +702,6 @@
03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,
03000000790000001c18000000000000,STK 7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000380700003847000000000000,Street Fighter Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,
030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
@@ -716,7 +716,8 @@
03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
03000000ba2200000701000000000000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b2,platform:Windows,
03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
03000000790000001c18000000000000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000790000002601000000000000,TGZ Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
03000000591c00002400000000000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000591c00002600000000000000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,start:b7,x:b3,y:b0,platform:Windows,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
@@ -883,7 +884,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
0300000008100000e501000019040000,Anbernic Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
0300000008100000e501000019040000,Anbernic Handheld,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000373500004610000001000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -997,6 +998,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000790000001c18000000010000,PB Tails Choc,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
@@ -1049,6 +1051,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000b40400000a01000000000000,Sega Saturn,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
03000000bc2000000155000000010000,SNK NEOGEO Arcade Stick Pro,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b2,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b0,y:b3,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
03000000666600006706000088020000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Mac OS X,
@@ -1207,10 +1210,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,
05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
0300000008100000e501000001010000,Anbernic Gamepad,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b3,y:b4,platform:Linux,
0300000008100000e501000001010000,Anbernic Handheld,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b3,y:b4,platform:Linux,
03000000020500000913000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000373500000710000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e0400008e02000072050000,Anbernic RG P01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
05000000373500004610000001000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
@@ -1301,7 +1303,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00005001000009040000,Hori Fighting Commander Octa Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00003701000013010000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b3,y:b2,platform:Linux,
@@ -1323,7 +1325,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00008501000015010000,Hori Switch Split Pad Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000c100000011010000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1346,6 +1348,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000300f00001101000010010000,Jess Tech Colour Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -1514,6 +1517,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000b20000001010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000540000001010000,PowerA Advantage Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
@@ -1607,6 +1611,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,
03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
03000000a30600000d5f000010010000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
@@ -1668,7 +1673,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000e40a00000307000011010000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
03000000e40a00000207000011010000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
@@ -1717,10 +1722,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00001503000000020000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
0000000058626f782047616d65706100,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008e02000072050000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,

422
bin/utils/bulk_compression.py Executable file
View File

@@ -0,0 +1,422 @@
#!/usr/bin/env python3
# PCSX2 - PS2 Emulator for PCs
# Copyright (C) 2024 PCSX2 Dev Team
#
# PCSX2 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 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 <https://www.gnu.org/licenses/>.
import sys
import os
import re
from subprocess import Popen, PIPE
from os.path import exists
gamecount = [0]
# =================================================================================================
def deletionChoice(source_extension): # Choose to delete source files
yesno = {
"n" : 0,
"no" : 0,
"y" : 1,
"yes" : 1,
}
print("╟-------------------------------------------------------------------------------╢")
print(f"║ Do you want to delete the original {source_extension.upper()} files as they are converted?")
choice = input("║ Type Y or N then press ENTER: ").lower()
if (not choice in yesno):
exitInvalidOption()
return (yesno[choice])
# -------------------------------------------------------------------------------------------------
def blockSizeChoice(is_cd, decompressing): # Choose block size
if (decompressing):
return 0
sizes = {
"1" : 16384,
"2" : 131072,
"3" : 262144,
} if not is_cd else {
"1": 17136,
"2": 132192,
"3": 264384,
}
print("╟-------------------------------------------------------------------------------╢")
print("║ Please pick the block size you would like to use:")
print("")
print("║ 1 - 16 kB (bigger files, faster access/less CPU, choose this if unsure)")
print("║ 2 - 128 kB (balanced)")
print("║ 3 - 256 kB (smaller files, slower access/more CPU)")
print("")
blocksize = input("║ Type the number corresponding to your selection then press ENTER: ")
if (not blocksize in sizes):
exitInvalidOption()
return (sizes[blocksize])
# =================================================================================================
def checkSuccess(compressing, fname, extension, error_code): # Ensure file created properly
target_fname = f"{fname}.{extension}"
if (error_code):
print("╠===============================================================================╣")
if (compressing):
print(f"║ Compression to {extension.upper()} failed for the following:{(37 - len(extension)) * ' '}")
else:
print(f"║ Extraction to {extension.upper()} failed for the following:{(38 - len(extension)) * ' '}")
print(f"{target_fname}{(77 - len(target_fname)) * ' '}")
print("╚===============================================================================╝")
sys.exit(1)
print(f"{target_fname} created.{(69 - len(target_fname)) * ' '}")
# -------------------------------------------------------------------------------------------------
def checkProgramMissing(program):
if (sys.platform.startswith('win32') and exists(f"./{program}.exe")):
return # Windows
else: # Linux, macOS
from shutil import which
if (which(program) is not None):
return
print("╠===============================================================================╗")
print(f"{program} failed, {program} is missing.{(39 - (len(program) * 2)) * ' '}")
print("╚===============================================================================╝")
sys.exit(1)
# -------------------------------------------------------------------------------------------------
def checkBinCueMismatch(bin_files, cue_files): # Ensure all bins and cues match
if (len(bin_files) != len(cue_files)): # Ensure numerical parity
exitBinCueMismatch()
for fname in bin_files: # Ensure filename parity
if (f"{fname[:-4]}.cue" not in cue_files):
exitBinCueMismatch()
# -------------------------------------------------------------------------------------------------
def checkDuplicates(source_files, target_extensions, crash_protection_type=0):
dupe_options = {
"s" : 0,
"skip" : 0,
"o" : 1,
"overwrite" : 1,
}
dupe_files = []
dupe_names = []
target_files = []
for extension in target_extensions:
target_files[len(target_files):] = returnFilteredPwdContents(extension)
for fname in source_files:
for extension in target_extensions:
target_fname = f"{fname[:-4]}.{extension}"
if (target_fname in target_files):
dupe_files.append(target_fname)
match crash_protection_type:
case 0:
pass
case 1: # Skip any dupe files no matter what
[dupe_names.append(fname[:-4]) for fname in dupe_files if fname[:-4] not in dupe_names]
return dupe_names
case 2: # Only skip if intermediate .iso present
[dupe_names.append(fname[:-4]) for fname in dupe_files if fname[:-4] not in dupe_names and fname[-4:] == ".iso"]
case _:
pass
if (not dupe_files):
return dupe_names
print("╟-------------------------------------------------------------------------------╢")
print("║ The following files were found which would be overwritten:")
for fname in dupe_files:
print(f"║ - {fname}")
print("")
print("║ You may choose to OVERWRITE or SKIP all of these.")
if (crash_protection_type == 2):
# chdman CLI just crashes trying to overwrite a .iso file
print("║ NOTE: chdman cannot overwrite .iso files, which are used as an intermediate format.")
print("║ These will be skipped regardless.")
choice = input("║ Press 'O' to overwrite or 'S' to skip and press ENTER: ").lower()
if (choice in dupe_options):
if (not dupe_options[choice]): # Skip
[dupe_names.append(fname[:-4]) for fname in dupe_files if fname[:-4] not in dupe_names]
return dupe_names
else:
exitInvalidOption()
# =================================================================================================
def printInitialStatus(decompressing, target_fname):
if (gamecount[0] != 0):
print("╟-------------------------------------------------------------------------------╢")
gamecount[0] += 1
if (decompressing):
print(f"║ Extracting to {target_fname}... ({gamecount[0]}){(58 - len(target_fname) - len(str(gamecount[0]))) * ' '}")
else:
print(f"║ Compressing to {target_fname}... ({gamecount[0]}){(57 - len(target_fname) - len(str(gamecount[0]))) * ' '}")
# -------------------------------------------------------------------------------------------------
def printSkip(target_fname):
if (gamecount[0] != 0):
print("╟-------------------------------------------------------------------------------╢")
gamecount[0] += 1
print(f"║ Skipping creation of {target_fname}{(57 - len(target_fname)) * ' '}")
# =================================================================================================
def createCommandList(mode, source_fname, target_fname, blocksize=0):
match mode:
case 1:
return [["maxcso", f"--block={blocksize}", source_fname]]
case 2:
return [["chdman", "createraw", "-us", "2048", "-hs", f"{blocksize}", "-f", "-i", source_fname, "-o", target_fname]]
case 3:
return [["chdman", "createcd", "-hs", f"{blocksize}", "-i", source_fname, "-o", f"{source_fname[:-4]}.chd"]]
case 4:
return [["maxcso", "--decompress", source_fname],
["chdman", "createraw", "-us", "2048", "-hs", f"{blocksize}", "-f", "-i", f"{source_fname[:-4]}.iso", "-o", f"{source_fname[:-4]}.chd"]]
case 5:
return [["chdman", "extractraw", "-i", source_fname, "-o", f"{source_fname[:-4]}.iso"],
["maxcso", f"--block={blocksize}", f"{source_fname[:-4]}.iso"]]
case 6:
return [["chdman", "extractraw", "-i", source_fname, "-o", target_fname]]
case 7:
return [["chdman", "extractcd", "-i", source_fname, "-o", target_fname]]
case 8:
return [["maxcso", "--decompress", source_fname]]
case _:
print("You have somehow chosen an invalid mode, and this was not correctly caught by the program.\nPlease report this as a bug.")
sys.exit(1)
# =================================================================================================
def returnFilteredPwdContents(file_extension): # Get files in pwd with extension
extension_pattern = r".*\." + file_extension.lower()
extension_reg = re.compile(extension_pattern)
return [fname for fname in os.listdir('.') if extension_reg.match(fname)]
# -------------------------------------------------------------------------------------------------
def deleteFile(fname): # Delete a file in pwd
print(f"║ Deleting {fname}...{(66 - len(fname)) * ' '}")
os.remove(f"./{fname}")
# =================================================================================================
def exitInvalidOption():
print("╠===============================================================================╗")
print("║ Invalid option. ║")
print("╚===============================================================================╝")
sys.exit(1)
# -------------------------------------------------------------------------------------------------
def exitBinCueMismatch():
print("╠===============================================================================╗")
print("║ All BIN files must have a matching CUE. ║")
print("╚===============================================================================╝")
sys.exit(1)
# =================================================================================================
# /////////////////////////////////////////////////////////////////////////////////////////////////
# =================================================================================================
options = { # Options listings
1 : "Convert ISO to CSO",
2 : "Convert ISO to CHD",
3 : "Convert CUE/BIN to CHD",
4 : "Convert CSO to CHD",
5 : "Convert DVD CHD to CSO",
6 : "Extract DVD CHD to ISO",
7 : "Extract CD CHD to CUE/BIN",
8 : "Extract CSO to ISO",
9 : "Exit script",
}
# -------------------------------------------------------------------------------------------------
sources = { # Source file extensions
1 : "iso",
2 : "iso",
3 : "cue/bin",
4 : "cso",
5 : "chd",
6 : "chd",
7 : "chd",
8 : "cso",
}
# -------------------------------------------------------------------------------------------------
targets = { # Target file extensions
1 : ["cso"],
2 : ["chd"],
3 : ["chd"],
4 : ["iso", "chd"],
5 : ["iso", "cso"],
6 : ["iso"],
7 : ["cue", "bin"],
8 : ["iso"],
}
# # -------------------------------------------------------------------------------------------------
reqs = { # Selection dependencies
1 : ["maxcso"],
2 : ["chdman"],
3 : ["chdman"],
4 : ["maxcso", "chdman"],
5 : ["maxcso", "chdman"],
6 : ["chdman"],
7 : ["chdman"],
8 : ["maxcso"],
}
# -------------------------------------------------------------------------------------------------
print("╔===============================================================================╗")
print("║ CSO/CHD/ISO/CUEBIN Conversion by Refraction, RedDevilus and TheTechnician27 ║")
print("║ (Version Jul 16 2024) ║")
print("╠===============================================================================╣")
print("║ ║")
print("║ PLEASE NOTE: This will affect all files in this folder! ║")
print("║ Be sure to run this from the same directory as the files you wish to convert. ║")
print("║ ║")
for number, message in options.items():
print("", number, " - ", message, f"{(70 - len(message)) * ' '}")
print("║ ║")
print("╠===============================================================================╝")
#print("║")
mode = input("║ Type the number corresponding to your selection then press ENTER: ")
# -------------------------------------------------------------------------------------------------
try:
mode = int(mode)
except ValueError:
exitInvalidOption()
# -------------------------------------------------------------------------------------------------
if (mode < 9 and mode > 0):
for program in reqs[mode]: # Check for dependencies
checkProgramMissing(program)
delete = deletionChoice(sources[mode]) # Choose to delete source files
blocksize = blockSizeChoice(mode == 3, mode > 5) # Choose block size if compressing
match mode:
case 3:
bin_files = returnFilteredPwdContents("bin") # Get all BIN files in pwd
source_files = returnFilteredPwdContents("cue") # Get all CUE files in pwd
checkBinCueMismatch(bin_files, source_files)
dupe_list = checkDuplicates(source_files, targets[mode], 1)
case 5:
source_files = returnFilteredPwdContents(sources[mode]) # Get source files in pwd
dupe_list = checkDuplicates(source_files, targets[mode], 2)
case 6:
source_files = returnFilteredPwdContents(sources[mode]) # Get source files in pwd
dupe_list = checkDuplicates(source_files, targets[mode], 1)
case _:
source_files = returnFilteredPwdContents(sources[mode]) # Get source files in pwd
dupe_list = checkDuplicates(source_files, targets[mode])
print("╠===============================================================================╗")
# ---------------------------------------------------------------------------------------------
for fname in source_files:
target_fname = f"{fname[:-4]}.{targets[mode][0]}"
commands = createCommandList(mode, fname, target_fname, blocksize)
if (fname[:-4] in dupe_list):
printSkip(target_fname)
continue
printInitialStatus(mode > 5, f"{fname[:-4]}.{targets[mode][-1]}")
for step, command in enumerate (commands):
process = Popen(commands[step], stdout=PIPE, stderr=PIPE) # Execute process
stdout, stderr = process.communicate() # Suppress output
checkSuccess(mode < 6, fname[:-4], # Ensure target creation
targets[mode][step], process.returncode)
if (step == 1): # Delete intermediate file
deleteFile(f"{fname[:-4]}.iso")
if (delete): # Delete source requested
deleteFile(fname)
if (mode == 3):
deleteFile(f"{fname[:-4]}.bin")
# ===== EXIT SCRIPT ===============================================================================
elif (mode == 9):
print("╠===============================================================================╗")
print("║ Goodbye! :) ║")
print("╚===============================================================================╝")
sys.exit(0)
# ===== EXIT SCRIPT WITH ERROR ====================================================================
else:
exitInvalidOption()
# -------------------------------------------------------------------------------------------------
print("╠===============================================================================╣")
print("║ Process complete! ║")
print("╚===============================================================================╝")
sys.exit(0)

View File

@@ -453,6 +453,11 @@ std::string Path::RealPath(const std::string_view path)
}
}
}
// If any relative symlinks were resolved, there may be '.' and '..'
// components in the resultant path, which must be removed.
realpath = Path::Canonicalize(realpath);
#endif
return realpath;
@@ -1225,6 +1230,14 @@ size_t FileSystem::ReadFileWithProgress(std::FILE* fp, void* dst, size_t length,
{
progress->SetProgressRange(100);
return FileSystem::ReadFileWithPartialProgress(fp, dst, length, progress, 0, 100, error, chunk_size);
}
size_t FileSystem::ReadFileWithPartialProgress(std::FILE* fp, void* dst, size_t length,
ProgressCallback* progress, int startPercent, int endPercent, Error* error, size_t chunk_size)
{
const int deltaPercent = endPercent - startPercent;
size_t done = 0;
while (done < length)
{
@@ -1238,7 +1251,7 @@ size_t FileSystem::ReadFileWithProgress(std::FILE* fp, void* dst, size_t length,
break;
}
progress->SetProgressValue((done * 100) / length);
progress->SetProgressValue(startPercent + (done * deltaPercent) / length);
done += read_size;
}
@@ -1961,6 +1974,26 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
return result;
}
bool FileSystem::CreateSymLink(const char* link, const char* target)
{
// convert to wide string
const std::wstring wlink = GetWin32Path(link);
if (wlink.empty())
return false;
const std::wstring wtarget = GetWin32Path(target);
if (wtarget.empty())
return false;
// check if it's a directory
DWORD flags = 0;
if (DirectoryExists(target))
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
// create the symbolic link
return CreateSymbolicLinkW(wlink.c_str(), wtarget.c_str(), flags) != 0;
}
bool FileSystem::IsSymbolicLink(const char* path)
{
// convert to wide string
@@ -2541,6 +2574,11 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
return false;
}
bool FileSystem::CreateSymLink(const char* link, const char* target)
{
return symlink(target, link) == 0;
}
bool FileSystem::IsSymbolicLink(const char* path)
{
struct stat sysStatData;

View File

@@ -144,6 +144,8 @@ namespace FileSystem
bool WriteStringToFile(const char* filename, const std::string_view sv);
size_t ReadFileWithProgress(std::FILE* fp, void* dst, size_t length, ProgressCallback* progress,
Error* error = nullptr, size_t chunk_size = 16 * 1024 * 1024);
size_t ReadFileWithPartialProgress(std::FILE* fp, void* dst, size_t length, ProgressCallback* progress,
int startPercent, int endPercent, Error* error = nullptr, size_t chunk_size = 16 * 1024 * 1024);
/// creates a directory in the local filesystem
/// if the directory already exists, the return value will be true.
@@ -178,6 +180,10 @@ namespace FileSystem
/// Does nothing and returns false on non-Windows platforms.
bool SetPathCompression(const char* path, bool enable);
// Creates a symbolic link. Note that on Windows this requires elevated
// privileges so this is mostly useful for testing purposes.
bool CreateSymLink(const char* link, const char* target);
/// Checks if a file or directory is a symbolic link.
bool IsSymbolicLink(const char* path);

View File

@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "common/Pcsx2Types.h"
@@ -22,6 +22,8 @@
#include <sys/wait.h>
#include <unistd.h>
#include <dbus/dbus.h>
#include <cstdlib>
#include <cstring>
// Returns 0 on failure (not supported by the operating system).
u64 GetPhysicalMemory()
@@ -101,6 +103,7 @@ static bool SetScreensaverInhibitDBus(const bool inhibit_requested, const char*
DBusMessage* message = nullptr;
DBusMessage* response = nullptr;
DBusMessageIter message_itr;
char* desktop_session = nullptr;
ScopedGuard cleanup = [&]() {
if (dbus_error_is_set(&error_dbus))
@@ -122,7 +125,17 @@ static bool SetScreensaverInhibitDBus(const bool inhibit_requested, const char*
s_cookie = 0;
s_comparison_connection = connection;
}
message = dbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", bus_method);
desktop_session = std::getenv("DESKTOP_SESSION");
if (desktop_session && std::strncmp(desktop_session, "mate", 4) == 0)
{
message = dbus_message_new_method_call("org.mate.ScreenSaver", "/org/mate/ScreenSaver", "org.mate.ScreenSaver", bus_method);
}
else
{
message = dbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", bus_method);
}
if (!message)
return false;
// Initialize an append iterator for the message, gets freed with the message.

View File

@@ -1224,22 +1224,35 @@ const xRegister32
#ifdef _WIN32
xPUSH(rdi);
xPUSH(rsi);
xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers
m_offset += 48;
#endif
m_offset += 16;
// Align for movaps, in addition to any following instructions
stackAlign(m_offset, true);
xSUB(rsp, 16 * 10);
for (u32 i = 6; i < 16; i++)
xMOVAPS(ptr128[rsp + (i - 6) * 16], xRegisterSSE(i));
xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers
#else
// Align for any following instructions
stackAlign(m_offset, true);
#endif
}
xScopedStackFrame::~xScopedStackFrame()
{
stackAlign(m_offset, false);
// Restore the register context
#ifdef _WIN32
xADD(rsp, 32);
for (u32 i = 6; i < 16; i++)
xMOVAPS(xRegisterSSE::GetInstance(i), ptr[rsp + (i - 6) * 16]);
xADD(rsp, 16 * 10);
stackAlign(m_offset, false);
xPOP(rsi);
xPOP(rdi);
#else
stackAlign(m_offset, false);
#endif
xPOP(r15);
xPOP(r14);

View File

@@ -52,10 +52,10 @@
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_M_X86;__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Platform)'=='ARM64' Or !$(Configuration.Contains(AVX2))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Platform)'=='x64' And $(Configuration.Contains(AVX2))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<!-- Allow SSE4 intrinsics on non-AVX Clang-cl builds -->
<AdditionalOptions Condition="'$(Platform)'=='x64' And $(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'=='x64' And $(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'=='ARM64' And $(Configuration.Contains(Clang))"> -march=armv8.4-a %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="!$(Configuration.Contains(Clang))">%(AdditionalOptions) /Zc:externConstexpr /Zc:__cplusplus /Zo /utf-8</AdditionalOptions>

View File

@@ -113,8 +113,15 @@ def check_regression_test(baselinedir, testdir, name):
path2 = os.path.join(dir2, imagename)
if not os.path.isfile(path2):
print("--- Frame %u for %s is missing in test set" % (framenum, name))
write("<h1>{}</h1>".format(name))
write("--- Frame %u for %s is missing in test set" % (framenum, name))
if first_fail:
write("<h1>{}</h1>".format(name))
if first_fail == False:
write("</table>")
write("<pre>--- Frame %u for %s is missing in test set</pre>" % (framenum, name))
write("</div>")
else:
write("<pre>--- Frame %u for %s is missing in test set</pre>" % (framenum, name))
return False
if not compare_frames(path1, path2):

View File

@@ -336,7 +336,7 @@ void CpuWidget::onVMPaused()
}
else
{
m_ui.disassemblyWidget->gotoAddress(m_cpu.getPC(), false);
m_ui.disassemblyWidget->gotoProgramCounterOnPause();
}
reloadCPUWidgets();

View File

@@ -656,6 +656,12 @@ void DisassemblyWidget::customMenuRequested(QPoint pos)
connect(action, &QAction::triggered, this, &DisassemblyWidget::contextGoToAddress);
contextMenu->addAction(action = new QAction(tr("Go to in Memory View"), this));
connect(action, &QAction::triggered, this, [this]() { gotoInMemory(m_selectedAddressStart); });
contextMenu->addAction(action = new QAction(tr("Go to PC on Pause"), this));
action->setCheckable(true);
action->setChecked(m_goToProgramCounterOnPause);
connect(action, &QAction::triggered, this, [this](bool value) { m_goToProgramCounterOnPause = value; });
contextMenu->addSeparator();
contextMenu->addAction(action = new QAction(tr("Add Function"), this));
connect(action, &QAction::triggered, this, &DisassemblyWidget::contextAddFunction);
@@ -822,6 +828,12 @@ void DisassemblyWidget::gotoAddressAndSetFocus(u32 address)
gotoAddress(address, true);
}
void DisassemblyWidget::gotoProgramCounterOnPause()
{
if (m_goToProgramCounterOnPause)
gotoAddress(m_cpu->getPC(), false);
}
void DisassemblyWidget::gotoAddress(u32 address, bool should_set_focus)
{
const u32 destAddress = address & ~3;

View File

@@ -59,6 +59,7 @@ public slots:
void contextShowOpcode();
void gotoAddressAndSetFocus(u32 address);
void gotoProgramCounterOnPause();
void gotoAddress(u32 address, bool should_set_focus);
void setDemangle(bool demangle) { m_demangleFunctions = demangle; };
@@ -82,6 +83,7 @@ private:
bool m_demangleFunctions = true;
bool m_showInstructionOpcode = true;
bool m_goToProgramCounterOnPause = true;
DisassemblyManager m_disassemblyManager;
inline QString DisassemblyStringFromAddress(u32 address, QFont font, u32 pc, bool selected);

View File

@@ -460,8 +460,8 @@ std::vector<std::unique_ptr<SymbolTreeNode>> SymbolTreeModel::populateChildren(
for (const ccc::ast::StructOrUnion::FlatField& field : fields)
{
if (symbol)
parent_handle = ccc::NodeHandle(*symbol, nullptr);
if (field.symbol)
parent_handle = ccc::NodeHandle(*field.symbol, nullptr);
SymbolTreeLocation field_location = location.addOffset(field.base_offset + field.node->offset_bytes);
if (field_location.type == SymbolTreeLocation::NONE)

View File

@@ -1346,9 +1346,8 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
if (action->isEnabled())
{
connect(action, &QAction::triggered, [entry]() {
SettingsWindow::openGamePropertiesDialog(entry, entry->title,
(entry->type != GameList::EntryType::ELF) ? entry->serial : std::string(),
entry->crc);
SettingsWindow::openGamePropertiesDialog(entry,
entry->title, entry->serial, entry->crc, entry->type == GameList::EntryType::ELF);
});
}
@@ -1564,7 +1563,7 @@ void MainWindow::onViewGamePropertiesActionTriggered()
if (entry)
{
SettingsWindow::openGamePropertiesDialog(
entry, entry->title, s_current_elf_override.isEmpty() ? entry->serial : std::string(), entry->crc);
entry, entry->title, entry->serial, entry->crc, !s_current_elf_override.isEmpty());
return;
}
}
@@ -1580,12 +1579,12 @@ void MainWindow::onViewGamePropertiesActionTriggered()
if (s_current_elf_override.isEmpty())
{
SettingsWindow::openGamePropertiesDialog(
nullptr, s_current_title.toStdString(), s_current_disc_serial.toStdString(), s_current_disc_crc);
nullptr, s_current_title.toStdString(), s_current_disc_serial.toStdString(), s_current_disc_crc, false);
}
else
{
SettingsWindow::openGamePropertiesDialog(
nullptr, s_current_title.toStdString(), std::string(), s_current_disc_crc);
nullptr, s_current_title.toStdString(), std::string(), s_current_disc_crc, true);
}
}

View File

@@ -38,6 +38,7 @@ ControllerSettingsWindow::ControllerSettingsWindow()
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &ControllerSettingsWindow::close);
connect(m_ui.newProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onNewProfileClicked);
connect(m_ui.applyProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onApplyProfileClicked);
connect(m_ui.renameProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onRenameProfileClicked);
connect(m_ui.deleteProfile, &QPushButton::clicked, this, &ControllerSettingsWindow::onDeleteProfileClicked);
connect(m_ui.mappingSettings, &QPushButton::clicked, this, &ControllerSettingsWindow::onMappingSettingsClicked);
connect(m_ui.restoreDefaults, &QPushButton::clicked, this, &ControllerSettingsWindow::onRestoreDefaultsClicked);
@@ -176,6 +177,48 @@ void ControllerSettingsWindow::onApplyProfileClicked()
switchProfile({});
}
void ControllerSettingsWindow::onRenameProfileClicked()
{
const QString profile_name(QInputDialog::getText(this, tr("Rename Input Profile"),
tr("Enter the new name for the input profile:").arg(m_profile_name)));
if (profile_name.isEmpty())
return;
std::string old_profile_name(m_profile_name.toStdString());
std::string old_profile_path(VMManager::GetInputProfilePath(m_profile_name.toStdString()));
std::string profile_path(VMManager::GetInputProfilePath(profile_name.toStdString()));
if (FileSystem::FileExists(profile_path.c_str()))
{
QMessageBox::critical(this, tr("Error"), tr("A profile with the name '%1' already exists.").arg(profile_name));
return;
}
if (!FileSystem::RenamePath(old_profile_path.c_str(), profile_path.c_str()))
{
QMessageBox::critical(this, tr("Error"), tr("Failed to rename '%1'.").arg(QString::fromStdString(old_profile_path)));
return;
}
FileSystem::FindResultsArray files;
FileSystem::FindFiles(EmuFolders::GameSettings.c_str(), "*", FILESYSTEM_FIND_FILES, &files);
for (const auto& game_settings : files)
{
std::string game_settings_path(game_settings.FileName.c_str());
std::unique_ptr<INISettingsInterface> update_sif(std::make_unique<INISettingsInterface>(std::move(game_settings_path)));
update_sif->Load();
if (!old_profile_name.compare(update_sif->GetStringValue("EmuCore", "InputProfileName")))
{
update_sif->SetStringValue("EmuCore", "InputProfileName", profile_name.toUtf8());
}
}
refreshProfileList();
switchProfile({profile_name});
}
void ControllerSettingsWindow::onDeleteProfileClicked()
{
if (QMessageBox::question(this, tr("Delete Input Profile"),
@@ -451,6 +494,7 @@ void ControllerSettingsWindow::createWidgets()
}
m_ui.applyProfile->setEnabled(isEditingProfile());
m_ui.renameProfile->setEnabled(isEditingProfile());
m_ui.deleteProfile->setEnabled(isEditingProfile());
m_ui.restoreDefaults->setEnabled(isEditingGlobalSettings());
}

View File

@@ -76,6 +76,7 @@ private Q_SLOTS:
void onCurrentProfileChanged(int index);
void onNewProfileClicked();
void onApplyProfileClicked();
void onRenameProfileClicked();
void onDeleteProfileClicked();
void onMappingSettingsClicked();
void onRestoreDefaultsClicked();

View File

@@ -113,6 +113,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="renameProfile">
<property name="text">
<string>Rename Profile</string>
</property>
<property name="icon">
<iconset theme="pencil-line"/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteProfile">
<property name="text">

View File

@@ -151,6 +151,14 @@ void DebugSettingsWidget::onDrawDumpingChanged()
m_ui.saveFrame->setEnabled(enabled);
m_ui.saveTexture->setEnabled(enabled);
m_ui.saveDepth->setEnabled(enabled);
m_ui.startDraw->setEnabled(enabled);
m_ui.dumpCount->setEnabled(enabled);
m_ui.hwDumpDirectory->setEnabled(enabled);
m_ui.hwDumpBrowse->setEnabled(enabled);
m_ui.hwDumpOpen->setEnabled(enabled);
m_ui.swDumpDirectory->setEnabled(enabled);
m_ui.swDumpBrowse->setEnabled(enabled);
m_ui.swDumpOpen->setEnabled(enabled);
}
#ifdef PCSX2_DEVBUILD

View File

@@ -167,7 +167,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QCheckBox" name="saveRT">
<property name="text">
<string>Save RT</string>
@@ -181,7 +181,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QCheckBox" name="saveTexture">
<property name="text">
<string>Save Texture</string>

View File

@@ -56,6 +56,7 @@ GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget
m_model_proxy->setFilterFixedString(text);
m_ui.cheatList->expandAll();
});
connect(m_dialog, &SettingsWindow::discSerialChanged, this, &GameCheatSettingsWidget::reloadList);
dialog->registerWidgetHelp(m_ui.allCRCsCheckbox, tr("Show Cheats For All CRCs"), tr("Checked"),
tr("Toggles scanning patch files for all CRCs of the game. With this enabled available patches for the game serial with different CRCs will also be loaded."));
@@ -124,7 +125,7 @@ void GameCheatSettingsWidget::updateListEnabled()
m_ui.enableAll->setEnabled(cheats_enabled);
m_ui.disableAll->setEnabled(cheats_enabled);
m_ui.reloadCheats->setEnabled(cheats_enabled);
m_ui.allCRCsCheckbox->setEnabled(cheats_enabled);
m_ui.allCRCsCheckbox->setEnabled(cheats_enabled && !m_dialog->getSerial().empty());
m_ui.searchText->setEnabled(cheats_enabled);
}
@@ -210,6 +211,7 @@ void GameCheatSettingsWidget::reloadList()
m_parent_map.clear();
m_model->removeRows(0, m_model->rowCount());
m_ui.allCRCsCheckbox->setEnabled(!m_dialog->getSerial().empty() && m_ui.cheatList->isEnabled());
for (const Patch::PatchInfo& pi : m_patches)
{

View File

@@ -16,7 +16,7 @@
#include <algorithm>
GamePatchDetailsWidget::GamePatchDetailsWidget(std::string name, const std::string& author,
const std::string& description, bool enabled, SettingsWindow* dialog, QWidget* parent)
const std::string& description, bool tristate, Qt::CheckState checkState, SettingsWindow* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
, m_name(name)
@@ -30,7 +30,8 @@ GamePatchDetailsWidget::GamePatchDetailsWidget(std::string name, const std::stri
.arg(description.empty() ? tr("No description provided.") : QString::fromStdString(description)));
pxAssert(dialog->getSettingsInterface());
m_ui.enabled->setChecked(enabled);
m_ui.enabled->setTristate(tristate);
m_ui.enabled->setCheckState(checkState);
connect(m_ui.enabled, &QCheckBox::checkStateChanged, this, &GamePatchDetailsWidget::onEnabledStateChanged);
}
@@ -40,9 +41,25 @@ void GamePatchDetailsWidget::onEnabledStateChanged(int state)
{
SettingsInterface* si = m_dialog->getSettingsInterface();
if (state == Qt::Checked)
si->AddToStringList("Patches", "Enable", m_name.c_str());
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, m_name.c_str());
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, m_name.c_str());
}
else
si->RemoveFromStringList("Patches", "Enable", m_name.c_str());
{
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, m_name.c_str());
if (m_ui.enabled->isTristate())
{
if (state == Qt::Unchecked)
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, m_name.c_str());
}
else
{
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, m_name.c_str());
}
}
}
si->Save();
g_emu_thread->reloadGameSettings();
@@ -56,12 +73,15 @@ GamePatchSettingsWidget::GamePatchSettingsWidget(SettingsWindow* dialog, QWidget
m_ui.scrollArea->setFrameShadow(QFrame::Sunken);
setUnlabeledPatchesWarningVisibility(false);
setGlobalWsPatchNoteVisibility(false);
setGlobalNiPatchNoteVisibility(false);
SettingsInterface* sif = m_dialog->getSettingsInterface();
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.allCRCsCheckbox, "EmuCore", "ShowPatchesForAllCRCs", false);
connect(m_ui.reload, &QPushButton::clicked, this, &GamePatchSettingsWidget::onReloadClicked);
connect(m_ui.allCRCsCheckbox, &QCheckBox::checkStateChanged, this, &GamePatchSettingsWidget::reloadList);
connect(m_dialog, &SettingsWindow::discSerialChanged, this, &GamePatchSettingsWidget::reloadList);
dialog->registerWidgetHelp(m_ui.allCRCsCheckbox, tr("Show Patches For All CRCs"), tr("Checked"),
tr("Toggles scanning patch files for all CRCs of the game. With this enabled available patches for the game serial with different CRCs will also be loaded."));
@@ -88,15 +108,24 @@ void GamePatchSettingsWidget::disableAllPatches()
void GamePatchSettingsWidget::reloadList()
{
const SettingsInterface* si = m_dialog->getSettingsInterface();
// Patches shouldn't have any unlabelled patch groups, because they're new.
u32 number_of_unlabeled_patches = 0;
bool showAllCRCS = m_ui.allCRCsCheckbox->isChecked();
std::vector<Patch::PatchInfo> patches = Patch::GetPatchInfo(m_dialog->getSerial(), m_dialog->getDiscCRC(), false, showAllCRCS, &number_of_unlabeled_patches);
std::vector<std::string> enabled_list =
m_dialog->getSettingsInterface()->GetStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY);
si->GetStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY);
std::vector<std::string> disabled_list =
si->GetStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY);
const bool ws_patches_enabled_globally = m_dialog->getEffectiveBoolValue("EmuCore", "EnableWideScreenPatches", false);
const bool ni_patches_enabled_globally = m_dialog->getEffectiveBoolValue("EmuCore", "EnableNoInterlacingPatches", false);
setUnlabeledPatchesWarningVisibility(number_of_unlabeled_patches > 0);
setGlobalWsPatchNoteVisibility(ws_patches_enabled_globally);
setGlobalNiPatchNoteVisibility(ni_patches_enabled_globally);
delete m_ui.scrollArea->takeWidget();
m_ui.allCRCsCheckbox->setEnabled(!m_dialog->getSerial().empty());
QWidget* container = new QWidget(m_ui.scrollArea);
QVBoxLayout* layout = new QVBoxLayout(container);
@@ -106,7 +135,7 @@ void GamePatchSettingsWidget::reloadList()
{
bool first = true;
for (Patch::PatchInfo& pi : patches)
for (const Patch::PatchInfo& pi : patches)
{
if (!first)
{
@@ -120,9 +149,35 @@ void GamePatchSettingsWidget::reloadList()
first = false;
}
const bool enabled = (std::find(enabled_list.begin(), enabled_list.end(), pi.name) != enabled_list.end());
const bool is_on_enable_list = std::find(enabled_list.begin(), enabled_list.end(), pi.name) != enabled_list.end();
const bool is_on_disable_list = std::find(disabled_list.begin(), disabled_list.end(), pi.name) != disabled_list.end();
const bool globally_toggleable_option = Patch::IsGloballyToggleablePatch(pi);
Qt::CheckState check_state;
if (!globally_toggleable_option)
{
// Normal patches
check_state = is_on_enable_list && !is_on_disable_list ? Qt::CheckState::Checked : Qt::CheckState::Unchecked;
}
else
{
// WS/NI patches
if (is_on_disable_list)
{
check_state = Qt::CheckState::Unchecked;
}
else if (is_on_enable_list)
{
check_state = Qt::CheckState::Checked;
}
else
{
check_state = Qt::CheckState::PartiallyChecked;
}
}
GamePatchDetailsWidget* it =
new GamePatchDetailsWidget(std::move(pi.name), pi.author, pi.description, enabled, m_dialog, container);
new GamePatchDetailsWidget(std::move(pi.name), pi.author, pi.description, globally_toggleable_option, check_state, m_dialog, container);
layout->addWidget(it);
}
}
@@ -141,3 +196,13 @@ void GamePatchSettingsWidget::setUnlabeledPatchesWarningVisibility(bool visible)
{
m_ui.unlabeledPatchWarning->setVisible(visible);
}
void GamePatchSettingsWidget::setGlobalWsPatchNoteVisibility(bool visible)
{
m_ui.globalWsPatchState->setVisible(visible);
}
void GamePatchSettingsWidget::setGlobalNiPatchNoteVisibility(bool visible)
{
m_ui.globalNiPatchState->setVisible(visible);
}

View File

@@ -22,7 +22,7 @@ class GamePatchDetailsWidget : public QWidget
Q_OBJECT
public:
GamePatchDetailsWidget(std::string name, const std::string& author, const std::string& description, bool enabled,
GamePatchDetailsWidget(std::string name, const std::string& author, const std::string& description, bool tristate, Qt::CheckState checkState,
SettingsWindow* dialog, QWidget* parent);
~GamePatchDetailsWidget();
@@ -50,6 +50,8 @@ private Q_SLOTS:
private:
void reloadList();
void setUnlabeledPatchesWarningVisibility(bool visible);
void setGlobalWsPatchNoteVisibility(bool visible);
void setGlobalNiPatchNoteVisibility(bool visible);
Ui::GamePatchSettingsWidget m_ui;
SettingsWindow* m_dialog;

View File

@@ -38,6 +38,29 @@
<property name="text">
<string>Any patches bundled with PCSX2 for this game will be disabled since you have unlabeled patches loaded.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="globalWsPatchState">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Widescreen patches are currently &lt;span style=&quot; font-weight:600;&quot;&gt;ENABLED&lt;/span&gt; globally.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="globalNiPatchState">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;No-Interlacing patches are currently &lt;span style=&quot; font-weight:600;&quot;&gt;ENABLED&lt;/span&gt; globally.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>

View File

@@ -156,7 +156,15 @@ void GameSummaryWidget::onDiscPathChanged(const QString& value)
// force rescan of elf to update the serial
g_main_window->rescanFile(m_entry_path);
repopulateCurrentDetails();
auto lock = GameList::GetLock();
const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
if (entry)
{
populateDetails(entry);
m_dialog->setSerial(entry->serial);
m_ui.checkWiki->setEnabled(!entry->serial.empty());
}
}
void GameSummaryWidget::onDiscPathBrowseClicked()

View File

@@ -8,6 +8,7 @@
#include <QtWidgets/QMessageBox>
#include "pcsx2/Host.h"
#include "pcsx2/Patch.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GS/GSCapture.h"
#include "pcsx2/GS/GSUtil.h"
@@ -321,24 +322,61 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
}
#endif
// Get rid of widescreen/no-interlace checkboxes from per-game settings, unless the user previously had them set.
// Get rid of widescreen/no-interlace checkboxes from per-game settings, and migrate them to Patches if necessary.
if (m_dialog->isPerGameSettings())
{
if ((m_dialog->containsSettingValue("EmuCore", "EnableWideScreenPatches") || m_dialog->containsSettingValue("EmuCore", "EnableNoInterlacingPatches")) &&
QMessageBox::question(QtUtils::GetRootWidget(this), tr("Remove Unsupported Settings"),
tr("You currently have the <strong>Enable Widescreen Patches</strong> or <strong>Enable No-Interlacing Patches</strong> options enabled for this game.<br><br>"
"We no longer support these options, instead <strong>you should select the \"Patches\" section, and explicitly enable the patches you want.</strong><br><br>"
"Do you want to remove these options from your game configuration now?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
SettingsInterface* si = m_dialog->getSettingsInterface();
bool needs_save = false;
if (si->ContainsValue("EmuCore", "EnableWideScreenPatches"))
{
m_dialog->removeSettingValue("EmuCore", "EnableWideScreenPatches");
m_dialog->removeSettingValue("EmuCore", "EnableNoInterlacingPatches");
const bool ws_enabled = si->GetBoolValue("EmuCore", "EnableWideScreenPatches");
si->DeleteValue("EmuCore", "EnableWideScreenPatches");
const char* WS_PATCH_NAME = "Widescreen 16:9";
if (ws_enabled)
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, WS_PATCH_NAME);
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, WS_PATCH_NAME);
}
else
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, WS_PATCH_NAME);
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, WS_PATCH_NAME);
}
needs_save = true;
}
if (si->ContainsValue("EmuCore", "EnableNoInterlacingPatches"))
{
const bool ni_enabled = si->GetBoolValue("EmuCore", "EnableNoInterlacingPatches");
si->DeleteValue("EmuCore", "EnableNoInterlacingPatches");
const char* NI_PATCH_NAME = "No-Interlacing";
if (ni_enabled)
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, NI_PATCH_NAME);
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, NI_PATCH_NAME);
}
else
{
si->AddToStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_DISABLE_CONFIG_KEY, NI_PATCH_NAME);
si->RemoveFromStringList(Patch::PATCHES_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY, NI_PATCH_NAME);
}
needs_save = true;
}
if (needs_save)
{
m_dialog->saveAndReloadGameSettings();
}
m_ui.displayGridLayout->removeWidget(m_ui.widescreenPatches);
m_ui.displayGridLayout->removeWidget(m_ui.noInterlacingPatches);
safe_delete(m_ui.widescreenPatches);
safe_delete(m_ui.noInterlacingPatches);
m_ui.widescreenPatches->deleteLater();
m_ui.noInterlacingPatches->deleteLater();
m_ui.widescreenPatches = nullptr;
m_ui.noInterlacingPatches = nullptr;
}
// Hide advanced options by default.
@@ -350,10 +388,13 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
m_ui.advancedTab = nullptr;
m_ui.gsDownloadMode = nullptr;
m_ui.gsDumpCompression = nullptr;
m_ui.texturePreloading = nullptr;
m_ui.exclusiveFullscreenControl = nullptr;
m_ui.useBlitSwapChain = nullptr;
m_ui.disableMailboxPresentation = nullptr;
m_ui.extendedUpscales = nullptr;
m_ui.spinCPUDuringReadbacks = nullptr;
m_ui.spinGPUDuringReadbacks = nullptr;
m_ui.skipPresentingDuplicateFrames = nullptr;
m_ui.overrideTextureBarriers = nullptr;
m_ui.disableFramebufferFetch = nullptr;

View File

@@ -447,6 +447,12 @@ void SettingsWindow::setWindowTitle(const QString& title)
QWidget::setWindowTitle(QStringLiteral("%1 [%2]").arg(title, m_filename));
}
void SettingsWindow::setSerial(std::string serial)
{
m_serial = std::move(serial);
emit discSerialChanged();
}
bool SettingsWindow::getEffectiveBoolValue(const char* section, const char* key, bool default_value) const
{
bool value;
@@ -649,9 +655,9 @@ void SettingsWindow::saveAndReloadGameSettings()
g_emu_thread->reloadGameSettings();
}
void SettingsWindow::openGamePropertiesDialog(const GameList::Entry* game, const std::string_view title, std::string serial, u32 disc_crc)
void SettingsWindow::openGamePropertiesDialog(const GameList::Entry* game, const std::string_view title, std::string serial, u32 disc_crc, bool is_elf)
{
std::string filename = VMManager::GetGameSettingsPath(serial, disc_crc);
std::string filename = VMManager::GetGameSettingsPath(!is_elf ? serial : std::string_view(), disc_crc);
// check for an existing dialog with this filename
for (SettingsWindow* dialog : s_open_game_properties_dialogs)

View File

@@ -45,7 +45,7 @@ public:
u32 disc_crc, QString filename = QString());
~SettingsWindow();
static void openGamePropertiesDialog(const GameList::Entry* game, const std::string_view title, std::string serial, u32 disc_crc);
static void openGamePropertiesDialog(const GameList::Entry* game, const std::string_view title, std::string serial, u32 disc_crc, bool is_elf);
static void closeGamePropertiesDialogs();
SettingsInterface* getSettingsInterface() const;
@@ -72,6 +72,7 @@ public:
bool eventFilter(QObject* object, QEvent* event) override;
void setWindowTitle(const QString& title);
void setSerial(std::string serial);
QString getCategory() const;
void setCategory(const char* category);
@@ -96,7 +97,7 @@ public:
void saveAndReloadGameSettings();
Q_SIGNALS:
void settingsResetToDefaults();
void discSerialChanged();
private Q_SLOTS:
void onCategoryCurrentRowChanged(int row);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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